From ba22c9e219ccd45fea318e7759a7fe4a7c3703dc Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Wed, 28 Nov 2007 00:28:26 -0800 Subject: [PATCH] Adding --contimeout=SECONDS option. --- errcode.h | 1 + log.c | 1 + main.c | 7 +++++++ options.c | 5 ++++- rsync.yo | 8 +++++++- socket.c | 26 ++++++++++++++++++++++++-- 6 files changed, 44 insertions(+), 4 deletions(-) diff --git a/errcode.h b/errcode.h index c5259d41..f9e63578 100644 --- a/errcode.h +++ b/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: diff --git a/log.c b/log.c index fc4b5833..146c082b 100644 --- a/log.c +++ b/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" }, diff --git a/main.c b/main.c index 4c040b99..8ca164bd 100644 --- a/main.c +++ b/main.c @@ -63,6 +63,7 @@ extern int read_batch; extern int write_batch; extern int batch_fd; extern int filesfrom_fd; +extern int connect_timeout; extern pid_t cleanup_child_pid; extern struct stats stats; extern char *filesfrom_host; @@ -1264,6 +1265,12 @@ static int start_client(int argc, char *argv[]) exit_cleanup(RERR_SYNTAX); } + if (connect_timeout) { + rprintf(FERROR, "The --contimeout option may only be " + "used when connecting to an rsync daemon.\n"); + exit_cleanup(RERR_SYNTAX); + } + if (shell_machine) { p = strrchr(shell_machine,'@'); if (p) { diff --git a/options.c b/options.c index 783ca594..a3ea1c6a 100644 --- a/options.c +++ b/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; @@ -377,7 +378,8 @@ void usage(enum logcode F) rprintf(F," --delay-updates put all updated files into place at transfer's end\n"); rprintf(F," -m, --prune-empty-dirs prune empty directory chains from the file-list\n"); rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n"); - rprintf(F," --timeout=TIME set I/O timeout in seconds\n"); + rprintf(F," --timeout=SECONDS set I/O timeout in seconds\n"); + rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n"); rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n"); rprintf(F," --size-only skip files that match in size\n"); rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n"); @@ -603,6 +605,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 }, diff --git a/rsync.yo b/rsync.yo index ec8654f9..87652d41 100644 --- a/rsync.yo +++ b/rsync.yo @@ -378,7 +378,8 @@ to the detailed description below for a complete description. verb( --delay-updates put all updated files into place at end -m, --prune-empty-dirs prune empty directory chains from file-list --numeric-ids don't map uid/gid values by user/group name - --timeout=TIME set I/O timeout in seconds + --timeout=SECONDS set I/O timeout in seconds + --contimeout=SECONDS set daemon connection timeout in seconds -I, --ignore-times don't skip files that match size and time --size-only skip files that match in size --modify-window=NUM compare mod-times with reduced accuracy @@ -1582,6 +1583,10 @@ dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum I/O timeout in seconds. If no data is transferred for the specified time then rsync will exit. The default is 0, which means no timeout. +dit(bf(--contimeout)) This option allows you to set the amount of time +that rsync will wait for its connection to an rsync daemon to succeed. +If the timeout is reached, rsync exits with an error. + dit(bf(--address)) By default rsync will bind to the wildcard address when connecting to an rsync daemon. The bf(--address) option allows you to specify a specific IP address (or hostname) to bind to. See also this @@ -2775,6 +2780,7 @@ dit(bf(23)) Partial transfer due to error 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) diff --git a/socket.c b/socket.c index 6bedc991..89f285a2 100644 --- a/socket.c +++ b/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, int ai_socktype, 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, const char *bind_addr, 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) { -- 2.34.1