From b1b657c48fad087d6451ae022a2f246a07b05c59 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 18 Nov 2020 15:10:52 +0100 Subject: [PATCH] copy: teach copy_file() that a mode=-1 call means "take mode from original file" --- src/basic/copy.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/basic/copy.c b/src/basic/copy.c index 6a9c3a396f..aa805bb8e2 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -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);