Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/libbb/copyfd.c


Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/libbb/copyfd.c

    r2725 r3621  
    99
    1010#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)
    1125
    1226/* Used by NOFORK applets (e.g. cat) - must not use xmalloc.
     
    1933    off_t total = 0;
    2034    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
    2240    char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024];
    2341    enum { buffer_size = sizeof(buffer) };
    24 #else
    25     char *buffer;
    26     int buffer_size;
    2742#endif
    2843
     
    3247    }
    3348
    34 #if CONFIG_FEATURE_COPYBUF_KB > 4
    35     if (size > 0 && size <= 4 * 1024)
    36         goto use_small_buf;
    37     /* We want page-aligned buffer, just in case kernel is clever
    38      * 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 #endif
    50 
    5149    if (src_fd < 0)
    5250        goto out;
    5351
     52    sendfile_sz = !ENABLE_FEATURE_USE_SENDFILE
     53        ? 0
     54        : SENDFILE_BIGBUF;
    5455    if (!size) {
    55         size = buffer_size;
     56        size = SENDFILE_BIGBUF;
    5657        status = 1; /* copy until eof */
    5758    }
     
    6061        ssize_t rd;
    6162
    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:
    6495        if (!rd) { /* eof - all done */
    6596            status = 0;
    6697            break;
    6798        }
    68         if (rd < 0) {
    69             bb_perror_msg(bb_msg_read_error);
    70             break;
    71         }
    7299        /* dst_fd == -1 is a fake, else... */
    73         if (dst_fd >= 0) {
     100        if (dst_fd >= 0 && !sendfile_sz) {
    74101            ssize_t wr = full_write(dst_fd, buffer, rd);
    75102            if (wr < rd) {
     
    93120 out:
    94121
    95 #if CONFIG_FEATURE_COPYBUF_KB > 4
    96     if (buffer_size != 4 * 1024)
     122    if (buffer_size > 4 * 1024)
    97123        munmap(buffer, buffer_size);
    98 #endif
    99124    return status ? -1 : total;
    100125}
Note: See TracChangeset for help on using the changeset viewer.