Improved the last bugfix description.
[rsync/rsync.git] / io.c
diff --git a/io.c b/io.c
index 1513ae9..e235d3e 100644 (file)
--- a/io.c
+++ b/io.c
@@ -1,8 +1,10 @@
-/* -*- c-file-style: "linux" -*-
+/*
+ * Socket and pipe I/O utilities used in rsync.
  *
- * Copyright (C) 1996-2001 by Andrew Tridgell
- * Copyright (C) Paul Mackerras 1996
- * Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
+ * Copyright (C) 1996-2001 Andrew Tridgell
+ * Copyright (C) 1996 Paul Mackerras
+ * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
+ * Copyright (C) 2003, 2004, 2005, 2006 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-/**
- * @file io.c
- *
- * Socket and pipe I/O utilities used in rsync.
- *
- * rsync provides its own multiplexing system, which is used to send
- * stderr and stdout over a single socket.  We need this because
- * stdout normally carries the binary data stream, and stderr all our
- * error messages.
+/* Rsync provides its own multiplexing system, which is used to send
+ * stderr and stdout over a single socket.
  *
  * For historical reasons this is off during the start of the
  * connection, but it's switched on quite early using
- * io_start_multiplex_out() and io_start_multiplex_in().
- **/
+ * io_start_multiplex_out() and io_start_multiplex_in(). */
 
 #include "rsync.h"
 
@@ -300,6 +294,7 @@ static void read_msg_fd(void)
                        exit_cleanup(RERR_STREAMIO);
                }
                close_multiplexing_out();
+               defer_forwarding_messages = 0;
                /* FALL THROUGH */
        case MSG_INFO:
        case MSG_ERROR:
@@ -309,7 +304,8 @@ static void read_msg_fd(void)
                        if (n >= sizeof buf)
                                n = sizeof buf - 1;
                        read_loop(fd, buf, n);
-                       if (am_generator && am_server && defer_forwarding_messages)
+                       if (am_generator && am_server
+                        && defer_forwarding_messages && tag != MSG_LOG)
                                msg_list_add(&msg2sndr, tag, buf, n);
                        else
                                rwrite((enum logcode)tag, buf, n);
@@ -1001,7 +997,7 @@ void write_sum_head(int f, struct sum_struct *sum)
 static void sleep_for_bwlimit(int bytes_written)
 {
        static struct timeval prior_tv;
-       static long total_written = 0; 
+       static long total_written = 0;
        struct timeval tv, start_tv;
        long elapsed_usec, sleep_usec;
 
@@ -1010,7 +1006,7 @@ static void sleep_for_bwlimit(int bytes_written)
        if (!bwlimit_writemax)
                return;
 
-       total_written += bytes_written; 
+       total_written += bytes_written;
 
        gettimeofday(&start_tv, NULL);
        if (prior_tv.tv_sec) {
@@ -1140,11 +1136,20 @@ static void msg2sndr_flush(void)
 
        while (msg2sndr.head && io_multiplexing_out) {
                struct msg_list_item *m = msg2sndr.head;
+               int tag = (IVAL(m->buf, 0) >> 24) - MPLEX_BASE;
                if (!(msg2sndr.head = m->next))
                        msg2sndr.tail = NULL;
-               stats.total_written += m->len;
                defer_forwarding_messages = 1;
-               writefd_unbuffered(sock_f_out, m->buf, m->len);
+               switch (tag) {
+               case MSG_INFO:
+               case MSG_ERROR:
+                       rwrite((enum logcode)tag, m->buf + 4, m->len - 4);
+                       break;
+               default:
+                       stats.total_written += m->len;
+                       writefd_unbuffered(sock_f_out, m->buf, m->len);
+                       break;
+               }
                defer_forwarding_messages = 0;
                free(m);
        }