[leafnode-list] PATCH: fix bogus fetchnews abort on server timeout (was: How can i suppress this message (Alarm clock)?)

Matthias Andree ma at dt.e-technik.uni-dortmund.de
Wed Sep 15 12:48:53 CEST 2004


Michael Rulov <miha_root at aport2000.ru> writes:

> 16:25 home/$ fetchnews
> Alarm clock
> 16:28 home/$ fetchnews >/dev/null 2>@1
> Alarm clock

OK, the redirection would have had to be 2>&1 (& rather than @), and the
message isn't suppressed because it is generated by your shell.

At any rate, the latest leafnode snapshot has a bug in timeout handling
in that it doesn't catch the signal it has requested. This patch fixes
the problem for me (Michael, if you now choose to remove the timeout =
90 line, fetchnews should complain that the connection to the server
timed out, or it should get the connection).

Index: nntputil.c
===================================================================
RCS file: /var/CVS/leafnode-2/nntputil.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- nntputil.c	23 Aug 2004 09:49:35 -0000	1.27
+++ nntputil.c	15 Sep 2004 10:44:16 -0000	1.28
@@ -173,17 +173,25 @@
     return newnntpreply(s, 0);
 }
 
+static int caught_alrm;
+static RETSIGTYPE catch_alrm(int sig) {
+    (void)sig;
+    caught_alrm = 1;
+}
+
 /** Create a socket and connect it to a remote address.
  * \returns -1 for trouble, socket descriptor if successful. 
  */
 static int
 any_connect(const int family, const int socktype, const int protocol,
 	    const struct sockaddr *sa, socklen_t addrlen,
-	    /*@exposed@*/ const char ** const errcause)
+	    /*@exposed@*/ const char ** const errcause,
+	    unsigned int timeout)
 /*@modifies errcause@*/
 {
     char *as;
     int sock;
+    struct sigaction sact;
 
     as = masock_sa2addr(sa);
     ln_log(LNLOG_SINFO, LNLOG_CSERVER,
@@ -195,9 +203,25 @@
 	ln_log(LNLOG_SINFO, LNLOG_CSERVER, "  cannot create socket: %m");
 	*errcause = "cannot create socket";
     } else {
-	if (connect(sock, sa, addrlen) < 0) {
-	    int e = errno;
-	    ln_log(LNLOG_SINFO, LNLOG_CSERVER, "  cannot connect: %m");
+	int r, e;
+	sact.sa_handler = catch_alrm;
+	sact.sa_flags = SA_NOCLDSTOP;
+	sigemptyset(&sact.sa_mask);
+	(void)sigaction(SIGALRM, &sact, NULL);
+	caught_alrm = 0;
+	alarm(timeout);
+	r = connect(sock, sa, addrlen);
+	e = errno;
+	alarm(0);
+	sact.sa_handler = SIG_DFL;
+	sact.sa_flags = 0;
+	(void)sigaction(SIGALRM, &sact, NULL);
+	errno = e;
+	if (r < 0) {
+	    if (errno == EINTR && caught_alrm)
+		ln_log(LNLOG_SINFO, LNLOG_CSERVER, "  cannot connect: timeout");
+	    else
+		ln_log(LNLOG_SINFO, LNLOG_CSERVER, "  cannot connect: %m");
 	    (void)close(sock);
 	    *errcause = "cannot connect";
 	    errno = e;
@@ -225,7 +249,9 @@
     /** service name or port number */
     const char *const service,
     /** address family, 0 means "don't care" */
-    int address_family)
+    int address_family,
+    /** timeout in seconds */
+    unsigned int timeout)
 {
     const char *errcause;
     int sock;
@@ -254,7 +280,7 @@
     errno = 0;
     for (aii = ai; aii != NULL; aii = aii->ai_next) {
 	sock = any_connect(aii->ai_family, aii->ai_socktype, aii->ai_protocol,
-			   aii->ai_addr, aii->ai_addrlen, &errcause);
+			   aii->ai_addr, aii->ai_addrlen, &errcause, timeout);
 	if (sock >= 0)
 	    break;
     }
@@ -317,7 +343,7 @@
 	memcpy(&s_in.sin_addr, *ha, he->h_length);
 	sock = any_connect(AF_INET, SOCK_STREAM, IPPROTO_TCP,
 			   (struct sockaddr *)&s_in, sizeof(s_in),
-			   &errcause);
+			   &errcause, timeout);
 	if (sock >= 0)
 	    break;
     }
@@ -343,7 +369,7 @@
 int
 nntpconnect(const struct serverlist *upstream)
 {
-    int sock, reply, infd, e;
+    int sock, reply, infd;
     socklen_t optlen = sizeof(sendbuf);
     char *line;
     char service[20];
@@ -356,11 +382,7 @@
 
     ln_log(LNLOG_SINFO, LNLOG_CSERVER, "%s: connecting to port %s",
 	   upstream->name, service);
-    alarm(upstream->timeout);
-    sock = tcp_connect(upstream->name, service, PF_UNSPEC);
-    e = errno;
-    alarm(0);
-    errno = e;
+    sock = tcp_connect(upstream->name, service, PF_UNSPEC, upstream->timeout);
     if (sock < 0)
 	return 0;
 
-- 
Matthias Andree

Encrypted mail welcome: my GnuPG key ID is 0x052E7D95 (PGP/MIME preferred)



More information about the leafnode-list mailing list