copy: teach copy_file() that a mode=-1 call means "take mode from original file"

This commit is contained in:
Lennart Poettering 2020-11-18 15:10:52 +01:00
parent ebef02dd8f
commit b1b657c48f
1 changed files with 16 additions and 2 deletions

View 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);