]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
copy: Add more at() helpers 26829/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 14 Mar 2023 16:12:27 +0000 (17:12 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 21 Mar 2023 19:53:09 +0000 (20:53 +0100)
src/shared/copy.c
src/shared/copy.h

index 146293acdff700be4fb4903695d2b41463272f4f..23d72ad1ca8527eea1fb9c175fccf180386c91ff 100644 (file)
@@ -1293,7 +1293,8 @@ int copy_directory_full(
         return 0;
 }
 
-int copy_file_fd_full(
+int copy_file_fd_at_full(
+                int dir_fdf,
                 const char *from,
                 int fdt,
                 CopyFlags copy_flags,
@@ -1304,10 +1305,11 @@ int copy_file_fd_full(
         struct stat st;
         int r;
 
+        assert(dir_fdf >= 0 || dir_fdf == AT_FDCWD);
         assert(from);
         assert(fdt >= 0);
 
-        fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        fdf = openat(dir_fdf, from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
         if (fdf < 0)
                 return -errno;
 
@@ -1435,8 +1437,10 @@ fail:
         return r;
 }
 
-int copy_file_atomic_full(
+int copy_file_atomic_at_full(
+                int dir_fdf,
                 const char *from,
+                int dir_fdt,
                 const char *to,
                 mode_t mode,
                 unsigned chattr_flags,
@@ -1453,11 +1457,11 @@ int copy_file_atomic_full(
         assert(to);
 
         if (copy_flags & COPY_MAC_CREATE) {
-                r = mac_selinux_create_file_prepare(to, S_IFREG);
+                r = mac_selinux_create_file_prepare_at(dir_fdt, to, S_IFREG);
                 if (r < 0)
                         return r;
         }
-        fdt = open_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
+        fdt = open_tmpfile_linkable_at(dir_fdt, to, O_WRONLY|O_CLOEXEC, &t);
         if (copy_flags & COPY_MAC_CREATE)
                 mac_selinux_create_file_clear();
         if (fdt < 0)
@@ -1466,7 +1470,7 @@ int copy_file_atomic_full(
         if (chattr_mask != 0)
                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL);
 
-        r = copy_file_fd_full(from, fdt, copy_flags, progress_bytes, userdata);
+        r = copy_file_fd_at_full(dir_fdf, from, fdt, copy_flags, progress_bytes, userdata);
         if (r < 0)
                 return r;
 
@@ -1479,7 +1483,7 @@ int copy_file_atomic_full(
                         return -errno;
         }
 
-        r = link_tmpfile(fdt, t, to, copy_flags & COPY_REPLACE);
+        r = link_tmpfile_at(fdt, dir_fdt, t, to, copy_flags & COPY_REPLACE);
         if (r < 0)
                 return r;
 
@@ -1494,7 +1498,7 @@ int copy_file_atomic_full(
 
         if (copy_flags & COPY_FSYNC_FULL) {
                 /* Sync the parent directory */
-                r = fsync_parent_at(AT_FDCWD, to);
+                r = fsync_parent_at(dir_fdt, to);
                 if (r < 0)
                         goto fail;
         }
@@ -1502,7 +1506,7 @@ int copy_file_atomic_full(
         return 0;
 
 fail:
-        (void) unlink(to);
+        (void) unlinkat(dir_fdt, to, 0);
         return r;
 }
 
index ec65959aefde99aff5e16e91ed28bd9d1d4f28b5..9e67838a99a4e8fbbefe75f38a43d0b3ffc93604 100644 (file)
@@ -41,9 +41,15 @@ typedef enum DenyType {
 typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
 typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata);
 
-int copy_file_fd_full(const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
+int copy_file_fd_at_full(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
+static inline int copy_file_fd_at(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata) {
+        return copy_file_fd_at_full(dir_fdf, from, to, copy_flags, progress, userdata);
+}
+static inline int copy_file_fd_full(const char *from, int to, CopyFlags copy_flags) {
+        return copy_file_fd_at_full(AT_FDCWD, from, to, copy_flags, NULL, NULL);
+}
 static inline int copy_file_fd(const char *from, int to, CopyFlags copy_flags) {
-        return copy_file_fd_full(from, to, copy_flags, NULL, NULL);
+        return copy_file_fd_at(AT_FDCWD, from, to, copy_flags, NULL, NULL);
 }
 
 int copy_file_at_full(int dir_fdf, const char *from, int dir_fdt, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
@@ -57,7 +63,13 @@ static inline int copy_file(const char *from, const char *to, int open_flags, mo
         return copy_file_at(AT_FDCWD, from, AT_FDCWD, to, open_flags, mode, copy_flags);
 }
 
-int copy_file_atomic_full(const char *from, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
+int copy_file_atomic_at_full(int dir_fdf, const char *from, int dir_fdt, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
+static inline int copy_file_atomic_at(int dir_fdf, const char *from, int dir_fdt, const char *to, mode_t mode, CopyFlags copy_flags) {
+        return copy_file_atomic_at_full(dir_fdf, from, dir_fdt, to, mode, 0, 0, copy_flags, NULL, NULL);
+}
+static inline int copy_file_atomic_full(const char *from, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata) {
+        return copy_file_atomic_at_full(AT_FDCWD, from, AT_FDCWD, to, mode, 0, 0, copy_flags, NULL, NULL);
+}
 static inline int copy_file_atomic(const char *from, const char *to, mode_t mode, CopyFlags copy_flags) {
         return copy_file_atomic_full(from, to, mode, 0, 0, copy_flags, NULL, NULL);
 }