X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/6b45fcf160fdc4cb78805835e05e25015fe4f973..b9b15fb165d9adbfb56201429af2bd0f492c483c:/io.c diff --git a/io.c b/io.c index 84a85bb3..bf7f3d90 100644 --- a/io.c +++ b/io.c @@ -41,8 +41,8 @@ static int io_multiplexing_out; static int io_multiplexing_in; -static int multiplex_in_fd; -static int multiplex_out_fd; +static int multiplex_in_fd = -1; +static int multiplex_out_fd = -1; static time_t last_io; static int no_flush; @@ -228,14 +228,14 @@ static int read_timeout(int fd, char *buf, size_t len) FD_ZERO(&r_fds); FD_SET(fd, &r_fds); - if (io_error_fd != -1) { + if (io_error_fd >= 0) { FD_SET(io_error_fd, &r_fds); if (io_error_fd >= fd_count) fd_count = io_error_fd+1; } - if (io_filesfrom_f_out != -1) { + if (io_filesfrom_f_out >= 0) { int new_fd; if (io_filesfrom_buflen == 0) { - if (io_filesfrom_f_in != -1) { + if (io_filesfrom_f_in >= 0) { FD_SET(io_filesfrom_f_in, &r_fds); new_fd = io_filesfrom_f_in; } else { @@ -270,11 +270,11 @@ static int read_timeout(int fd, char *buf, size_t len) continue; } - if (io_error_fd != -1 && FD_ISSET(io_error_fd, &r_fds)) { + if (io_error_fd >= 0 && FD_ISSET(io_error_fd, &r_fds)) { read_error_fd(); } - if (io_filesfrom_f_out != -1) { + if (io_filesfrom_f_out >= 0) { if (io_filesfrom_buflen) { if (FD_ISSET(io_filesfrom_f_out, &w_fds)) { int l = write(io_filesfrom_f_out, @@ -290,7 +290,7 @@ static int read_timeout(int fd, char *buf, size_t len) io_filesfrom_f_out = -1; } } - } else if (io_filesfrom_f_in != -1) { + } else if (io_filesfrom_f_in >= 0) { if (FD_ISSET(io_filesfrom_f_in, &r_fds)) { int l = read(io_filesfrom_f_in, io_filesfrom_buf, @@ -352,7 +352,7 @@ static int read_timeout(int fd, char *buf, size_t len) } else if (n == 0) { whine_about_eof(); return -1; /* doesn't return */ - } else if (n == -1) { + } else if (n < 0) { if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) continue; @@ -440,17 +440,31 @@ static int read_unbuffered(int fd, char *buf, size_t len) static size_t remaining; int tag, ret = 0; char line[1024]; + static char *buffer; + static size_t bufferIdx = 0; + static size_t bufferSz; - if (!io_multiplexing_in || fd != multiplex_in_fd) + if (fd != multiplex_in_fd) return read_timeout(fd, buf, len); + if (!io_multiplexing_in && remaining == 0) { + if (!buffer) { + bufferSz = 2 * IO_BUFFER_SIZE; + buffer = new_array(char, bufferSz); + if (!buffer) out_of_memory("read_unbuffered"); + } + remaining = read_timeout(fd, buffer, bufferSz); + bufferIdx = 0; + } + while (ret == 0) { if (remaining) { len = MIN(len, remaining); - read_loop(fd, buf, len); + memcpy(buf, buffer + bufferIdx, len); + bufferIdx += len; remaining -= len; ret = len; - continue; + break; } read_loop(fd, line, 4); @@ -459,8 +473,16 @@ static int read_unbuffered(int fd, char *buf, size_t len) remaining = tag & 0xFFFFFF; tag = tag >> 24; - if (tag == MPLEX_BASE) + if (tag == MPLEX_BASE) { + if (!buffer || remaining > bufferSz) { + buffer = realloc_array(buffer, char, remaining); + if (!buffer) out_of_memory("read_unbuffered"); + bufferSz = remaining; + } + read_loop(fd, buffer, remaining); + bufferIdx = 0; continue; + } tag -= MPLEX_BASE; @@ -482,6 +504,9 @@ static int read_unbuffered(int fd, char *buf, size_t len) remaining = 0; } + if (remaining == 0) + io_flush(); + return ret; } @@ -498,8 +523,6 @@ static void readfd(int fd, char *buffer, size_t N) size_t total=0; while (total < N) { - io_flush(); - ret = read_unbuffered(fd, buffer + total, N-total); total += ret; } @@ -608,7 +631,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) FD_SET(fd,&w_fds); fd_count = fd; - if (io_error_fd != -1) { + if (io_error_fd >= 0) { FD_ZERO(&r_fds); FD_SET(io_error_fd,&r_fds); if (io_error_fd > fd_count) @@ -621,7 +644,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) errno = 0; count = select(fd_count+1, - io_error_fd != -1?&r_fds:NULL, + io_error_fd >= 0?&r_fds:NULL, &w_fds,NULL, &tv); @@ -636,7 +659,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) continue; } - if (io_error_fd != -1 && FD_ISSET(io_error_fd, &r_fds)) { + if (io_error_fd >= 0 && FD_ISSET(io_error_fd, &r_fds)) { read_error_fd(); } @@ -645,14 +668,13 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) size_t n = len-total; ret = write(fd,buf+total,n); - if (ret == -1 && errno == EINTR) { - continue; - } - - if (ret == -1 && - (errno == EWOULDBLOCK || errno == EAGAIN)) { - msleep(1); - continue; + if (ret < 0) { + if (errno == EINTR) + continue; + if (errno == EWOULDBLOCK || errno == EAGAIN) { + msleep(1); + continue; + } } if (ret <= 0) { @@ -682,7 +704,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) static char *io_buffer; static int io_buffer_count; -void io_start_buffering(int fd) +void io_start_buffering_out(int fd) { if (io_buffer) return; multiplex_out_fd = fd; @@ -691,6 +713,11 @@ void io_start_buffering(int fd) io_buffer_count = 0; } +void io_start_buffering_in(int fd) +{ + multiplex_in_fd = fd; +} + /** * Write an message to a multiplexed stream. If this fails then rsync * exits. @@ -881,7 +908,7 @@ void io_start_multiplex_out(int fd) { multiplex_out_fd = fd; io_flush(); - io_start_buffering(fd); + io_start_buffering_out(fd); io_multiplexing_out = 1; }