X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/344fb1276b0215f7b3fb5067fae69619691541c8..593fde2d3bfeaaeff4103ce354215783be1cec9f:/io.c diff --git a/io.c b/io.c index 52c4cb14..b48ae0f9 100644 --- a/io.c +++ b/io.c @@ -45,8 +45,8 @@ static int buffer_f_in = -1; void setup_nonblocking(int f_in,int f_out) { - set_blocking(f_out,0); - buffer_f_in = f_in; + set_blocking(f_out,0); + buffer_f_in = f_in; } @@ -61,39 +61,42 @@ static int read_buffer_size; * ssh will clag up. Uggh. */ static void read_check(int f) { - int n; + int n; - if (f == -1) return; + if (f == -1) return; - if (read_buffer_len == 0) { - read_buffer_p = read_buffer; - } + if (read_buffer_len == 0) { + read_buffer_p = read_buffer; + } - if ((n=num_waiting(f)) <= 0) - return; + if ((n=num_waiting(f)) <= 0) + return; - /* things could deteriorate if we read in really small chunks */ - if (n < 10) n = 1024; + /* things could deteriorate if we read in really small chunks */ + if (n < 10) n = 1024; - if (read_buffer_p != read_buffer) { - memmove(read_buffer,read_buffer_p,read_buffer_len); - read_buffer_p = read_buffer; - } + if (n > MAX_READ_BUFFER/4) + n = MAX_READ_BUFFER/4; - if (n > (read_buffer_size - read_buffer_len)) { - read_buffer_size += n; - if (!read_buffer) - read_buffer = (char *)malloc(read_buffer_size); - else - read_buffer = (char *)realloc(read_buffer,read_buffer_size); - if (!read_buffer) out_of_memory("read check"); - read_buffer_p = read_buffer; - } + if (read_buffer_p != read_buffer) { + memmove(read_buffer,read_buffer_p,read_buffer_len); + read_buffer_p = read_buffer; + } - n = read(f,read_buffer+read_buffer_len,n); - if (n > 0) { - read_buffer_len += n; - } + if (n > (read_buffer_size - read_buffer_len)) { + read_buffer_size += n; + if (!read_buffer) + read_buffer = (char *)malloc(read_buffer_size); + else + read_buffer = (char *)realloc(read_buffer,read_buffer_size); + if (!read_buffer) out_of_memory("read check"); + read_buffer_p = read_buffer; + } + + n = read(f,read_buffer+read_buffer_len,n); + if (n > 0) { + read_buffer_len += n; + } } static time_t last_io; @@ -301,7 +304,7 @@ int write_file(int f,char *buf,int len) } -static int writefd(int fd,char *buf,int len) +static int writefd_unbuffered(int fd,char *buf,int len) { int total = 0; fd_set w_fds, r_fds; @@ -334,38 +337,40 @@ static int writefd(int fd,char *buf,int len) if (ret == -1) { - read_check(buffer_f_in); - - fd_count = fd+1; - FD_ZERO(&w_fds); - FD_ZERO(&r_fds); - FD_SET(fd,&w_fds); - if (buffer_f_in != -1) { - FD_SET(buffer_f_in,&r_fds); - if (buffer_f_in > fd) - fd_count = buffer_f_in+1; - } - - tv.tv_sec = BLOCKING_TIMEOUT; - tv.tv_usec = 0; - count = select(fd_count,buffer_f_in == -1? NULL: &r_fds, - &w_fds,NULL,&tv); - if (count == -1 && errno != EINTR) { - if (verbose > 1) - rprintf(FERROR,"select error: %s\n", strerror(errno)); - exit_cleanup(1); - } - - if (count == 0) { - check_timeout(); - continue; - } + if (read_buffer_len < MAX_READ_BUFFER) + read_check(buffer_f_in); + + fd_count = fd+1; + FD_ZERO(&w_fds); + FD_ZERO(&r_fds); + FD_SET(fd,&w_fds); + if (buffer_f_in != -1) { + FD_SET(buffer_f_in,&r_fds); + if (buffer_f_in > fd) + fd_count = buffer_f_in+1; + } + + tv.tv_sec = BLOCKING_TIMEOUT; + tv.tv_usec = 0; + count = select(fd_count,buffer_f_in == -1? NULL: &r_fds, + &w_fds,NULL,&tv); + + if (count == -1 && errno != EINTR) { + if (verbose > 1) + rprintf(FERROR,"select error: %s\n", strerror(errno)); + exit_cleanup(1); + } + + if (count == 0) { + check_timeout(); + continue; + } - if (FD_ISSET(fd, &w_fds)) { - got_select = 1; - } + if (FD_ISSET(fd, &w_fds)) { + got_select = 1; + } } else { - total += ret; + total += ret; } } @@ -375,6 +380,58 @@ static int writefd(int fd,char *buf,int len) return total; } +static char *io_buffer; +static int io_buffer_count; + +void io_start_buffering(int fd) +{ + io_buffer = (char *)malloc(IO_BUFFER_SIZE); + if (!io_buffer) out_of_memory("writefd"); + io_buffer_count = 0; +} + +void io_end_buffering(int fd) +{ + if (io_buffer_count) { + if (writefd_unbuffered(fd, io_buffer, + io_buffer_count) != + io_buffer_count) { + rprintf(FERROR,"write failed\n"); + exit_cleanup(1); + } + io_buffer_count = 0; + } + free(io_buffer); + io_buffer = NULL; +} + +static int writefd(int fd,char *buf,int len1) +{ + int len = len1; + + if (!io_buffer) return writefd_unbuffered(fd, buf, len); + + while (len) { + int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count); + if (n > 0) { + memcpy(io_buffer+io_buffer_count, buf, n); + buf += n; + len -= n; + io_buffer_count += n; + } + + if (io_buffer_count == IO_BUFFER_SIZE) { + if (writefd_unbuffered(fd, io_buffer, + io_buffer_count) != + io_buffer_count) { + return -1; + } + io_buffer_count = 0; + } + } + + return len1; +} void write_int(int f,int32 x) @@ -469,13 +526,7 @@ void io_printf(int fd, const char *format, ...) int len; va_start(ap, format); - -#if HAVE_VSNPRINTF - len = vsnprintf(buf, sizeof(buf)-1, format, ap); -#else - vsprintf(buf, format, ap); - len = strlen(buf); -#endif + len = vslprintf(buf, sizeof(buf)-1, format, ap); va_end(ap); if (len < 0) exit_cleanup(1);