tmpfile-util: Introduce fopen_temporary_child()

Instead of having fopen_temporary() create the file either next
to an existing file or in tmp/, let's split this up clearly into
two different functions, one for creating temporary files next to
existing files, and one for creating a temporary file in a directory.
This commit is contained in:
Daan De Meyer
2022-11-17 14:14:31 +01:00
parent 305dd91adf
commit dd3c825294
7 changed files with 62 additions and 26 deletions
+50 -22
View File
@@ -19,31 +19,15 @@
#include "tmpfile-util.h"
#include "umask-util.h"
int fopen_temporary_at(int dir_fd, const char *path, FILE **ret_file, char **ret_temp_path) {
static int fopen_temporary_internal(int dir_fd, const char *path, FILE **ret_file) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *t = NULL;
_cleanup_close_ int fd = -1;
int r;
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
if (path) {
r = tempfn_random(path, NULL, &t);
if (r < 0)
return r;
} else {
const char *d;
r = tmp_dir(&d);
if (r < 0)
return r;
r = tempfn_random_child(d, NULL, &t);
if (r < 0)
return r;
}
fd = openat(dir_fd, t, O_CLOEXEC|O_NOCTTY|O_RDWR|O_CREAT|O_EXCL, 0600);
fd = openat(dir_fd, path, O_CLOEXEC|O_NOCTTY|O_RDWR|O_CREAT|O_EXCL, 0600);
if (fd < 0)
return -errno;
@@ -52,15 +36,59 @@ int fopen_temporary_at(int dir_fd, const char *path, FILE **ret_file, char **ret
r = take_fdopen_unlocked(&fd, "w", &f);
if (r < 0) {
(void) unlinkat(dir_fd, t, 0);
(void) unlinkat(dir_fd, path, 0);
return r;
}
if (ret_file)
*ret_file = TAKE_PTR(f);
if (ret_temp_path)
*ret_temp_path = TAKE_PTR(t);
return 0;
}
int fopen_temporary_at(int dir_fd, const char *path, FILE **ret_file, char **ret_path) {
_cleanup_free_ char *t = NULL;
int r;
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
r = tempfn_random(path, NULL, &t);
if (r < 0)
return r;
r = fopen_temporary_internal(dir_fd, t, ret_file);
if (r < 0)
return r;
if (ret_path)
*ret_path = TAKE_PTR(t);
return 0;
}
int fopen_temporary_child_at(int dir_fd, const char *path, FILE **ret_file, char **ret_path) {
_cleanup_free_ char *t = NULL;
int r;
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
if (!path) {
r = tmp_dir(&path);
if (r < 0)
return r;
}
r = tempfn_random_child(path, NULL, &t);
if (r < 0)
return r;
r = fopen_temporary_internal(dir_fd, t, ret_file);
if (r < 0)
return r;
if (ret_path)
*ret_path = TAKE_PTR(t);
return 0;
}
+6
View File
@@ -8,6 +8,12 @@ int fopen_temporary_at(int dir_fd, const char *path, FILE **ret_file, char **ret
static inline int fopen_temporary(const char *path, FILE **ret_file, char **ret_path) {
return fopen_temporary_at(AT_FDCWD, path, ret_file, ret_path);
}
int fopen_temporary_child_at(int dir_fd, const char *path, FILE **ret_file, char **ret_path);
static inline int fopen_temporary_child(const char *path, FILE **ret_file, char **ret_path) {
return fopen_temporary_child_at(AT_FDCWD, path, ret_file, ret_path);
}
int mkostemp_safe(char *pattern);
int fmkostemp_safe(char *pattern, const char *mode, FILE**_f);