}
/* Try to copy as directory? */
- r = copy_directory_fd(source_fd, arg_target, COPY_REFLINK|COPY_MERGE_EMPTY|COPY_SIGINT|COPY_HARDLINKS);
+ r = copy_directory_at(source_fd, NULL, AT_FDCWD, arg_target, COPY_REFLINK|COPY_MERGE_EMPTY|COPY_SIGINT|COPY_HARDLINKS);
if (r >= 0)
return 0;
if (r != -ENOTDIR)
progress_bytes,
&progress);
else
- r = copy_directory_fd_full(
- fd,
- dest,
+ r = copy_directory_at_full(
+ fd, NULL,
+ AT_FDCWD, dest,
COPY_REFLINK|
COPY_SAME_MOUNT|
COPY_HARDLINKS|
} else if (r < 0)
return r;
- r = copy_directory_fd_full(
- old_fd, new_path,
+ r = copy_directory_at_full(
+ old_fd, NULL,
+ AT_FDCWD, new_path,
COPY_MERGE_EMPTY|
COPY_REFLINK|
COPY_SAME_MOUNT|
return 0;
}
-static int sync_dir_by_flags(const char *path, CopyFlags copy_flags) {
+static int sync_dir_by_flags(int dir_fd, const char *path, CopyFlags copy_flags) {
+ assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+ assert(path);
if (copy_flags & COPY_SYNCFS)
- return syncfs_path(AT_FDCWD, path);
+ return syncfs_path(dir_fd, path);
if (copy_flags & COPY_FSYNC_FULL)
- return fsync_parent_at(AT_FDCWD, path);
+ return fsync_parent_at(dir_fd, path);
return 0;
}
-int copy_directory_fd_full(
- int dirfd,
- const char *to,
- CopyFlags copy_flags,
- copy_progress_path_t progress_path,
- copy_progress_bytes_t progress_bytes,
- void *userdata) {
-
- struct stat st;
- int r;
-
- assert(dirfd >= 0);
- assert(to);
-
- if (fstat(dirfd, &st) < 0)
- return -errno;
-
- r = stat_verify_directory(&st);
- if (r < 0)
- return r;
-
- r = fd_copy_directory(
- dirfd, NULL,
- &st,
- AT_FDCWD, to,
- st.st_dev,
- COPY_DEPTH_MAX,
- UID_INVALID, GID_INVALID,
- copy_flags,
- NULL, NULL, NULL,
- progress_path,
- progress_bytes,
- userdata);
- if (r < 0)
- return r;
-
- r = sync_dir_by_flags(to, copy_flags);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-int copy_directory_full(
+int copy_directory_at_full(
+ int dir_fdf,
const char *from,
+ int dir_fdt,
const char *to,
CopyFlags copy_flags,
copy_progress_path_t progress_path,
struct stat st;
int r;
- assert(from);
+ assert(dir_fdf >= 0 || dir_fdf == AT_FDCWD);
+ assert(dir_fdt >= 0 || dir_fdt == AT_FDCWD);
assert(to);
- if (lstat(from, &st) < 0)
+ if (fstatat(dir_fdf, strempty(from), &st, AT_SYMLINK_NOFOLLOW|(isempty(from) ? AT_EMPTY_PATH : 0)) < 0)
return -errno;
r = stat_verify_directory(&st);
return r;
r = fd_copy_directory(
- AT_FDCWD, from,
+ dir_fdf, from,
&st,
- AT_FDCWD, to,
+ dir_fdt, to,
st.st_dev,
COPY_DEPTH_MAX,
UID_INVALID, GID_INVALID,
if (r < 0)
return r;
- r = sync_dir_by_flags(to, copy_flags);
+ r = sync_dir_by_flags(dir_fdt, to, copy_flags);
if (r < 0)
return r;
return copy_tree_at_full(AT_FDCWD, from, AT_FDCWD, to, override_uid, override_gid, copy_flags, denylist, NULL, NULL, NULL);
}
-int copy_directory_fd_full(int dirfd, const char *to, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
-static inline int copy_directory_fd(int dirfd, const char *to, CopyFlags copy_flags) {
- return copy_directory_fd_full(dirfd, to, copy_flags, NULL, NULL, NULL);
-}
-
-int copy_directory_full(const char *from, const char *to, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
-static inline int copy_directory(const char *from, const char *to, CopyFlags copy_flags) {
- return copy_directory_full(from, to, copy_flags, NULL, NULL, NULL);
+int copy_directory_at_full(int dir_fdf, const char *from, int dir_fdt, const char *to, CopyFlags copy_flags, copy_progress_path_t progress_path, copy_progress_bytes_t progress_bytes, void *userdata);
+static inline int copy_directory_at(int dir_fdf, const char *from, int dir_fdt, const char *to, CopyFlags copy_flags) {
+ return copy_directory_at_full(dir_fdf, from, dir_fdt, to, copy_flags, NULL, NULL, NULL);
}
int copy_bytes_full(int fdf, int fdt, uint64_t max_bytes, CopyFlags copy_flags, void **ret_remains, size_t *ret_remains_size, copy_progress_bytes_t progress, void *userdata);
/* Copy unit files to make them accessible even when unprivileged. */
assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
- assert_se(copy_directory(unit_dir, PRIVATE_UNIT_DIR, COPY_MERGE_EMPTY) >= 0);
+ assert_se(copy_directory_at(AT_FDCWD, unit_dir, AT_FDCWD, PRIVATE_UNIT_DIR, COPY_MERGE_EMPTY) >= 0);
/* Prepare credstore like tmpfiles.d/credstore.conf for LoadCredential= tests. */
FOREACH_STRING(p, "/run/credstore", "/run/credstore.encrypted") {