fixed a select bug which caused rsync to use far more cpu time than
[rsync/rsync.git] / io.c
diff --git a/io.c b/io.c
index 0021d95..52c4cb1 100644 (file)
--- a/io.c
+++ b/io.c
@@ -113,7 +113,7 @@ static void check_timeout(void)
        t = time(NULL);
 
        if (last_io && io_timeout && (t-last_io)>io_timeout) {
-               fprintf(FERROR,"read timeout after %d second - exiting\n", 
+               rprintf(FERROR,"read timeout after %d second - exiting\n", 
                        (int)(t-last_io));
                exit_cleanup(1);
        }
@@ -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();
                        }
                }
@@ -164,13 +165,13 @@ static int readfd(int fd,char *buffer,int N)
 }
 
 
-int read_int(int f)
+int32 read_int(int f)
 {
   int ret;
   char b[4];
   if ((ret=readfd(f,b,4)) != 4) {
     if (verbose > 1) 
-      fprintf(FERROR,"(%d) Error reading %d bytes : %s\n",
+      rprintf(FERROR,"(%d) Error reading %d bytes : %s\n",
              getpid(),4,ret==-1?strerror(errno):"EOF");
     exit_cleanup(1);
   }
@@ -185,16 +186,16 @@ int64 read_longint(int f)
        char b[8];
        ret = read_int(f);
 
-       if (ret != -1) return ret;
+       if ((int32)ret != (int32)0xffffffff) return ret;
 
 #ifdef NO_INT64
-       fprintf(FERROR,"Integer overflow - attempted 64 bit offset\n");
+       rprintf(FERROR,"Integer overflow - attempted 64 bit offset\n");
        exit_cleanup(1);
 #else
        if (remote_version >= 16) {
                if ((ret=readfd(f,b,8)) != 8) {
                        if (verbose > 1) 
-                               fprintf(FERROR,"(%d) Error reading %d bytes : %s\n",
+                               rprintf(FERROR,"(%d) Error reading %d bytes : %s\n",
                                        getpid(),8,ret==-1?strerror(errno):"EOF");
                        exit_cleanup(1);
                }
@@ -211,7 +212,7 @@ void read_buf(int f,char *buf,int len)
   int ret;
   if ((ret=readfd(f,buf,len)) != len) {
     if (verbose > 1) 
-      fprintf(FERROR,"(%d) Error reading %d bytes : %s\n",
+      rprintf(FERROR,"(%d) Error reading %d bytes : %s\n",
              getpid(),len,ret==-1?strerror(errno):"EOF");
     exit_cleanup(1);
   }
@@ -238,7 +239,7 @@ static int last_sparse;
 int sparse_end(int f)
 {
        if (last_sparse) {
-               lseek(f,-1,SEEK_CUR);
+               do_lseek(f,-1,SEEK_CUR);
                return (write(f,&last_byte,1) == 1 ? 0 : -1);
        }
        last_sparse = 0;
@@ -260,7 +261,7 @@ static int write_sparse(int f,char *buf,int len)
                last_sparse=1;
 
        if (l1 > 0)
-               lseek(f,l1,SEEK_CUR);  
+               do_lseek(f,l1,SEEK_CUR);  
 
        if (l1 == len) 
                return len;
@@ -271,7 +272,7 @@ static int write_sparse(int f,char *buf,int len)
        }
 
        if (l2 > 0)
-               lseek(f,l2,SEEK_CUR);
+               do_lseek(f,l2,SEEK_CUR);
        
        return len;
 }
@@ -324,7 +325,7 @@ static int writefd(int fd,char *buf,int len)
               systems it seems (eg. IRIX) */
            u_sleep(1000);
 #if 0
-           fprintf(FERROR,"write exception\n");
+           rprintf(FERROR,"write exception\n");
            exit_cleanup(1);
 #endif
     }
@@ -351,7 +352,7 @@ static int writefd(int fd,char *buf,int len)
                     &w_fds,NULL,&tv);
       if (count == -1 && errno != EINTR) {
              if (verbose > 1) 
-                     fprintf(FERROR,"select error: %s\n", strerror(errno));
+                     rprintf(FERROR,"select error: %s\n", strerror(errno));
              exit_cleanup(1);
       }
 
@@ -376,13 +377,13 @@ static int writefd(int fd,char *buf,int len)
 
 
 
-void write_int(int f,int x)
+void write_int(int f,int32 x)
 {
   int ret;
   char b[4];
   SIVAL(b,0,x);
   if ((ret=writefd(f,b,4)) != 4) {
-    fprintf(FERROR,"write_int failed : %s\n",
+    rprintf(FERROR,"write_int failed : %s\n",
            ret==-1?strerror(errno):"EOF");
     exit_cleanup(1);
   }
@@ -405,7 +406,7 @@ void write_longint(int f, int64 x)
        SIVAL(b,4,((x>>32)&0xFFFFFFFF));
 
        if ((ret=writefd(f,b,8)) != 8) {
-               fprintf(FERROR,"write_longint failed : %s\n",
+               rprintf(FERROR,"write_longint failed : %s\n",
                        ret==-1?strerror(errno):"EOF");
                exit_cleanup(1);
        }
@@ -416,17 +417,23 @@ void write_buf(int f,char *buf,int len)
 {
   int ret;
   if ((ret=writefd(f,buf,len)) != len) {
-    fprintf(FERROR,"write_buf failed : %s\n",
+    rprintf(FERROR,"write_buf failed : %s\n",
            ret==-1?strerror(errno):"EOF");
     exit_cleanup(1);
   }
   total_written += len;
 }
 
+/* write a string to the connection */
+void write_sbuf(int f,char *buf)
+{
+       write_buf(f, buf, strlen(buf));
+}
+
 
 void write_byte(int f,unsigned char c)
 {
-  write_buf(f,(char *)&c,1);
+       write_buf(f,(char *)&c,1);
 }
 
 void write_flush(int f)
@@ -434,3 +441,44 @@ void write_flush(int f)
 }
 
 
+int read_line(int f, char *buf, int maxlen)
+{
+       while (maxlen) {
+               read_buf(f, buf, 1);
+               if (buf[0] == '\n') {
+                       buf[0] = 0;
+                       break;
+               }
+               if (buf[0] != '\r') {
+                       buf++;
+                       maxlen--;
+               }
+       }
+       if (maxlen == 0) {
+               *buf = 0;
+               return 0;
+       }
+       return 1;
+}
+
+
+void io_printf(int fd, const char *format, ...)
+{
+       va_list ap;  
+       char buf[1024];
+       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
+       va_end(ap);
+
+       if (len < 0) exit_cleanup(1);
+
+       write_sbuf(fd, buf);
+}