aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorMatt Kraai <kraai@debian.org>2001-06-11 13:58:02 +0000
committerMatt Kraai <kraai@debian.org>2001-06-11 13:58:02 +0000
commitbf0a010cf705d21c75d2c6ba8de38cec038f9aa1 (patch)
tree5a059e12e61728a72d4ec58166ec63794d944ed3 /libbb
parent5246225596a45de63a994abbef92b7d23180681c (diff)
downloadbusybox-bf0a010cf705d21c75d2c6ba8de38cec038f9aa1.tar.gz
Copy files until EOF, not the reported file size, to deal with bad sizes in
the proc filesystem.
Diffstat (limited to 'libbb')
-rw-r--r--libbb/copy_file.c7
-rw-r--r--libbb/copy_file_chunk.c62
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;
+}