]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfile-util: Add open_tmpfile_linkable_at() and link_tmpfile_at() 26828/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 14 Mar 2023 16:12:06 +0000 (17:12 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 21 Mar 2023 14:20:01 +0000 (15:20 +0100)
src/basic/tmpfile-util.c
src/basic/tmpfile-util.h

index 379d81d5c8c3abe89175a344f6a6995f1042da85..d44464dd7bd16fce94235551a4987a625fed72bd 100644 (file)
@@ -272,7 +272,7 @@ int open_tmpfile_unlinkable(const char *directory, int flags) {
         return fd;
 }
 
-int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
+int open_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **ret_path) {
         _cleanup_free_ char *tmp = NULL;
         int r, fd;
 
@@ -286,7 +286,7 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
          * which case "ret_path" will be returned as NULL. If not possible the temporary path name used is returned in
          * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
 
-        fd = open_parent(target, O_TMPFILE|flags, 0640);
+        fd = open_parent_at(dir_fd, target, O_TMPFILE|flags, 0640);
         if (fd >= 0) {
                 *ret_path = NULL;
                 return fd;
@@ -298,7 +298,7 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
         if (r < 0)
                 return r;
 
-        fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
+        fd = openat(dir_fd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
         if (fd < 0)
                 return -errno;
 
@@ -349,11 +349,12 @@ static int link_fd(int fd, int newdirfd, const char *newpath) {
         return RET_NERRNO(linkat(fd, "", newdirfd, newpath, AT_EMPTY_PATH));
 }
 
-int link_tmpfile(int fd, const char *path, const char *target, bool replace) {
+int link_tmpfile_at(int fd, int dir_fd, const char *path, const char *target, bool replace) {
         _cleanup_free_ char *tmp = NULL;
         int r;
 
         assert(fd >= 0);
+        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
         assert(target);
 
         /* Moves a temporary file created with open_tmpfile() above into its final place. If "path" is NULL
@@ -362,12 +363,12 @@ int link_tmpfile(int fd, const char *path, const char *target, bool replace) {
 
         if (path) {
                 if (replace)
-                        return RET_NERRNO(rename(path, target));
+                        return RET_NERRNO(renameat(dir_fd, path, dir_fd, target));
 
-                return rename_noreplace(AT_FDCWD, path, AT_FDCWD, target);
+                return rename_noreplace(dir_fd, path, dir_fd, target);
         }
 
-        r = link_fd(fd, AT_FDCWD, target);
+        r = link_fd(fd, dir_fd, target);
         if (r != -EEXIST || !replace)
                 return r;
 
@@ -381,12 +382,12 @@ int link_tmpfile(int fd, const char *path, const char *target, bool replace) {
         if (r < 0)
                 return r;
 
-        if (link_fd(fd, AT_FDCWD, tmp) < 0)
+        if (link_fd(fd, dir_fd, tmp) < 0)
                 return -EEXIST; /* propagate original error */
 
-        r = RET_NERRNO(rename(tmp, target));
+        r = RET_NERRNO(renameat(dir_fd, tmp, dir_fd, target));
         if (r < 0) {
-                (void) unlink(tmp);
+                (void) unlinkat(dir_fd, tmp, 0);
                 return r;
         }
 
index 4665dafb24c0e10c0ebf614def8e1ce60c066a31..f48ce10e688207fc6b71fe0749c069d3a01ae517 100644 (file)
@@ -2,6 +2,7 @@
 #pragma once
 
 #include <fcntl.h>
+#include <stdbool.h>
 #include <stdio.h>
 
 int fopen_temporary_at(int dir_fd, const char *path, FILE **ret_file, char **ret_path);
@@ -22,10 +23,16 @@ int tempfn_random(const char *p, const char *extra, char **ret);
 int tempfn_random_child(const char *p, const char *extra, char **ret);
 
 int open_tmpfile_unlinkable(const char *directory, int flags);
-int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
+int open_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **ret_path);
+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 link_tmpfile(int fd, const char *path, const char *target, bool replace);
+int link_tmpfile_at(int fd, int dir_fd, const char *path, const char *target, bool replace);
+static inline int link_tmpfile(int fd, const char *path, const char *target, bool replace) {
+        return link_tmpfile_at(fd, AT_FDCWD, path, target, replace);
+}
 int flink_tmpfile(FILE *f, const char *path, const char *target, bool replace);
 
 int mkdtemp_malloc(const char *template, char **ret);