Patch from vodz:
[oweals/busybox.git] / libbb / copyfd.c
index aa938d1053e17c32bd842ab5443c51eb28fe4d9f..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 int 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[8192];
-       ssize_t nread, nwrote;
+       ssize_t nread;
+       size_t size;
+       off_t remaining;
+       RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
 
-       while (1) {
-               nread = safe_read(fd1, buf, sizeof(buf));
-               if (nread == 0)
-                       break;
-               if (nread == -1) {
-                       perror_msg("read");
-                       return -1;
+       remaining = size = BUFSIZ;
+       if (chunksize) {
+               remaining = chunksize;
+       }
+
+       do {
+               if (size > remaining) {
+                       size = remaining;
                }
 
-               nwrote = full_write(fd2, buf, nread);
-               if (nwrote == -1) {
-                       perror_msg("write");
-                       return -1;
+               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;
+                       }
+                       return 0;
+               } else {                                /* nread < 0 */
+                       bb_perror_msg("Read error");    /* match bb_msg_write_error above */
+                       break;
                }
-       }
 
-       return 0;
-}
+       } while (1);
 
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
+       return -1;
+}