]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
env-file: rework write_env_file() to make use of O_TMPFILE
authorLennart Poettering <lennart@poettering.net>
Fri, 16 May 2025 11:08:56 +0000 (13:08 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 21 May 2025 17:50:48 +0000 (02:50 +0900)
src/basic/env-file.c
src/basic/tmpfile-util.c
src/basic/tmpfile-util.h

index b0faeab4ccc9e4690510e660e497dc1161da8134..60cb55e326e3687399c9d87f6feaa57a9735ca10 100644 (file)
@@ -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;
 }
 
index 9d2c0b71b9c6b98d571ebd769ea2c0f410f9ae47..0debd249ad02efd3d8eeaf80624262394489e962 100644 (file)
@@ -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) {
index 408f80e1472f885a7cd7f6f241f37ffd22d07434..5b94837d35ad21ba22ae0ae737f8b22af8fc085f 100644 (file)
@@ -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);