diff -urpN busybox-1.2.0/include/libbb.h busybox-1.2.0-cp/include/libbb.h --- busybox-1.2.0/include/libbb.h 2006-07-01 00:42:10.000000000 +0200 +++ busybox-1.2.0-cp/include/libbb.h 2011-08-04 10:53:28.403950705 +0200 @@ -160,8 +160,8 @@ extern char *find_block_device(char *pat extern char *bb_get_line_from_file(FILE *file); extern char *bb_get_chomped_line_from_file(FILE *file); extern char *bb_get_chunk_from_file(FILE *file, int *end); -extern int bb_copyfd_size(int fd1, int fd2, const off_t size); -extern int bb_copyfd_eof(int fd1, int fd2); +extern off_t bb_copyfd_size(int fd1, int fd2, off_t size); +extern off_t bb_copyfd_eof(int fd1, int fd2); extern void bb_xprint_and_close_file(FILE *file); extern int bb_xprint_file_by_name(const char *filename); extern char bb_process_escape_sequence(const char **ptr); diff -urpN busybox-1.2.0/libbb/copyfd.c busybox-1.2.0-cp/libbb/copyfd.c --- busybox-1.2.0/libbb/copyfd.c 2006-07-01 00:42:08.000000000 +0200 +++ busybox-1.2.0-cp/libbb/copyfd.c 2011-08-04 10:54:58.708818468 +0200 @@ -14,62 +14,66 @@ #include "libbb.h" - -#if BUFSIZ < 4096 -#undef BUFSIZ -#define BUFSIZ 4096 -#endif - - -static ssize_t bb_full_fd_action(int src_fd, int dst_fd, size_t size) +static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) { int status = -1; - size_t total = 0; - RESERVE_CONFIG_BUFFER(buffer,BUFSIZ); + off_t total = 0; + char buffer[4 * 1024]; + enum { buffer_size = sizeof(buffer) }; + + if (src_fd < 0) + goto out; + + if (!size) { + size = buffer_size; + status = 1; /* copy until eof */ + } + + while (1) { + ssize_t rd; + + rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size); - if (src_fd < 0) goto out; - while (!size || total < size) - { - ssize_t wrote, xread; - - xread = safe_read(src_fd, buffer, - (!size || size - total > BUFSIZ) ? BUFSIZ : size - total); - - if (xread > 0) { - /* A -1 dst_fd means we need to fake it... */ - wrote = (dst_fd < 0) ? xread : bb_full_write(dst_fd, buffer, xread); - if (wrote < xread) { + if (!rd) { /* eof - all done */ + status = 0; + break; + } + if (rd < 0) { + bb_perror_msg(bb_msg_read_error); + break; + } + /* dst_fd == -1 is a fake, else... */ + if (dst_fd >= 0) { + ssize_t wr = bb_full_write(dst_fd, buffer, rd); + if (wr < rd) { bb_perror_msg(bb_msg_write_error); break; } - total += wrote; - if (total == size) status = 0; - } else if (xread < 0) { - bb_perror_msg(bb_msg_read_error); - break; - } else if (xread == 0) { - /* All done. */ - status = 0; - break; + } + total += rd; + if (status < 0) { /* if we aren't copying till EOF... */ + size -= rd; + if (!size) { + /* 'size' bytes copied - all done */ + status = 0; + break; + } } } + out: -out: - RELEASE_CONFIG_BUFFER(buffer); - - return status ? status : (ssize_t)total; + return status ? -1 : total; } - -int bb_copyfd_size(int fd1, int fd2, const off_t size) +off_t bb_copyfd_size(int fd1, int fd2, off_t size) { if (size) { - return(bb_full_fd_action(fd1, fd2, size)); + return bb_full_fd_action(fd1, fd2, size); } - return(0); + return 0; } -int bb_copyfd_eof(int fd1, int fd2) +off_t bb_copyfd_eof(int fd1, int fd2) { - return(bb_full_fd_action(fd1, fd2, 0)); + return bb_full_fd_action(fd1, fd2, 0); }