tmpfile-util: if no path is passed to fopen_temporary() make one up

Let's beef up functionality a bit, and modernize the whole function.
This commit is contained in:
Lennart Poettering
2019-12-04 10:59:17 +01:00
parent a3292ec8d7
commit e5ea9ed030
+28 -18
View File
@@ -19,38 +19,48 @@
#include "tmpfile-util.h"
#include "umask-util.h"
int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
FILE *f;
char *t;
int r, fd;
int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *t = NULL;
_cleanup_close_ int fd = -1;
int r;
assert(path);
assert(_f);
assert(_temp_path);
if (path) {
r = tempfn_xxxxxx(path, NULL, &t);
if (r < 0)
return r;
} else {
const char *d;
r = tempfn_xxxxxx(path, NULL, &t);
if (r < 0)
return r;
r = tmp_dir(&d);
if (r < 0)
return r;
t = path_join(d, "XXXXXX");
if (!t)
return -ENOMEM;
}
fd = mkostemp_safe(t);
if (fd < 0) {
free(t);
if (fd < 0)
return -errno;
}
/* This assumes that returned FILE object is short-lived and used within the same single-threaded
* context and never shared externally, hence locking is not necessary. */
r = fdopen_unlocked(fd, "w", &f);
if (r < 0) {
unlink(t);
free(t);
safe_close(fd);
(void) unlink(t);
return r;
}
*_f = f;
*_temp_path = t;
TAKE_FD(fd);
if (ret_f)
*ret_f = TAKE_PTR(f);
if (ret_temp_path)
*ret_temp_path = TAKE_PTR(t);
return 0;
}