X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/3a6a366fc5ac1f418446128de50b4f2a174399fc..6ba9279fb2c52280cedaaca94783caf44ae9d324:/io.c diff --git a/io.c b/io.c index 75127f01..b5ceff12 100644 --- a/io.c +++ b/io.c @@ -24,18 +24,19 @@ */ #include "rsync.h" -static off_t total_written; -static off_t total_read; +static int64 total_written; +static int64 total_read; extern int verbose; extern int sparse_files; +extern int io_timeout; -off_t write_total(void) +int64 write_total(void) { return total_written; } -off_t read_total(void) +int64 read_total(void) { return total_read; } @@ -95,39 +96,70 @@ static void read_check(int f) } } +static time_t last_io; + + +static void check_timeout(void) +{ + time_t t; + + if (!io_timeout) return; + + if (!last_io) { + last_io = time(NULL); + return; + } + + t = time(NULL); + + if (last_io && io_timeout && (t-last_io)>io_timeout) { + fprintf(FERROR,"read timeout after %d second - exiting\n", + (int)(t-last_io)); + exit_cleanup(1); + } +} static int readfd(int fd,char *buffer,int N) { - int ret; - int total=0; - - if (read_buffer_len < N) - read_check(buffer_f_in); - - while (total < N) - { - if (read_buffer_len > 0 && buffer_f_in == fd) { - ret = MIN(read_buffer_len,N-total); - memcpy(buffer+total,read_buffer_p,ret); - read_buffer_p += ret; - read_buffer_len -= ret; - } else { - while ((ret = read(fd,buffer + total,N - total)) == -1) { - fd_set fds; - - if (errno != EAGAIN && errno != EWOULDBLOCK) - return -1; - FD_ZERO(&fds); - FD_SET(fd, &fds); - select(fd+1, &fds, NULL, NULL, NULL); + int ret; + int total=0; + struct timeval tv; + + if (read_buffer_len < N) + read_check(buffer_f_in); + + while (total < N) { + if (read_buffer_len > 0 && buffer_f_in == fd) { + ret = MIN(read_buffer_len,N-total); + memcpy(buffer+total,read_buffer_p,ret); + read_buffer_p += ret; + read_buffer_len -= ret; + continue; + } + + while ((ret = read(fd,buffer + total,N-total)) == -1) { + fd_set fds; + + if (errno != EAGAIN && errno != EWOULDBLOCK) + return -1; + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = io_timeout; + tv.tv_usec = 0; + + if (select(fd+1, &fds, NULL, NULL, &tv) != 1) { + check_timeout(); + } + } + + if (ret <= 0) + return total; + total += ret; } - } - if (ret <= 0) + if (io_timeout) + last_io = time(NULL); return total; - total += ret; - } - return total; } @@ -145,17 +177,20 @@ int read_int(int f) return IVAL(b,0); } -off_t read_longint(int f) +int64 read_longint(int f) { extern int remote_version; - off_t ret; + int64 ret; char b[8]; ret = read_int(f); - if (ret == -1 && remote_version >= 16) { - if (sizeof(off_t) <= 4) { - fprintf(FERROR,"Integer overflow - attempted 64 bit offset\n"); - exit_cleanup(1); - } + + if (ret != -1) return ret; + +#ifndef HAVE_LONGLONG + fprintf(FERROR,"Integer overflow - attempted 64 bit offset\n"); + exit_cleanup(1); +#else + if (remote_version >= 16) { if ((ret=readfd(f,b,8)) != 8) { if (verbose > 1) fprintf(FERROR,"(%d) Error reading %d bytes : %s\n", @@ -163,8 +198,10 @@ off_t read_longint(int f) exit_cleanup(1); } total_read += 8; - ret = IVAL(b,0) | (((off_t)IVAL(b,4))<<32); + ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32); } +#endif + return ret; } @@ -290,7 +327,10 @@ static int writefd(int fd,char *buf,int len) exit_cleanup(1); } - if (count == 0) continue; + if (count == 0) { + check_timeout(); + continue; + } if (FD_ISSET(fd, &w_fds)) { got_select = 1; @@ -300,6 +340,9 @@ static int writefd(int fd,char *buf,int len) } } + if (io_timeout) + last_io = time(NULL); + return total; } @@ -318,7 +361,7 @@ void write_int(int f,int x) total_written += 4; } -void write_longint(int f, off_t x) +void write_longint(int f, int64 x) { extern int remote_version; char b[8];