diff --git a/src/basic/tmpfile-util.c b/src/basic/tmpfile-util.c index 909057429d..dbbd54027e 100644 --- a/src/basic/tmpfile-util.c +++ b/src/basic/tmpfile-util.c @@ -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; } diff --git a/src/basic/tmpfile-util.h b/src/basic/tmpfile-util.h index 4af28b9da3..e5b7709e3f 100644 --- a/src/basic/tmpfile-util.h +++ b/src/basic/tmpfile-util.h @@ -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); diff --git a/src/home/homework-cifs.c b/src/home/homework-cifs.c index e79def3dae..8ad1da6303 100644 --- a/src/home/homework-cifs.c +++ b/src/home/homework-cifs.c @@ -64,7 +64,7 @@ int home_setup_cifs( pid_t mount_pid; int exit_status; - r = fopen_temporary(NULL, &f, &p); + r = fopen_temporary_child(NULL, &f, &p); if (r < 0) return log_error_errno(r, "Failed to create temporary credentials file: %m"); diff --git a/src/partition/repart.c b/src/partition/repart.c index 5d4cdbe689..07efcd2857 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -3178,6 +3178,7 @@ static int partition_encrypt(Context *context, Partition *p, const char *node) { const char *passphrase = NULL; size_t passphrase_size = 0; sd_id128_t uuid; + const char *vt; int r; assert(context); @@ -3194,7 +3195,11 @@ static int partition_encrypt(Context *context, Partition *p, const char *node) { log_info("Encrypting future partition %" PRIu64 "...", p->partno); - r = fopen_temporary(NULL, &h, &hp); + r = var_tmp_dir(&vt); + if (r < 0) + return log_error_errno(r, "Failed to determine temporary files directory: %m"); + + r = fopen_temporary_child(vt, &h, &hp); if (r < 0) return log_error_errno(r, "Failed to create temporary LUKS header file: %m"); diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index 19ffd9151b..0e135a9ac3 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -198,21 +198,16 @@ static int protofile_print_item( void *userdata) { FILE *f = ASSERT_PTR(userdata); - _cleanup_free_ char *base = NULL; int r; if (event == RECURSE_DIR_LEAVE) { - fprintf(f, "$\n"); + fputs("$\n", f); return 0; } if (!IN_SET(event, RECURSE_DIR_ENTER, RECURSE_DIR_ENTRY)) return RECURSE_DIR_CONTINUE; - r = path_extract_filename(path, &base); - if (r < 0) - return log_error_errno(r, "Failed to extract basename from %p: %m", path); - char type = S_ISDIR(sx->stx_mode) ? 'd' : S_ISREG(sx->stx_mode) ? '-' : S_ISLNK(sx->stx_mode) ? 'l' : @@ -223,51 +218,55 @@ static int protofile_print_item( return RECURSE_DIR_CONTINUE; fprintf(f, "%s %c%c%c%03o 0 0 ", - base, + de->d_name, type, sx->stx_mode & S_ISUID ? 'u' : '-', sx->stx_mode & S_ISGID ? 'g' : '-', (unsigned) (sx->stx_mode & 0777)); if (S_ISREG(sx->stx_mode)) - fprintf(f, "%s", path); + fputs(path, f); else if (S_ISLNK(sx->stx_mode)) { _cleanup_free_ char *p = NULL; - r = readlink_malloc(path, &p); + r = readlinkat_malloc(dir_fd, de->d_name, &p); if (r < 0) return log_error_errno(r, "Failed to read symlink %s: %m", path); - fprintf(f, "%s", p); + fputs(p, f); } else if (S_ISBLK(sx->stx_mode) || S_ISCHR(sx->stx_mode)) - fprintf(f, "%u %u", sx->stx_rdev_major, sx->stx_rdev_minor); + fprintf(f, "%" PRIu32 " %" PRIu32, sx->stx_rdev_major, sx->stx_rdev_minor); - fprintf(f, "\n"); + fputc('\n', f); return RECURSE_DIR_CONTINUE; } static int make_protofile(const char *root, char **ret) { _cleanup_fclose_ FILE *f = NULL; - _cleanup_free_ char *p = NULL; + _cleanup_(unlink_and_freep) char *p = NULL; + const char *vt; int r; assert(ret); - r = fopen_temporary(NULL, &f, &p); + r = var_tmp_dir(&vt); + if (r < 0) + return log_error_errno(r, "Failed to get persistent temporary directory: %m"); + + r = fopen_temporary_child(vt, &f, &p); if (r < 0) return log_error_errno(r, "Failed to open temporary file: %m"); - fprintf(f, "/\n"); - fprintf(f, "0 0\n"); - fprintf(f, "d--755 0 0\n"); + fputs("/\n" + "0 0\n" + "d--755 0 0\n", f); - r = recurse_dir_at(AT_FDCWD, root, STATX_TYPE|STATX_MODE, UINT_MAX, RECURSE_DIR_SORT, - protofile_print_item, f); + r = recurse_dir_at(AT_FDCWD, root, STATX_TYPE|STATX_MODE, UINT_MAX, 0, protofile_print_item, f); if (r < 0) return log_error_errno(r, "Failed to recurse through %s: %m", root); - fprintf(f, "$\n"); + fputs("$\n", f); r = fflush_and_check(f); if (r < 0) diff --git a/src/shared/tmpfile-util-label.c b/src/shared/tmpfile-util-label.c index d37c0b0845..17c5038b51 100644 --- a/src/shared/tmpfile-util-label.c +++ b/src/shared/tmpfile-util-label.c @@ -14,6 +14,8 @@ int fopen_temporary_label( int r; + assert(path); + r = mac_selinux_create_file_prepare(target, S_IFREG); if (r < 0) return r; diff --git a/src/test/test-uid-range.c b/src/test/test-uid-range.c index c759573173..186f6ee29c 100644 --- a/src/test/test-uid-range.c +++ b/src/test/test-uid-range.c @@ -114,7 +114,7 @@ TEST(load_userns) { assert_se(uid_range_covers(p, 0, UINT32_MAX)); } - assert_se(fopen_temporary(NULL, &f, &fn) >= 0); + assert_se(fopen_temporary_child(NULL, &f, &fn) >= 0); fputs("0 0 20\n" "100 0 20\n", f); assert_se(fflush_and_check(f) >= 0);