]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/copy.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / basic / copy.c
index b8cbe644d443a65e601213d0040f761892070d34..7702d906c778edce41efa37e819d6e65b7d0726c 100644 (file)
 #include <sys/sendfile.h>
 #include <sys/xattr.h>
 
-#include "util.h"
 #include "btrfs-util.h"
+#include "string-util.h"
 #include "strv.h"
+#include "util.h"
 #include "copy.h"
 
 #define COPY_BUFFER_SIZE (16*1024)
@@ -37,10 +38,14 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
         assert(fdt >= 0);
 
         /* Try btrfs reflinks first. */
-        if (try_reflink && max_bytes == (uint64_t) -1) {
+        if (try_reflink &&
+            max_bytes == (uint64_t) -1 &&
+            lseek(fdf, 0, SEEK_CUR) == 0 &&
+            lseek(fdt, 0, SEEK_CUR) == 0) {
+
                 r = btrfs_reflink(fdf, fdt);
                 if (r >= 0)
-                        return r;
+                        return 0; /* we copied the whole thing, hence hit EOF, return 0 */
         }
 
         for (;;) {
@@ -50,7 +55,7 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
                 if (max_bytes != (uint64_t) -1) {
 
                         if (max_bytes <= 0)
-                                return -EFBIG;
+                                return 1; /* return > 0 if we hit the max_bytes limit */
 
                         if ((uint64_t) m > max_bytes)
                                 m = (size_t) max_bytes;
@@ -75,7 +80,7 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
 
                 /* The try splice, unless we already tried */
                 if (try_splice) {
-                        n  = splice(fdf, NULL, fdt, NULL, m, 0);
+                        n = splice(fdf, NULL, fdt, NULL, m, 0);
                         if (n < 0) {
                                 if (errno != EINVAL && errno != ENOSYS)
                                         return -errno;
@@ -91,7 +96,7 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
 
                 /* As a fallback just copy bits by hand */
                 {
-                        char buf[m];
+                        uint8_t buf[m];
 
                         n = read(fdf, buf, m);
                         if (n < 0)
@@ -111,7 +116,7 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
                 }
         }
 
-        return 0;
+        return 0; /* return 0 if we hit EOF earlier than the size limit */
 }
 
 static int fd_copy_symlink(int df, const char *from, const struct stat *st, int dt, const char *to) {