diff options
author | Matt Kraai <kraai@debian.org> | 2001-06-11 13:58:02 +0000 |
---|---|---|
committer | Matt Kraai <kraai@debian.org> | 2001-06-11 13:58:02 +0000 |
commit | bf0a010cf705d21c75d2c6ba8de38cec038f9aa1 (patch) | |
tree | 5a059e12e61728a72d4ec58166ec63794d944ed3 | |
parent | 5246225596a45de63a994abbef92b7d23180681c (diff) | |
download | busybox-bf0a010cf705d21c75d2c6ba8de38cec038f9aa1.tar.gz |
Copy files until EOF, not the reported file size, to deal with bad sizes in
the proc filesystem.
-rw-r--r-- | libbb/copy_file.c | 7 | ||||
-rw-r--r-- | libbb/copy_file_chunk.c | 62 |
2 files changed, 39 insertions, 30 deletions
diff --git a/libbb/copy_file.c b/libbb/copy_file.c index 22684be74..24bdf9002 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c @@ -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); diff --git a/libbb/copy_file_chunk.c b/libbb/copy_file_chunk.c index e9663c354..c440a6102 100644 --- a/libbb/copy_file_chunk.c +++ b/libbb/copy_file_chunk.c @@ -29,38 +29,46 @@ #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; +} |