use strlcat() strlcpy() and slprintf() whenever possible to avoid any
[rsync/rsync.git] / io.c
diff --git a/io.c b/io.c
index 004f4ce..ccb099a 100644 (file)
--- a/io.c
+++ b/io.c
@@ -148,7 +148,8 @@ static int readfd(int fd,char *buffer,int N)
                        tv.tv_sec = io_timeout;
                        tv.tv_usec = 0;
 
-                       if (select(fd+1, &fds, NULL, NULL, &tv) != 1) {
+                       if (select(fd+1, &fds, NULL, NULL, 
+                                  io_timeout?&tv:NULL) != 1) {
                                check_timeout();
                        }
                }
@@ -300,7 +301,7 @@ int write_file(int f,char *buf,int len)
 }
 
 
-static int writefd(int fd,char *buf,int len)
+static int writefd_unbuffered(int fd,char *buf,int len)
 {
   int total = 0;
   fd_set w_fds, r_fds;
@@ -374,6 +375,58 @@ static int writefd(int fd,char *buf,int len)
   return total;
 }
 
+static char *io_buffer;
+static int io_buffer_count;
+
+void io_start_buffering(int fd)
+{
+       io_buffer = (char *)malloc(IO_BUFFER_SIZE);
+       if (!io_buffer) out_of_memory("writefd");
+       io_buffer_count = 0;
+}
+
+void io_end_buffering(int fd)
+{
+       if (io_buffer_count) {
+               if (writefd_unbuffered(fd, io_buffer, 
+                                      io_buffer_count) != 
+                   io_buffer_count) {
+                       rprintf(FERROR,"write failed\n");
+                       exit_cleanup(1);
+               }
+               io_buffer_count = 0;
+       }
+       free(io_buffer);
+       io_buffer = NULL;
+}
+
+static int writefd(int fd,char *buf,int len1)
+{
+       int len = len1;
+
+       if (!io_buffer) return writefd_unbuffered(fd, buf, len);
+
+       while (len) {
+               int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count);
+               if (n > 0) {
+                       memcpy(io_buffer+io_buffer_count, buf, n);
+                       buf += n;
+                       len -= n;
+                       io_buffer_count += n;
+               }
+               
+               if (io_buffer_count == IO_BUFFER_SIZE) {
+                       if (writefd_unbuffered(fd, io_buffer, 
+                                              io_buffer_count) != 
+                           io_buffer_count) {
+                               return -1;
+                       }
+                       io_buffer_count = 0;
+               }
+       }
+
+       return len1;
+}
 
 
 void write_int(int f,int32 x)
@@ -468,13 +521,7 @@ void io_printf(int fd, const char *format, ...)
        int len;
        
        va_start(ap, format);
-
-#if HAVE_VSNPRINTF
-       len = vsnprintf(buf, sizeof(buf)-1, format, ap);
-#else
-       vsprintf(buf, format, ap);
-       len = strlen(buf);
-#endif
+       len = vslprintf(buf, sizeof(buf)-1, format, ap);
        va_end(ap);
 
        if (len < 0) exit_cleanup(1);