X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/3eeac9bc7ed328b44ca4e49a6daa0fd272c1114c..f2a4853c93136bfa282cff767873064db3ebb28c:/io.c diff --git a/io.c b/io.c index 42a6bf0c..f8b908e3 100644 --- a/io.c +++ b/io.c @@ -574,7 +574,7 @@ static int read_timeout(int fd, char *buf, size_t len) len -= n; ret += n; - if (io_timeout && fd == sock_f_in) + if (fd == sock_f_in && (io_timeout || am_generator)) last_io = time(NULL); } @@ -665,6 +665,13 @@ void io_end_buffering(void) } +void maybe_flush_socket(void) +{ + if (iobuf_out && iobuf_out_cnt && time(NULL) - last_io >= 5) + io_flush(NORMAL_FLUSH); +} + + void maybe_send_keepalive(void) { if (time(NULL) - last_io >= allowed_lull) { @@ -705,8 +712,13 @@ static int readfd_unbuffered(int fd, char *buf, size_t len) { static size_t remaining; static size_t iobuf_in_ndx; + size_t msg_bytes; int tag, ret = 0; - char line[MAXPATHLEN+1]; +#if MAXPATHLEN < 4096 + char line[4096+1024]; +#else + char line[MAXPATHLEN+1024]; +#endif if (!iobuf_in || fd != sock_f_in) return read_timeout(fd, buf, len); @@ -729,56 +741,52 @@ static int readfd_unbuffered(int fd, char *buf, size_t len) read_loop(fd, line, 4); tag = IVAL(line, 0); - remaining = tag & 0xFFFFFF; + msg_bytes = tag & 0xFFFFFF; tag = (tag >> 24) - MPLEX_BASE; switch (tag) { case MSG_DATA: - if (remaining > iobuf_in_siz) { + if (msg_bytes > iobuf_in_siz) { if (!(iobuf_in = realloc_array(iobuf_in, char, - remaining))) + msg_bytes))) out_of_memory("readfd_unbuffered"); - iobuf_in_siz = remaining; + iobuf_in_siz = msg_bytes; } - read_loop(fd, iobuf_in, remaining); + read_loop(fd, iobuf_in, msg_bytes); + remaining = msg_bytes; iobuf_in_ndx = 0; break; case MSG_DELETED: - if (remaining >= sizeof line) { - rprintf(FERROR, "invalid multi-message %d:%ld\n", - tag, (long)remaining); - exit_cleanup(RERR_STREAMIO); - } - read_loop(fd, line, remaining); - line[remaining] = '\0'; + if (msg_bytes >= sizeof line) + goto overflow; + read_loop(fd, line, msg_bytes); + line[msg_bytes] = '\0'; /* A directory name was sent with the trailing null */ - if (remaining > 0 && !line[remaining-1]) + if (msg_bytes > 0 && !line[msg_bytes-1]) log_delete(line, S_IFDIR); else log_delete(line, S_IFREG); - remaining = 0; break; case MSG_SUCCESS: - if (remaining != 4) { + if (msg_bytes != 4) { rprintf(FERROR, "invalid multi-message %d:%ld [%s]\n", - tag, (long)remaining, who_am_i()); + tag, (long)msg_bytes, who_am_i()); exit_cleanup(RERR_STREAMIO); } - read_loop(fd, line, remaining); + read_loop(fd, line, msg_bytes); successful_send(IVAL(line, 0)); - remaining = 0; break; case MSG_INFO: case MSG_ERROR: - if (remaining >= sizeof line) { + if (msg_bytes >= sizeof line) { + overflow: rprintf(FERROR, "multiplexing overflow %d:%ld [%s]\n", - tag, (long)remaining, who_am_i()); + tag, (long)msg_bytes, who_am_i()); exit_cleanup(RERR_STREAMIO); } - read_loop(fd, line, remaining); - rwrite((enum logcode)tag, line, remaining); - remaining = 0; + read_loop(fd, line, msg_bytes); + rwrite((enum logcode)tag, line, msg_bytes); break; default: rprintf(FERROR, "unexpected tag %d [%s]\n", @@ -1024,11 +1032,6 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) using_r_fds = 1; } else using_r_fds = 0; - if (fd != sock_f_out && iobuf_out_cnt && no_flush == 1) { - FD_SET(sock_f_out, &w_fds); - if (sock_f_out > maxfd) - maxfd = sock_f_out; - } tv.tv_sec = select_timeout; tv.tv_usec = 0; @@ -1085,7 +1088,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) total += ret; if (fd == sock_f_out) { - if (io_timeout) + if (io_timeout || am_generator) last_io = time(NULL); sleep_for_bwlimit(ret); }