Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/libbb/copyfd.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/libbb/copyfd.c
r2725 r3621 9 9 10 10 #include "libbb.h" 11 #if ENABLE_FEATURE_USE_SENDFILE 12 # include <sys/sendfile.h> 13 #else 14 # define sendfile(a,b,c,d) (-1) 15 #endif 16 17 /* 18 * We were using 0x7fff0000 as sendfile chunk size, but it 19 * was seen to cause largish delays when user tries to ^C a file copy. 20 * Let's use a saner size. 21 * Note: needs to be >= max(CONFIG_FEATURE_COPYBUF_KB), 22 * or else "copy to eof" code will use neddlesly short reads. 23 */ 24 #define SENDFILE_BIGBUF (16*1024*1024) 11 25 12 26 /* Used by NOFORK applets (e.g. cat) - must not use xmalloc. … … 19 33 off_t total = 0; 20 34 bool continue_on_write_error = 0; 21 #if CONFIG_FEATURE_COPYBUF_KB <= 4 35 ssize_t sendfile_sz; 36 #if CONFIG_FEATURE_COPYBUF_KB > 4 37 char *buffer = buffer; /* for compiler */ 38 int buffer_size = 0; 39 #else 22 40 char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024]; 23 41 enum { buffer_size = sizeof(buffer) }; 24 #else25 char *buffer;26 int buffer_size;27 42 #endif 28 43 … … 32 47 } 33 48 34 #if CONFIG_FEATURE_COPYBUF_KB > 435 if (size > 0 && size <= 4 * 1024)36 goto use_small_buf;37 /* We want page-aligned buffer, just in case kernel is clever38 * and can do page-aligned io more efficiently */39 buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024,40 PROT_READ | PROT_WRITE,41 MAP_PRIVATE | MAP_ANON,42 /* ignored: */ -1, 0);43 buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024;44 if (buffer == MAP_FAILED) {45 use_small_buf:46 buffer = alloca(4 * 1024);47 buffer_size = 4 * 1024;48 }49 #endif50 51 49 if (src_fd < 0) 52 50 goto out; 53 51 52 sendfile_sz = !ENABLE_FEATURE_USE_SENDFILE 53 ? 0 54 : SENDFILE_BIGBUF; 54 55 if (!size) { 55 size = buffer_size;56 size = SENDFILE_BIGBUF; 56 57 status = 1; /* copy until eof */ 57 58 } … … 60 61 ssize_t rd; 61 62 62 rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size); 63 63 if (sendfile_sz) { 64 rd = sendfile(dst_fd, src_fd, NULL, 65 size > sendfile_sz ? sendfile_sz : size); 66 if (rd >= 0) 67 goto read_ok; 68 sendfile_sz = 0; /* do not try sendfile anymore */ 69 } 70 #if CONFIG_FEATURE_COPYBUF_KB > 4 71 if (buffer_size == 0) { 72 if (size > 0 && size <= 4 * 1024) 73 goto use_small_buf; 74 /* We want page-aligned buffer, just in case kernel is clever 75 * and can do page-aligned io more efficiently */ 76 buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024, 77 PROT_READ | PROT_WRITE, 78 MAP_PRIVATE | MAP_ANON, 79 /* ignored: */ -1, 0); 80 buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024; 81 if (buffer == MAP_FAILED) { 82 use_small_buf: 83 buffer = alloca(4 * 1024); 84 buffer_size = 4 * 1024; 85 } 86 } 87 #endif 88 rd = safe_read(src_fd, buffer, 89 size > buffer_size ? buffer_size : size); 90 if (rd < 0) { 91 bb_perror_msg(bb_msg_read_error); 92 break; 93 } 94 read_ok: 64 95 if (!rd) { /* eof - all done */ 65 96 status = 0; 66 97 break; 67 98 } 68 if (rd < 0) {69 bb_perror_msg(bb_msg_read_error);70 break;71 }72 99 /* dst_fd == -1 is a fake, else... */ 73 if (dst_fd >= 0 ) {100 if (dst_fd >= 0 && !sendfile_sz) { 74 101 ssize_t wr = full_write(dst_fd, buffer, rd); 75 102 if (wr < rd) { … … 93 120 out: 94 121 95 #if CONFIG_FEATURE_COPYBUF_KB > 4 96 if (buffer_size != 4 * 1024) 122 if (buffer_size > 4 * 1024) 97 123 munmap(buffer, buffer_size); 98 #endif99 124 return status ? -1 : total; 100 125 }
Note:
See TracChangeset
for help on using the changeset viewer.