Patch from vodz:
[oweals/busybox.git] / libbb / copyfd.c
index 253a8cf6e0d7e58b5147d8aff4ba9137d0c9f466..05bed6b733a8f49c624f721c7275a54e0c23d170 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Utility routines.
  *
- * Copyright (C) 1999-2001 Erik Andersen <andersee@debian.org>
+ * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
-#include "libbb.h"
+#include "busybox.h"
 
+#if BUFSIZ < 4096
+#undef BUFSIZ
+#define BUFSIZ 4096
+#endif
 
-extern size_t copyfd(int fd1, int fd2)
+/* If chunksize is 0 copy until EOF */
+extern int bb_copyfd(int fd1, int fd2, const off_t chunksize)
 {
-       char buf[32768], *writebuf;
-       int status = TRUE;
-       size_t totalread = 0, bytesread, byteswritten;
+       ssize_t nread;
+       size_t size;
+       off_t remaining;
+       RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
 
-       while(status) {
-               bytesread = read(fd1, &buf, sizeof(buf));
-               if(bytesread == -1) {
-                       error_msg("read: %s", strerror(errno));
-                       status = FALSE;
-                       break;
+       remaining = size = BUFSIZ;
+       if (chunksize) {
+               remaining = chunksize;
+       }
+
+       do {
+               if (size > remaining) {
+                       size = remaining;
                }
-               byteswritten = 0;
-               writebuf = buf;
-               while(bytesread) {
-                       byteswritten = write( fd2, &writebuf, bytesread );
-                       if(byteswritten == -1) {
-                               error_msg("write: %s", strerror(errno));
-                               status = FALSE;
+
+               if ((nread = safe_read(fd1, buffer, size)) > 0) {
+                       if (bb_full_write(fd2, buffer, nread) < 0) {
+                               bb_perror_msg(bb_msg_write_error);      /* match Read error below */
+                               break;
+                       }
+                       if (chunksize && ((remaining -= nread) == 0)) {
+                               return 0;
+                       }
+               } else if (!nread) {
+                       if (chunksize) {
+                               bb_error_msg("Unable to read all data");
                                break;
                        }
-                       bytesread -= byteswritten;
-                       writebuf += byteswritten;
+                       return 0;
+               } else {                                /* nread < 0 */
+                       bb_perror_msg("Read error");    /* match bb_msg_write_error above */
+                       break;
                }
-       }
-       if ( status == TRUE )
-               return totalread;
-       else
-               return -1;
-}
 
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
+       } while (1);
+
+       return -1;
+}