From: Thomas Roessler Date: Wed, 4 Oct 2000 08:50:53 +0000 (+0000) Subject: patch.me.connect_timeout.1 X-Git-Tag: mutt-1-3-10-rel~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc3d0e280048a2d283ca2491e93f1a5c5e5a8fa6;p=mutt patch.me.connect_timeout.1 --- diff --git a/globals.h b/globals.h index 871e59ff..543e685f 100644 --- a/globals.h +++ b/globals.h @@ -125,6 +125,7 @@ extern unsigned char QuadOptions[]; WHERE unsigned short Counter INITVAL (0); +WHERE short ConnectTimeout; WHERE short HistSize; WHERE short PagerContext; WHERE short PagerIndexLines; diff --git a/init.h b/init.h index 20ba1101..e7ee8cf8 100644 --- a/init.h +++ b/init.h @@ -319,6 +319,13 @@ struct option_t MuttVars[] = { ** When set, Mutt will prompt for confirmation when saving messages to a ** mailbox which does not yet exist before creating it. */ + { "connect_timeout", DT_NUM, R_NONE, UL &ConnectTimeout, 30 }, + /* + ** .pp + ** Causes Mutt to timeout a network connection (for IMAP or POP) after this + ** many seconds if the connection is not able to be established. A negative + ** value causes Mutt to wait indefinitely for the connection to succeed. + */ { "copy", DT_QUAD, R_NONE, OPT_COPY, M_YES }, /* ** .pp diff --git a/mutt_socket.c b/mutt_socket.c index c56d0700..d513081e 100644 --- a/mutt_socket.c +++ b/mutt_socket.c @@ -219,6 +219,8 @@ static int socket_connect (int fd, struct sockaddr* sa) { int sa_size; int rc; + int save_errno; + /* old first_try_without_preconnect removed for now. unset $preconnect first. */ @@ -229,10 +231,11 @@ static int socket_connect (int fd, struct sockaddr* sa) dprint (1, (debugfile, "Preconnect result: %d\n", rc)); if (rc) { - mutt_perror (_("Preconnect command failed.")); - sleep (1); + save_errno = errno; + mutt_perror (_("Preconnect command failed.")); + sleep (1); - return -1; + return save_errno; } } @@ -246,14 +249,25 @@ static int socket_connect (int fd, struct sockaddr* sa) return -1; } + if (ConnectTimeout > 0) + alarm (ConnectTimeout); + + mutt_allow_interrupt (1); + + save_errno = 0; + if (connect (fd, sa, sa_size) < 0) { - dprint (2, (debugfile, "Connection failed. errno: %d...\n", errno)); - - return errno; + save_errno = errno; + dprint (2, (debugfile, "Connection failed. errno: %d...\n", errno)); + SigInt = 0; /* reset in case we caugh SIGINTR while in connect() */ } - - return 0; + + if (ConnectTimeout > 0) + alarm (0); + mutt_allow_interrupt (0); + + return save_errno; } /* socket_new_conn: allocate and initialise a new connection. */ @@ -322,10 +336,9 @@ int raw_socket_open (CONNECTION* conn) fd = socket (cur->ai_family, cur->ai_socktype, cur->ai_protocol); if (fd >= 0) { - if (socket_connect (fd, res->ai_addr) == 0) + if ((rc = socket_connect (fd, res->ai_addr)) == 0) { conn->fd = fd; - rc = 0; break; } else @@ -365,10 +378,9 @@ int raw_socket_open (CONNECTION* conn) if (fd > 0) { - if (socket_connect (fd, (struct sockaddr*) &sin) == 0) + if ((rc = socket_connect (fd, (struct sockaddr*) &sin) == 0)) { conn->fd = fd; - rc = 0; break; } else @@ -380,10 +392,7 @@ int raw_socket_open (CONNECTION* conn) if (rc) { mutt_error (_("Could not connect to %s (%s)."), conn->account.host, - rc == ETIMEDOUT ? "timed out" : - rc == ECONNREFUSED ? "connection refused" : - rc == ENETUNREACH ? "host unreachable" : - "unknown error"); + (rc > 0) ? strerror (rc) : _("unknown error")); sleep (2); } diff --git a/protos.h b/protos.h index e582aa4c..a517de35 100644 --- a/protos.h +++ b/protos.h @@ -137,6 +137,7 @@ const char *mutt_fqdn(short); void mutt_adv_mktemp (char *, size_t); void mutt_alias_menu (char *, size_t, ALIAS *); +void mutt_allow_interrupt (int); void mutt_block_signals (void); void mutt_block_signals_system (void); void mutt_body_handler (BODY *, STATE *); diff --git a/signal.c b/signal.c index 68f1f3ca..85b5ada9 100644 --- a/signal.c +++ b/signal.c @@ -111,12 +111,19 @@ void mutt_signal_init (void) /* we want to avoid race conditions */ sigaddset (&act.sa_mask, SIGTSTP); + act.sa_handler = sighandler; + + /* we want SIGALRM to abort the current syscall, so we do this before + * setting the SA_RESTART flag below. currently this is only used to + * timeout on a connect() call in a reasonable amout of time. + */ + sigaction (SIGALRM, &act, NULL); + /* we also don't want to mess with interrupted system calls */ #ifdef SA_RESTART act.sa_flags = SA_RESTART; #endif - act.sa_handler = sighandler; sigaction (SIGCONT, &act, NULL); sigaction (SIGTSTP, &act, NULL); sigaction (SIGINT, &act, NULL); @@ -218,3 +225,16 @@ void mutt_unblock_signals_system (int catch) unset_option (OPTSYSSIGNALSBLOCKED); } } + +void mutt_allow_interrupt (int disposition) +{ + struct sigaction sa; + + memset (&sa, 0, sizeof sa); + sa.sa_handler = sighandler; +#ifdef SA_RESTART + if (disposition == 0) + sa.sa_flags |= SA_RESTART; +#endif + sigaction (SIGINT, &sa, NULL); +}