make sure that io_flush() doesn't call writefd_unbuffered from within
[rsync/rsync.git] / io.c
diff --git a/io.c b/io.c
index 4c704eb..a88d76a 100644 (file)
--- a/io.c
+++ b/io.c
@@ -32,10 +32,11 @@ static int io_multiplexing_in;
 static int multiplex_in_fd;
 static int multiplex_out_fd;
 static time_t last_io;
-
+static int eof_error=1;
 extern int verbose;
 extern int io_timeout;
 
+
 int64 write_total(void)
 {
        return total_written;
@@ -78,6 +79,7 @@ static char *read_buffer;
 static char *read_buffer_p;
 static int read_buffer_len;
 static int read_buffer_size;
+static int no_flush;
 
 /* read from a socket with IO timeout. return the number of
    bytes read. If no bytes can be read then exit, never return
@@ -86,6 +88,8 @@ static int read_timeout(int fd, char *buf, int len)
 {
        int n, ret=0;
 
+       io_flush();
+
        while (ret == 0) {
                fd_set fds;
                struct timeval tv;
@@ -117,7 +121,9 @@ static int read_timeout(int fd, char *buf, int len)
                }
 
                if (n == 0) {
-                       rprintf(FERROR,"EOF in read_timeout\n");
+                       if (eof_error) {
+                               rprintf(FERROR,"EOF in read_timeout\n");
+                       }
                        exit_cleanup(1);
                }
 
@@ -140,7 +146,7 @@ static void read_loop(int fd, char *buf, int len)
        }
 }
 
-/* read from the file descriptor handing multiplexing - 
+/* read from the file descriptor handling multiplexing - 
    return number of bytes read
    never return <= 0 */
 static int read_unbuffered(int fd, char *buf, int len)
@@ -218,10 +224,7 @@ static void read_check(int f)
 
        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);
+               read_buffer = (char *)Realloc(read_buffer,read_buffer_size);
                if (!read_buffer) out_of_memory("read check");      
                read_buffer_p = read_buffer;      
        }
@@ -323,6 +326,8 @@ static void writefd_unbuffered(int fd,char *buf,int len)
        struct timeval tv;
        int reading;
 
+       no_flush++;
+
        reading = (buffer_f_in != -1 && read_buffer_len < MAX_READ_BUFFER);
 
        while (total < len) {
@@ -372,6 +377,8 @@ static void writefd_unbuffered(int fd,char *buf,int len)
                        read_check(buffer_f_in);
                }
        }
+
+       no_flush--;
 }
 
 
@@ -393,7 +400,7 @@ void io_start_buffering(int fd)
 void io_flush(void)
 {
        int fd = multiplex_out_fd;
-       if (!io_buffer_count) return;
+       if (!io_buffer_count || no_flush) return;
 
        if (io_multiplexing_out) {
                SIVAL(io_buffer-4, 0, (MPLEX_BASE<<24) + io_buffer_count);
@@ -480,8 +487,12 @@ void write_byte(int f,unsigned char c)
 
 int read_line(int f, char *buf, int maxlen)
 {
+       eof_error = 0;
+
        while (maxlen) {
+               buf[0] = 0;
                read_buf(f, buf, 1);
+               if (buf[0] == 0) return 0;
                if (buf[0] == '\n') {
                        buf[0] = 0;
                        break;
@@ -495,6 +506,9 @@ int read_line(int f, char *buf, int maxlen)
                *buf = 0;
                return 0;
        }
+
+       eof_error = 1;
+
        return 1;
 }