X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/71c4617611ca07d7c249faa2dfd2cfc5cb32b836..fc4e8d51ff374d442de010c2a7d3b55b57248d86:/io.c diff --git a/io.c b/io.c index aae64b75..a557a9b8 100644 --- a/io.c +++ b/io.c @@ -29,6 +29,7 @@ static int64 total_read; extern int verbose; extern int sparse_files; +extern int io_timeout; int64 write_total(void) { @@ -95,39 +96,71 @@ 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; + total += 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; } @@ -295,7 +328,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; @@ -305,6 +341,9 @@ static int writefd(int fd,char *buf,int len) } } + if (io_timeout) + last_io = time(NULL); + return total; }