f8cc519b7e740c7467d4fa3cd95ea6d8d4a9a1ab
[rsync-patches.git] / contimeout.diff
1 This patch adds a connection timeout option, --contimeout.
2
3 To use this patch, run these commands for a successful build:
4
5     patch -p1 <patches/contimeout.diff
6     ./configure                                 (optional if already run)
7     make
8
9 --- old/errcode.h
10 +++ new/errcode.h
11 @@ -45,6 +45,7 @@
12  #define RERR_DEL_LIMIT  25      /* skipped some deletes due to --max-delete */
13  
14  #define RERR_TIMEOUT    30      /* timeout in data send/receive */
15 +#define RERR_CONTIMEOUT 35      /* timeout waiting for daemon connection */
16  
17  /* Although it doesn't seem to be specified anywhere,
18   * ssh and the shell seem to return these values:
19 --- old/log.c
20 +++ new/log.c
21 @@ -86,6 +86,7 @@ struct {
22         { RERR_PARTIAL    , "some files could not be transferred" },
23         { RERR_VANISHED   , "some files vanished before they could be transferred" },
24         { RERR_TIMEOUT    , "timeout in data send/receive" },
25 +       { RERR_CONTIMEOUT , "timeout waiting for daemon connection" },
26         { RERR_CMD_FAILED , "remote shell failed" },
27         { RERR_CMD_KILLED , "remote shell killed" },
28         { RERR_CMD_RUN    , "remote command could not be run" },
29 --- old/options.c
30 +++ new/options.c
31 @@ -99,6 +99,7 @@ int xfer_dirs = -1;
32  int am_daemon = 0;
33  int do_stats = 0;
34  int do_progress = 0;
35 +int connect_timeout = 0;
36  int keep_partial = 0;
37  int safe_symlinks = 0;
38  int copy_unsafe_links = 0;
39 @@ -603,6 +604,7 @@ static struct poptOption long_options[] 
40    {"no-numeric-ids",   0,  POPT_ARG_VAL,    &numeric_ids, 0, 0, 0 },
41    {"timeout",          0,  POPT_ARG_INT,    &io_timeout, 0, 0, 0 },
42    {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
43 +  {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
44    {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
45    {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
46    {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
47 --- old/rsync.yo
48 +++ new/rsync.yo
49 @@ -2775,6 +2775,7 @@ dit(bf(23)) Partial transfer due to erro
50  dit(bf(24)) Partial transfer due to vanished source files
51  dit(bf(25)) The --max-delete limit stopped deletions
52  dit(bf(30)) Timeout in data send/receive
53 +dit(bf(35)) Timeout waiting for daemon connection
54  enddit()
55  
56  manpagesection(ENVIRONMENT VARIABLES)
57 --- old/socket.c
58 +++ new/socket.c
59 @@ -32,6 +32,7 @@
60  
61  extern char *bind_address;
62  extern int default_af_hint;
63 +extern int connect_timeout;
64  
65  #ifdef HAVE_SIGACTION
66  static struct sigaction sigact;
67 @@ -157,6 +158,11 @@ int try_bind_local(int s, int ai_family,
68         return -1;
69  }
70  
71 +/* connect() timeout handler based on alarm() */
72 +static RETSIGTYPE contimeout_handler(UNUSED(int val))
73 +{
74 +       connect_timeout = -1;
75 +}
76  
77  /**
78   * Open a socket to a tcp remote host with the specified port .
79 @@ -261,11 +267,27 @@ int open_socket_out(char *host, int port
80                         s = -1;
81                         continue;
82                 }
83 -               if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
84 +               if (connect_timeout > 0) {
85 +                       SIGACTION(SIGALRM, contimeout_handler);
86 +                       alarm(connect_timeout);
87 +               }
88 +
89 +               while (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
90 +                       if (connect_timeout < 0)
91 +                               exit_cleanup(RERR_CONTIMEOUT);
92 +                       if (errno == EINTR)
93 +                               continue;
94                         close(s);
95                         s = -1;
96 -                       continue;
97 +                       break;
98                 }
99 +
100 +               if (connect_timeout > 0)
101 +                       alarm(0);
102 +
103 +               if (s < 0)
104 +                       continue;
105 +
106                 if (proxied
107                  && establish_proxy_connection(s, host, port,
108                                                proxy_user, proxy_pass) != 0) {