My improved version of a connection-timeout patch.
authorWayne Davison <wayned@samba.org>
Sun, 11 Nov 2007 15:03:24 +0000 (15:03 +0000)
committerWayne Davison <wayned@samba.org>
Sun, 11 Nov 2007 15:03:24 +0000 (15:03 +0000)
contimeout.diff [new file with mode: 0644]

diff --git a/contimeout.diff b/contimeout.diff
new file mode 100644 (file)
index 0000000..f8cc519
--- /dev/null
@@ -0,0 +1,108 @@
+This patch adds a connection timeout option, --contimeout.
+
+To use this patch, run these commands for a successful build:
+
+    patch -p1 <patches/contimeout.diff
+    ./configure                                 (optional if already run)
+    make
+
+--- old/errcode.h
++++ new/errcode.h
+@@ -45,6 +45,7 @@
+ #define RERR_DEL_LIMIT  25      /* skipped some deletes due to --max-delete */
+ #define RERR_TIMEOUT    30      /* timeout in data send/receive */
++#define RERR_CONTIMEOUT 35      /* timeout waiting for daemon connection */
+ /* Although it doesn't seem to be specified anywhere,
+  * ssh and the shell seem to return these values:
+--- old/log.c
++++ new/log.c
+@@ -86,6 +86,7 @@ struct {
+       { RERR_PARTIAL    , "some files could not be transferred" },
+       { RERR_VANISHED   , "some files vanished before they could be transferred" },
+       { RERR_TIMEOUT    , "timeout in data send/receive" },
++      { RERR_CONTIMEOUT , "timeout waiting for daemon connection" },
+       { RERR_CMD_FAILED , "remote shell failed" },
+       { RERR_CMD_KILLED , "remote shell killed" },
+       { RERR_CMD_RUN    , "remote command could not be run" },
+--- old/options.c
++++ new/options.c
+@@ -99,6 +99,7 @@ int xfer_dirs = -1;
+ int am_daemon = 0;
+ int do_stats = 0;
+ int do_progress = 0;
++int connect_timeout = 0;
+ int keep_partial = 0;
+ int safe_symlinks = 0;
+ int copy_unsafe_links = 0;
+@@ -603,6 +604,7 @@ static struct poptOption long_options[] 
+   {"no-numeric-ids",   0,  POPT_ARG_VAL,    &numeric_ids, 0, 0, 0 },
+   {"timeout",          0,  POPT_ARG_INT,    &io_timeout, 0, 0, 0 },
+   {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
++  {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
+   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
+   {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
+   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
+--- old/rsync.yo
++++ new/rsync.yo
+@@ -2775,6 +2775,7 @@ dit(bf(23)) Partial transfer due to erro
+ dit(bf(24)) Partial transfer due to vanished source files
+ dit(bf(25)) The --max-delete limit stopped deletions
+ dit(bf(30)) Timeout in data send/receive
++dit(bf(35)) Timeout waiting for daemon connection
+ enddit()
+ manpagesection(ENVIRONMENT VARIABLES)
+--- old/socket.c
++++ new/socket.c
+@@ -32,6 +32,7 @@
+ extern char *bind_address;
+ extern int default_af_hint;
++extern int connect_timeout;
+ #ifdef HAVE_SIGACTION
+ static struct sigaction sigact;
+@@ -157,6 +158,11 @@ int try_bind_local(int s, int ai_family,
+       return -1;
+ }
++/* connect() timeout handler based on alarm() */
++static RETSIGTYPE contimeout_handler(UNUSED(int val))
++{
++      connect_timeout = -1;
++}
+ /**
+  * Open a socket to a tcp remote host with the specified port .
+@@ -261,11 +267,27 @@ int open_socket_out(char *host, int port
+                       s = -1;
+                       continue;
+               }
+-              if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
++              if (connect_timeout > 0) {
++                      SIGACTION(SIGALRM, contimeout_handler);
++                      alarm(connect_timeout);
++              }
++
++              while (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
++                      if (connect_timeout < 0)
++                              exit_cleanup(RERR_CONTIMEOUT);
++                      if (errno == EINTR)
++                              continue;
+                       close(s);
+                       s = -1;
+-                      continue;
++                      break;
+               }
++
++              if (connect_timeout > 0)
++                      alarm(0);
++
++              if (s < 0)
++                      continue;
++
+               if (proxied
+                && establish_proxy_connection(s, host, port,
+                                              proxy_user, proxy_pass) != 0) {