summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-11-18 15:10:52 +0100
committerLennart Poettering <lennart@poettering.net>2020-12-02 10:32:17 +0100
commitb1b657c48fad087d6451ae022a2f246a07b05c59 (patch)
treeaa5d21de486d79d5b9fae58977530154bd12dd88
parentpager: stop disabling urlification under a pager (diff)
downloadsystemd-b1b657c48fad087d6451ae022a2f246a07b05c59.tar.xz
systemd-b1b657c48fad087d6451ae022a2f246a07b05c59.zip
copy: teach copy_file() that a mode=-1 call means "take mode from original file"
-rw-r--r--src/basic/copy.c18
1 files 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);