Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/libbb/copyfd.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/libbb/copyfd.c
r821 r1770 8 8 */ 9 9 10 #include <errno.h>11 #include <stdlib.h>12 #include <string.h>13 #include <unistd.h>14 15 10 #include "libbb.h" 16 17 11 18 12 #if BUFSIZ < 4096 … … 21 15 #endif 22 16 17 /* Used by NOFORK applets (e.g. cat) - must not use xmalloc */ 23 18 24 static ssize_t bb_full_fd_action(int src_fd, int dst_fd, size_t size)19 static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) 25 20 { 26 21 int status = -1; 27 size_t total = 0;28 RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);22 off_t total = 0; 23 char buffer[BUFSIZ]; 29 24 30 if (src_fd < 0) goto out; 31 while (!size || total < size) 32 { 33 ssize_t wrote, xread; 25 if (src_fd < 0) 26 goto out; 34 27 35 xread = safe_read(src_fd, buffer, 36 (!size || size - total > BUFSIZ) ? BUFSIZ : size - total); 28 if (!size) { 29 size = BUFSIZ; 30 status = 1; /* copy until eof */ 31 } 37 32 38 if (xread > 0) { 39 /* A -1 dst_fd means we need to fake it... */ 40 wrote = (dst_fd < 0) ? xread : bb_full_write(dst_fd, buffer, xread); 41 if (wrote < xread) { 33 while (1) { 34 ssize_t rd; 35 36 rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size); 37 38 if (!rd) { /* eof - all done */ 39 status = 0; 40 break; 41 } 42 if (rd < 0) { 43 bb_perror_msg(bb_msg_read_error); 44 break; 45 } 46 /* dst_fd == -1 is a fake, else... */ 47 if (dst_fd >= 0) { 48 ssize_t wr = full_write(dst_fd, buffer, rd); 49 if (wr < rd) { 42 50 bb_perror_msg(bb_msg_write_error); 43 51 break; 44 52 } 45 total += wrote;46 if (total == size) status = 0;47 } else if (xread < 0) {48 bb_perror_msg(bb_msg_read_error);49 break;50 } else if (xread == 0) {51 /* All done. */52 status = 0;53 break;53 } 54 total += rd; 55 if (status < 0) { /* if we aren't copying till EOF... */ 56 size -= rd; 57 if (!size) { 58 /* 'size' bytes copied - all done */ 59 status = 0; 60 break; 61 } 54 62 } 55 63 } 56 57 out: 58 RELEASE_CONFIG_BUFFER(buffer); 59 60 return status ? status : (ssize_t)total; 64 out: 65 return status ? -1 : total; 61 66 } 62 67 63 68 64 int bb_copyfd_size(int fd1, int fd2, const off_t size) 69 #if 0 70 void complain_copyfd_and_die(off_t sz) 71 { 72 if (sz != -1) 73 bb_error_msg_and_die("short read"); 74 /* if sz == -1, bb_copyfd_XX already complained */ 75 xfunc_die(); 76 } 77 #endif 78 79 off_t bb_copyfd_size(int fd1, int fd2, off_t size) 65 80 { 66 81 if (size) { 67 return (bb_full_fd_action(fd1, fd2, size));82 return bb_full_fd_action(fd1, fd2, size); 68 83 } 69 return (0);84 return 0; 70 85 } 71 86 72 int bb_copyfd_eof(int fd1, int fd2)87 void bb_copyfd_exact_size(int fd1, int fd2, off_t size) 73 88 { 74 return(bb_full_fd_action(fd1, fd2, 0)); 89 off_t sz = bb_copyfd_size(fd1, fd2, size); 90 if (sz == size) 91 return; 92 if (sz != -1) 93 bb_error_msg_and_die("short read"); 94 /* if sz == -1, bb_copyfd_XX already complained */ 95 xfunc_die(); 75 96 } 97 98 off_t bb_copyfd_eof(int fd1, int fd2) 99 { 100 return bb_full_fd_action(fd1, fd2, 0); 101 }
Note:
See TracChangeset
for help on using the changeset viewer.