Commit | Line | Data |
---|---|---|
e9d4ab88 WD |
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) { |