From: Lennart Poettering Date: Fri, 16 May 2025 11:08:56 +0000 (+0200) Subject: env-file: rework write_env_file() to make use of O_TMPFILE X-Git-Tag: v258-rc1~532 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c450027d14c52b1f920cb7d97cf0d8224ea33d95;p=thirdparty%2Fsystemd.git env-file: rework write_env_file() to make use of O_TMPFILE --- diff --git a/src/basic/env-file.c b/src/basic/env-file.c index b0faeab4ccc..60cb55e326e 100644 --- a/src/basic/env-file.c +++ b/src/basic/env-file.c @@ -612,11 +612,13 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l) { assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(fname); - r = fopen_temporary_at(dir_fd, fname, &f, &p); + r = fopen_tmpfile_linkable_at(dir_fd, fname, O_WRONLY|O_CLOEXEC, &p, &f); if (r < 0) return r; - (void) fchmod_umask(fileno(f), 0644); + r = fchmod_umask(fileno(f), 0644); + if (r < 0) + goto fail; STRV_FOREACH(i, headers) { assert(isempty(*i) || startswith(*i, "#")); @@ -627,15 +629,16 @@ int write_env_file(int dir_fd, const char *fname, char **headers, char **l) { STRV_FOREACH(i, l) write_env_var(f, *i); - r = fflush_and_check(f); - if (r >= 0) { - if (renameat(dir_fd, p, dir_fd, fname) >= 0) - return 0; + r = flink_tmpfile_at(f, dir_fd, p, fname, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC); + if (r < 0) + goto fail; - r = -errno; - } + return 0; + +fail: + if (p) + (void) unlinkat(dir_fd, p, 0); - (void) unlinkat(dir_fd, p, 0); return r; } diff --git a/src/basic/tmpfile-util.c b/src/basic/tmpfile-util.c index 9d2c0b71b9c..0debd249ad0 100644 --- a/src/basic/tmpfile-util.c +++ b/src/basic/tmpfile-util.c @@ -321,7 +321,7 @@ int open_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **r return fd; } -int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE **ret_file) { +int fopen_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **ret_path, FILE **ret_file) { _cleanup_free_ char *path = NULL; _cleanup_fclose_ FILE *f = NULL; _cleanup_close_ int fd = -EBADF; @@ -330,7 +330,7 @@ int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE assert(ret_file); assert(ret_path); - fd = open_tmpfile_linkable(target, flags, &path); + fd = open_tmpfile_linkable_at(dir_fd, target, flags, &path); if (fd < 0) return fd; @@ -380,7 +380,7 @@ int link_tmpfile_at(int fd, int dir_fd, const char *path, const char *target, Li return 0; } -int flink_tmpfile(FILE *f, const char *path, const char *target, LinkTmpfileFlags flags) { +int flink_tmpfile_at(FILE *f, int dir_fd, const char *path, const char *target, LinkTmpfileFlags flags) { int fd, r; assert(f); @@ -394,7 +394,7 @@ int flink_tmpfile(FILE *f, const char *path, const char *target, LinkTmpfileFlag if (r < 0) return r; - return link_tmpfile(fd, path, target, flags); + return link_tmpfile_at(fd, dir_fd, path, target, flags); } int mkdtemp_malloc(const char *template, char **ret) { diff --git a/src/basic/tmpfile-util.h b/src/basic/tmpfile-util.h index 408f80e1472..5b94837d35a 100644 --- a/src/basic/tmpfile-util.h +++ b/src/basic/tmpfile-util.h @@ -29,7 +29,10 @@ int open_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **r static inline int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { return open_tmpfile_linkable_at(AT_FDCWD, target, flags, ret_path); } -int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE **ret_file); +int fopen_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **ret_path, FILE **ret_file); +static inline int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE **ret_file) { + return fopen_tmpfile_linkable_at(AT_FDCWD, target, flags, ret_path, ret_file); +} typedef enum LinkTmpfileFlags { LINK_TMPFILE_REPLACE = 1 << 0, @@ -40,7 +43,10 @@ int link_tmpfile_at(int fd, int dir_fd, const char *path, const char *target, Li static inline int link_tmpfile(int fd, const char *path, const char *target, LinkTmpfileFlags flags) { return link_tmpfile_at(fd, AT_FDCWD, path, target, flags); } -int flink_tmpfile(FILE *f, const char *path, const char *target, LinkTmpfileFlags flags); +int flink_tmpfile_at(FILE *f, int dir_fd, const char *path, const char *target, LinkTmpfileFlags flags); +static inline int flink_tmpfile(FILE *f, const char *path, const char *target, LinkTmpfileFlags flags) { + return flink_tmpfile_at(f, AT_FDCWD, path, target, flags); +} int mkdtemp_malloc(const char *template, char **ret); int mkdtemp_open(const char *template, int flags, char **ret);