Fix ufdCopy() for large (> 2GB) files
authorPanu Matilainen <pmatilai@redhat.com>
Wed, 14 Mar 2012 08:05:32 +0000 (10:05 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Wed, 14 Mar 2012 09:19:47 +0000 (11:19 +0200)
- Files can be (much) larger than INT32_MAX, change the return
  type to off_t and fix + simplify the calculations. Fixes the other
  half of RhBug:790396 and makes ufdCopy() usable for other purposes too.

rpmio/rpmio.c
rpmio/rpmio.h

index 2434687..6feae86 100644 (file)
@@ -452,36 +452,30 @@ static const struct FDIO_s fdio_s = {
 };
 static const FDIO_t fdio = &fdio_s ;
 
-int ufdCopy(FD_t sfd, FD_t tfd)
+off_t ufdCopy(FD_t sfd, FD_t tfd)
 {
     char buf[BUFSIZ];
-    int itemsRead;
-    int itemsCopied = 0;
-    int rc = 0;
+    ssize_t rdbytes, wrbytes;
+    off_t total = 0;
 
     while (1) {
-       rc = Fread(buf, sizeof(buf[0]), sizeof(buf), sfd);
-       if (rc < 0)
-           break;
-       else if (rc == 0) {
-           rc = itemsCopied;
-           break;
-       }
-       itemsRead = rc;
-       rc = Fwrite(buf, sizeof(buf[0]), itemsRead, tfd);
-       if (rc < 0)
-           break;
-       if (rc != itemsRead) {
-           rc = -1;
+       rdbytes = Fread(buf, sizeof(buf[0]), sizeof(buf), sfd);
+
+       if (rdbytes > 0) {
+           wrbytes = Fwrite(buf, sizeof(buf[0]), rdbytes, tfd);
+           if (wrbytes != rdbytes) {
+               total = -1;
+               break;
+           }
+           total += wrbytes;
+       } else {
+           if (rdbytes < 0)
+               total = -1;
            break;
        }
-
-       itemsCopied += itemsRead;
     }
 
-    DBGIO(sfd, (stderr, "++ copied %d bytes\n", itemsCopied));
-
-    return rc;
+    return total;
 }
 
 /*
index ea8fcd1..8cebe16 100644 (file)
@@ -116,7 +116,7 @@ FD_t fdFree(FD_t fd);
 
 /**
  */
-int ufdCopy(FD_t sfd, FD_t tfd);
+off_t ufdCopy(FD_t sfd, FD_t tfd);
 
 /** \ingroup rpmio
  * Identify per-desciptor I/O operation statistics.