Copy files until EOF, not the reported file size, to deal with bad sizes in
authorMatt Kraai <kraai@debian.org>
Mon, 11 Jun 2001 13:58:02 +0000 (13:58 -0000)
committerMatt Kraai <kraai@debian.org>
Mon, 11 Jun 2001 13:58:02 +0000 (13:58 -0000)
the proc filesystem.

libbb/copy_file.c
libbb/copy_file_chunk.c

index 22684be74283c1bf0996637979a91c48ded60f9a..24bdf9002f99b702a02cd27d6caa0a3663e7e772 100644 (file)
@@ -94,7 +94,7 @@ int copy_file(const char *source, const char *dest, int flags)
 
                        umask(saved_umask);
                }
-               
+
                /* Recursively copy files in SOURCE.  */
                if ((dp = opendir(source)) == NULL) {
                        perror_msg("unable to open directory `%s'", source);
@@ -116,7 +116,7 @@ int copy_file(const char *source, const char *dest, int flags)
                        free(new_source);
                        free(new_dest);
                }
-               
+
                /* ??? What if an error occurs in readdir?  */
 
                if (closedir(dp) < 0) {
@@ -173,7 +173,8 @@ int copy_file(const char *source, const char *dest, int flags)
                        goto end;
                }
 
-               copy_file_chunk(sfp, dfp, source_stat.st_size);
+               if (copy_file_chunk(sfp, dfp, -1) < 0)
+                       status = -1;
 
                if (fclose(dfp) < 0) {
                        perror_msg("unable to close `%s'", dest);
index e9663c3542e5e12bf24cfe7e7adaddff7d6df3cd..c440a6102aaec1155410f5fd481266ebfc618c57 100644 (file)
 #include <sys/stat.h>
 #include "libbb.h"
 
-/*
- * Copy chunksize bytes between two file descriptors
- *
- * unsigned long is used so that if -1 is passed as chunksize it will read as
- * much as possible, and it will work with off_t or off64_t
- */
+/* Copy CHUNKSIZE bytes (or until EOF if CHUNKSIZE equals -1) from SRC_FILE
+ * to DST_FILE.  */
 extern int copy_file_chunk(FILE *src_file, FILE *dst_file, unsigned long long chunksize)
 {
-       off_t size, amount_written;
-       char buffer[BUFSIZ]; /* BUFSIZ is declared in stdio.h */
-       
-       while (chunksize > 0) {
-               if (chunksize > BUFSIZ) {
+       size_t nread, nwritten, size;
+       char buffer[BUFSIZ];
+
+       while (chunksize != 0) {
+               if (chunksize > BUFSIZ)
                        size = BUFSIZ;
-               } else {
+               else
                        size = chunksize;
+
+               nread = fread (buffer, 1, size, src_file);
+
+               if (nread != size && ferror (src_file)) {
+                       perror_msg ("read");
+                       return -1;
+               } else if (nread == 0) {
+                       if (chunksize != -1) {
+                               error_msg ("Unable to read all data");
+                               return -1;
+                       }
+
+                       return 0;
                }
-               amount_written = fwrite(buffer, 1, fread(buffer, 1, size, src_file), dst_file);
-               if (amount_written != size) {
-                       error_msg("Couldnt write correct amount");
-                       return(FALSE);
+
+               nwritten = fwrite (buffer, 1, nread, dst_file);
+
+               if (nwritten != nread) {
+                       if (ferror (dst_file))
+                               perror_msg ("write");
+                       else
+                               error_msg ("Unable to write all data");
+                       return -1;
                }
-               chunksize -= amount_written;
+
+               if (chunksize != -1)
+                       chunksize -= nwritten;
        }
-       return (TRUE);
-}
 
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
+       return 0;
+}