chiark / gitweb /
Make bus errno mappings non-static
[elogind.git] / src / shared / copy.c
index 7c3fab6901020c0db85520dce2224a85829137c2..3744797b9502788b8d16335085ec3ca89a7492f5 100644 (file)
 #include "util.h"
 #include "copy.h"
 
-int copy_bytes(int fdf, int fdt) {
+int copy_bytes(int fdf, int fdt, off_t max_bytes) {
         assert(fdf >= 0);
         assert(fdt >= 0);
 
         for (;;) {
                 char buf[PIPE_BUF];
                 ssize_t n, k;
+                size_t m = sizeof(buf);
 
-                n = read(fdf, buf, sizeof(buf));
+                if (max_bytes != (off_t) -1) {
+
+                        if (max_bytes <= 0)
+                                return -E2BIG;
+
+                        if ((off_t) m > max_bytes)
+                                m = (size_t) max_bytes;
+                }
+
+                n = read(fdf, buf, m);
                 if (n < 0)
                         return -errno;
                 if (n == 0)
@@ -42,6 +52,11 @@ int copy_bytes(int fdf, int fdt) {
                         return k;
                 if (k != n)
                         return errno ? -errno : -EIO;
+
+                if (max_bytes != (off_t) -1) {
+                        assert(max_bytes >= n);
+                        max_bytes -= n;
+                }
         }
 
         return 0;
@@ -84,7 +99,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);
+        r = copy_bytes(fdf, fdt, (off_t) -1);
         if (r < 0) {
                 unlinkat(dt, to, 0);
                 return r;
@@ -262,7 +277,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode) {
         if (fdt < 0)
                 return -errno;
 
-        r = copy_bytes(fdf, fdt);
+        r = copy_bytes(fdf, fdt, (off_t) -1);
         if (r < 0) {
                 unlink(to);
                 return r;