summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shared/copy.c22
-rw-r--r--src/shared/copy.h18
2 files changed, 28 insertions, 12 deletions
diff --git a/src/shared/copy.c b/src/shared/copy.c
index 146293acdf..23d72ad1ca 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -1293,7 +1293,8 @@ int copy_directory_full(
return 0;
}
-int copy_file_fd_full(
+int copy_file_fd_at_full(
+ int dir_fdf,
const char *from,
int fdt,
CopyFlags copy_flags,
@@ -1304,10 +1305,11 @@ int copy_file_fd_full(
struct stat st;
int r;
+ assert(dir_fdf >= 0 || dir_fdf == AT_FDCWD);
assert(from);
assert(fdt >= 0);
- 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;
@@ -1435,8 +1437,10 @@ fail:
return r;
}
-int copy_file_atomic_full(
+int copy_file_atomic_at_full(
+ int dir_fdf,
const char *from,
+ int dir_fdt,
const char *to,
mode_t mode,
unsigned chattr_flags,
@@ -1453,11 +1457,11 @@ int copy_file_atomic_full(
assert(to);
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_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
+ fdt = open_tmpfile_linkable_at(dir_fdt, to, O_WRONLY|O_CLOEXEC, &t);
if (copy_flags & COPY_MAC_CREATE)
mac_selinux_create_file_clear();
if (fdt < 0)
@@ -1466,7 +1470,7 @@ int copy_file_atomic_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_file_fd_at_full(dir_fdf, from, fdt, copy_flags, progress_bytes, userdata);
if (r < 0)
return r;
@@ -1479,7 +1483,7 @@ int copy_file_atomic_full(
return -errno;
}
- r = link_tmpfile(fdt, t, to, copy_flags & COPY_REPLACE);
+ r = link_tmpfile_at(fdt, dir_fdt, t, to, copy_flags & COPY_REPLACE);
if (r < 0)
return r;
@@ -1494,7 +1498,7 @@ int copy_file_atomic_full(
if (copy_flags & COPY_FSYNC_FULL) {
/* Sync the parent directory */
- r = fsync_parent_at(AT_FDCWD, to);
+ r = fsync_parent_at(dir_fdt, to);
if (r < 0)
goto fail;
}
@@ -1502,7 +1506,7 @@ int copy_file_atomic_full(
return 0;
fail:
- (void) unlink(to);
+ (void) unlinkat(dir_fdt, to, 0);
return r;
}
diff --git a/src/shared/copy.h b/src/shared/copy.h
index ec65959aef..9e67838a99 100644
--- a/src/shared/copy.h
+++ b/src/shared/copy.h
@@ -41,9 +41,15 @@ typedef enum DenyType {
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata);
-int copy_file_fd_full(const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
+int copy_file_fd_at_full(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
+static inline int copy_file_fd_at(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata) {
+ return copy_file_fd_at_full(dir_fdf, from, to, copy_flags, progress, userdata);
+}
+static inline int copy_file_fd_full(const char *from, int to, CopyFlags copy_flags) {
+ return copy_file_fd_at_full(AT_FDCWD, from, to, copy_flags, NULL, NULL);
+}
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);
+ return copy_file_fd_at(AT_FDCWD, from, to, copy_flags, NULL, NULL);
}
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);
@@ -57,7 +63,13 @@ static inline int copy_file(const char *from, const char *to, int open_flags, mo
return copy_file_at(AT_FDCWD, from, AT_FDCWD, to, open_flags, mode, 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);
+int copy_file_atomic_at_full(int dir_fdf, const char *from, int dir_fdt, const char *to, mode_t mode, unsigned chattr_flags, unsigned chattr_mask, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);
+static inline int copy_file_atomic_at(int dir_fdf, const char *from, int dir_fdt, const char *to, mode_t mode, CopyFlags copy_flags) {
+ return copy_file_atomic_at_full(dir_fdf, from, dir_fdt, to, mode, 0, 0, copy_flags, NULL, NULL);
+}
+static inline 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) {
+ return copy_file_atomic_at_full(AT_FDCWD, from, AT_FDCWD, to, mode, 0, 0, copy_flags, NULL, NULL);
+}
static inline int copy_file_atomic(const char *from, const char *to, mode_t mode, CopyFlags copy_flags) {
return copy_file_atomic_full(from, to, mode, 0, 0, copy_flags, NULL, NULL);
}