#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;
}