]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
copy: teach copy_file() that a mode=-1 call means "take mode from original file"
authorLennart Poettering <lennart@poettering.net>
Wed, 18 Nov 2020 14:10:52 +0000 (15:10 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 2 Dec 2020 09:32:17 +0000 (10:32 +0100)
src/basic/copy.c

index 6a9c3a396f7f664d4a2486418058c49020dd26d3..aa805bb8e25acbf9e5303b37e453251dcd5a9cfc 100644 (file)
@@ -1047,18 +1047,29 @@ int copy_file_full(
                 copy_progress_bytes_t progress_bytes,
                 void *userdata) {
 
+        _cleanup_close_ int fdf = -1;
+        struct stat st;
         int fdt = -1, r;
 
         assert(from);
         assert(to);
 
+        fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fdf < 0)
+                return -errno;
+
+        if (mode == (mode_t) -1)
+                if (fstat(fdf, &st) < 0)
+                        return -errno;
+
         RUN_WITH_UMASK(0000) {
                 if (copy_flags & COPY_MAC_CREATE) {
                         r = mac_selinux_create_file_prepare(to, S_IFREG);
                         if (r < 0)
                                 return r;
                 }
-                fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode);
+                fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
+                           mode != (mode_t) -1 ? mode : st.st_mode);
                 if (copy_flags & COPY_MAC_CREATE)
                         mac_selinux_create_file_clear();
                 if (fdt < 0)
@@ -1068,13 +1079,16 @@ int copy_file_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_bytes_full(fdf, fdt, (uint64_t) -1, copy_flags, NULL, NULL, progress_bytes, userdata);
         if (r < 0) {
                 close(fdt);
                 (void) unlink(to);
                 return r;
         }
 
+        (void) copy_times(fdf, fdt, copy_flags);
+        (void) copy_xattr(fdf, fdt);
+
         if (chattr_mask != 0)
                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);