copy: Add copy_file_at()

This commit is contained in:
Daan De Meyer 2022-12-22 14:27:26 +01:00
parent 361bcb2097
commit d9daf0d144
2 changed files with 18 additions and 8 deletions

View file

@ -1329,8 +1329,10 @@ int copy_file_fd_full(
return 0;
}
int copy_file_full(
int copy_file_at_full(
int dir_fdf,
const char *from,
int dir_fdt,
const char *to,
int flags,
mode_t mode,
@ -1344,10 +1346,12 @@ int copy_file_full(
struct stat st;
int r;
assert(dir_fdf >= 0 || dir_fdf == AT_FDCWD);
assert(dir_fdt >= 0 || dir_fdt == AT_FDCWD);
assert(from);
assert(to);
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;
@ -1360,11 +1364,11 @@ int copy_file_full(
WITH_UMASK(0000) {
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(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
fdt = openat(dir_fdt, to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
mode != MODE_INVALID ? mode : st.st_mode);
if (copy_flags & COPY_MAC_CREATE)
mac_selinux_create_file_clear();
@ -1403,7 +1407,7 @@ int copy_file_full(
goto fail;
if (copy_flags & COPY_FSYNC_FULL) {
r = fsync_parent_at(AT_FDCWD, to);
r = fsync_parent_at(dir_fdt, to);
if (r < 0)
goto fail;
}
@ -1413,7 +1417,7 @@ int copy_file_full(
fail:
/* Only unlink if we definitely are the ones who created the file */
if (FLAGS_SET(flags, O_EXCL))
(void) unlink(to);
(void) unlinkat(dir_fdt, to, 0);
return r;
}

View file

@ -38,9 +38,15 @@ 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);
}
int copy_file_full(const char *from, 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);
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);
static inline int copy_file_at(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) {
return copy_file_at_full(dir_fdf, from, dir_fdt, to, open_flags, mode, chattr_flags, chattr_mask, copy_flags, NULL, NULL);
}
static inline int copy_file_full(const char *from, 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) {
return copy_file_at_full(AT_FDCWD, from, AT_FDCWD, to, open_flags, mode, chattr_flags, chattr_mask, copy_flags, progress, userdata);
}
static inline int copy_file(const char *from, const char *to, int open_flags, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags) {
return copy_file_full(from, to, open_flags, mode, chattr_flags, chattr_mask, copy_flags, NULL, NULL);
return copy_file_at(AT_FDCWD, from, AT_FDCWD, to, open_flags, mode, chattr_flags, chattr_mask, 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);