chiark / gitweb /
copy: change the various copy_xyz() calls to take a unified flags parameter
[elogind.git] / src / basic / copy.c
index 20078a81e23e417c18d73a95b7d0d17c360a456f..b0a093f489cd7b40c0b235de78ec68a26be227fa 100644 (file)
@@ -67,7 +67,7 @@ static ssize_t try_copy_file_range(int fd_in, loff_t *off_in,
                 return -errno;
 }
 
-int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
+int copy_bytes(int fdf, int fdt, uint64_t max_bytes, CopyFlags copy_flags) {
         bool try_cfr = true, try_sendfile = true, try_splice = true;
         int r;
         size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
@@ -77,7 +77,7 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
 
 #if 0 /// UNNEEDED by elogind
         /* Try btrfs reflinks first. */
-        if (try_reflink &&
+        if ((copy_flags & COPY_REFLINK) &&
             max_bytes == (uint64_t) -1 &&
             lseek(fdf, 0, SEEK_CUR) == 0 &&
             lseek(fdt, 0, SEEK_CUR) == 0) {
@@ -199,7 +199,7 @@ static int fd_copy_symlink(int df, const char *from, const struct stat *st, int
         return 0;
 }
 
-static int fd_copy_regular(int df, const char *from, const struct stat *st, int dt, const char *to) {
+static int fd_copy_regular(int df, const char *from, const struct stat *st, int dt, const char *to, CopyFlags copy_flags) {
         _cleanup_close_ int fdf = -1, fdt = -1;
         struct timespec ts[2];
         int r, q;
@@ -216,7 +216,7 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
         if (fdt < 0)
                 return -errno;
 
-        r = copy_bytes(fdf, fdt, (uint64_t) -1, true);
+        r = copy_bytes(fdf, fdt, (uint64_t) -1, copy_flags);
         if (r < 0) {
                 unlinkat(dt, to, 0);
                 return r;
@@ -292,7 +292,7 @@ static int fd_copy_directory(
                 int dt,
                 const char *to,
                 dev_t original_device,
-                bool merge) {
+                CopyFlags copy_flags) {
 
         _cleanup_close_ int fdf = -1, fdt = -1;
         _cleanup_closedir_ DIR *d = NULL;
@@ -318,7 +318,7 @@ static int fd_copy_directory(
         r = mkdirat(dt, to, st->st_mode & 07777);
         if (r >= 0)
                 created = true;
-        else if (errno == EEXIST && merge)
+        else if (errno == EEXIST && (copy_flags & COPY_MERGE))
                 created = false;
         else
                 return -errno;
@@ -345,9 +345,9 @@ static int fd_copy_directory(
                         continue;
 
                 if (S_ISREG(buf.st_mode))
-                        q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+                        q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, copy_flags);
                 else if (S_ISDIR(buf.st_mode))
-                        q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, merge);
+                        q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, copy_flags);
                 else if (S_ISLNK(buf.st_mode))
                         q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name);
                 else if (S_ISFIFO(buf.st_mode))
@@ -357,7 +357,7 @@ static int fd_copy_directory(
                 else
                         q = -EOPNOTSUPP;
 
-                if (q == -EEXIST && merge)
+                if (q == -EEXIST && (copy_flags & COPY_MERGE))
                         q = 0;
 
                 if (q < 0)
@@ -383,7 +383,7 @@ static int fd_copy_directory(
         return r;
 }
 
-int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge) {
+int copy_tree_at(int fdf, const char *from, int fdt, const char *to, CopyFlags copy_flags) {
         struct stat st;
 
         assert(from);
@@ -393,9 +393,9 @@ int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge)
                 return -errno;
 
         if (S_ISREG(st.st_mode))
-                return fd_copy_regular(fdf, from, &st, fdt, to);
+                return fd_copy_regular(fdf, from, &st, fdt, to, copy_flags);
         else if (S_ISDIR(st.st_mode))
-                return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, merge);
+                return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, copy_flags);
         else if (S_ISLNK(st.st_mode))
                 return fd_copy_symlink(fdf, from, &st, fdt, to);
         else if (S_ISFIFO(st.st_mode))
@@ -406,11 +406,11 @@ int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge)
                 return -EOPNOTSUPP;
 }
 
-int copy_tree(const char *from, const char *to, bool merge) {
-        return copy_tree_at(AT_FDCWD, from, AT_FDCWD, to, merge);
+int copy_tree(const char *from, const char *to, CopyFlags copy_flags) {
+        return copy_tree_at(AT_FDCWD, from, AT_FDCWD, to, copy_flags);
 }
 
-int copy_directory_fd(int dirfd, const char *to, bool merge) {
+int copy_directory_fd(int dirfd, const char *to, CopyFlags copy_flags) {
         struct stat st;
 
         assert(dirfd >= 0);
@@ -422,10 +422,10 @@ int copy_directory_fd(int dirfd, const char *to, bool merge) {
         if (!S_ISDIR(st.st_mode))
                 return -ENOTDIR;
 
-        return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
+        return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, copy_flags);
 }
 
-int copy_directory(const char *from, const char *to, bool merge) {
+int copy_directory(const char *from, const char *to, CopyFlags copy_flags) {
         struct stat st;
 
         assert(from);
@@ -437,10 +437,10 @@ int copy_directory(const char *from, const char *to, bool merge) {
         if (!S_ISDIR(st.st_mode))
                 return -ENOTDIR;
 
-        return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, merge);
+        return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, copy_flags);
 }
 
-int copy_file_fd(const char *from, int fdt, bool try_reflink) {
+int copy_file_fd(const char *from, int fdt, CopyFlags copy_flags) {
         _cleanup_close_ int fdf = -1;
         int r;
 
@@ -451,7 +451,7 @@ int copy_file_fd(const char *from, int fdt, bool try_reflink) {
         if (fdf < 0)
                 return -errno;
 
-        r = copy_bytes(fdf, fdt, (uint64_t) -1, try_reflink);
+        r = copy_bytes(fdf, fdt, (uint64_t) -1, copy_flags);
 
         (void) copy_times(fdf, fdt);
         (void) copy_xattr(fdf, fdt);
@@ -459,7 +459,7 @@ int copy_file_fd(const char *from, int fdt, bool try_reflink) {
         return r;
 }
 
-int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned chattr_flags) {
+int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags) {
         int fdt = -1, r;
 
         assert(from);
@@ -474,7 +474,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned
         if (chattr_flags != 0)
                 (void) chattr_fd(fdt, chattr_flags, (unsigned) -1);
 
-        r = copy_file_fd(from, fdt, true);
+        r = copy_file_fd(from, fdt, copy_flags);
         if (r < 0) {
                 close(fdt);
                 unlink(to);
@@ -489,7 +489,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned
         return 0;
 }
 
-int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace, unsigned chattr_flags) {
+int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned chattr_flags, CopyFlags copy_flags) {
         _cleanup_free_ char *t = NULL;
         int r;
 
@@ -500,11 +500,11 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
         if (r < 0)
                 return r;
 
-        r = copy_file(from, t, O_NOFOLLOW|O_EXCL, mode, chattr_flags);
+        r = copy_file(from, t, O_NOFOLLOW|O_EXCL, mode, chattr_flags, copy_flags);
         if (r < 0)
                 return r;
 
-        if (replace) {
+        if (copy_flags & COPY_REPLACE) {
                 r = renameat(AT_FDCWD, t, AT_FDCWD, to);
                 if (r < 0)
                         r = -errno;