minor man page update
[rsync/rsync.git] / util.c
diff --git a/util.c b/util.c
index 03a626e..bd0af33 100644 (file)
--- a/util.c
+++ b/util.c
@@ -28,10 +28,7 @@ extern int verbose;
 
 
 /****************************************************************************
-Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
-else
-if SYSV use O_NDELAY
-if BSD use FNDELAY
+Set a fd into nonblocking mode
 ****************************************************************************/
 void set_nonblocking(int fd)
 {
@@ -45,6 +42,21 @@ void set_nonblocking(int fd)
        }
 }
 
+/****************************************************************************
+Set a fd into blocking mode
+****************************************************************************/
+void set_blocking(int fd)
+{
+       int val;
+
+       if((val = fcntl(fd, F_GETFL, 0)) == -1)
+               return;
+       if (val & NONBLOCK_FLAG) {
+               val &= ~NONBLOCK_FLAG;
+               fcntl(fd, F_SETFL, val);
+       }
+}
+
 
 /* create a file descriptor pair - like pipe() but use socketpair if
    possible (because of blocking issues on pipes)
@@ -70,12 +82,22 @@ int fd_pair(int fd[2])
 }
 
 
-/* this is taken from CVS */
+/* this is derived from CVS code 
+
+   note that in the child STDIN is set to blocking and STDOUT
+   is set to non-blocking. This is necessary as rsh relies on stdin being blocking
+   and ssh relies on stdout being non-blocking
+
+   if blocking_io is set then use blocking io on both fds. That can be
+   used to cope with badly broken rsh implementations like the one on
+   solaris.
+ */
 int piped_child(char **command,int *f_in,int *f_out)
 {
   int pid;
   int to_child_pipe[2];
   int from_child_pipe[2];
+  extern int blocking_io;
 
   if (fd_pair(to_child_pipe) < 0 ||
       fd_pair(from_child_pipe) < 0) {
@@ -103,6 +125,10 @@ int piped_child(char **command,int *f_in,int *f_out)
       if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
       if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
       umask(orig_umask);
+      set_blocking(STDIN_FILENO);
+      if (blocking_io) {
+       set_blocking(STDOUT_FILENO);
+      }
       execvp(command[0], command);
       rprintf(FERROR,"Failed to exec %s : %s\n",
              command[0],strerror(errno));
@@ -904,14 +930,58 @@ char *timestring(time_t t)
 }
 
 
-/****************************************************************************
- like waitpid but does the WEXITSTATUS
-****************************************************************************/
-#ifndef WEXITSTATUS
-#define        WEXITSTATUS(stat)       ((int)(((stat)>>8)&0xFF))
-#endif
-void wait_process(pid_t pid, int *status)
+/*******************************************************************
+sleep for a specified number of milliseconds
+********************************************************************/
+void msleep(int t)
 {
-       waitpid(pid, status, 0);
-       *status = WEXITSTATUS(*status);
+       int tdiff=0;
+       struct timeval tval,t1,t2;  
+
+       gettimeofday(&t1, NULL);
+       gettimeofday(&t2, NULL);
+  
+       while (tdiff < t) {
+               tval.tv_sec = (t-tdiff)/1000;
+               tval.tv_usec = 1000*((t-tdiff)%1000);
+               errno = 0;
+               select(0,NULL,NULL, NULL, &tval);
+
+               gettimeofday(&t2, NULL);
+               tdiff = (t2.tv_sec - t1.tv_sec)*1000 + 
+                       (t2.tv_usec - t1.tv_usec)/1000;
+       }
+}
+
+
+#ifdef __INSURE__
+#include <dlfcn.h>
+
+/*******************************************************************
+This routine is a trick to immediately catch errors when debugging
+with insure. A xterm with a gdb is popped up when insure catches
+a error. It is Linux specific.
+********************************************************************/
+int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
+{
+       static int (*fn)();
+       int ret;
+       char cmd[1024];
+
+       sprintf(cmd, "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'", 
+               getpid(), getpid(), getpid());
+
+       if (!fn) {
+               static void *h;
+               h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
+               fn = dlsym(h, "_Insure_trap_error");
+       }
+
+       ret = fn(a1, a2, a3, a4, a5, a6);
+
+       system(cmd);
+
+       return ret;
 }
+#endif