followup: stuck lmtpd processes

Etienne Goyer etienne.goyer at linuxquebec.com
Wed Sep 24 12:11:44 EDT 2003


On Wed, Sep 24, 2003 at 11:27:46AM -0400, Rob Siemborski wrote:
> However, I have looked into this and to my surprise, Linux is indeed
> restarting the system calls instead of returning with EINTR.  However, the
> answer here is to set up the alarm() handler with sigaction without
> setting SA_RESTART, not to jump through select() hoops or make nonblocking
> lock attempts.

I consult my local Unix guru on the subject, and he point me to
"Advanced Programming in the Unix Environment" by W. Richard Stevens,
section 10.5 (page 275 in my edition) "Interrupted System Calls".
The revelancy of this text may be questionned since it was published in
1992, but the behavior of SVR4 vs BSD differ substantially in this
regard according to it.  My guru concluded that system call interuption 
by signal is an assumption that may lead to portability problem.  In the
fud case, he is right.
 
> I'll work on fixing fud shortly (its using signal() and it should be
> using sigaction()).

The included patch against 2.1.13 work for me.

-- 
Etienne Goyer                    Linux Québec Technologies Inc.
http://www.LinuxQuebec.com       etienne.goyer at linuxquebec.com
-------------- next part --------------
--- fud.c.orig	Wed Jun  4 14:19:43 2003
+++ fud.c	Wed Jun  4 15:28:54 2003
@@ -53,6 +53,7 @@
 #include <syslog.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/time.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <netinet/in.h>
@@ -62,6 +63,7 @@
 #include <errno.h>
 #include <com_err.h>
 #include <pwd.h>
+#include <sys/select.h>
 
 #include "assert.h"
 #include "mboxlist.h"
@@ -196,12 +198,6 @@
     shut_down(r);
 }
 
-static void cyrus_timeout(int signo)
-{
-  signo = 0;
-  return;
-}
-
 /* Send a proxy request to the backend, send their reply to sfrom */
 int do_proxy_request(const char *who, const char *name,
 		     const char *backend_host,
@@ -210,8 +206,10 @@
     char tmpbuf[1024];
     int x, rc;
     int csoc = -1;
+    fd_set ssock;
     struct sockaddr_in cin, cout;
     struct hostent *hp;
+    struct timeval tv;
     static int backend_port = 0; /* fud port in NETWORK BYTE ORDER */
 
     /* Open a UDP socket to the Cyrus mail server */
@@ -240,14 +238,24 @@
     /* Send the query and wait for a reply */
     sendto (csoc, tmpbuf, strlen (tmpbuf), 0, (struct sockaddr *) &cin, x);
     memset (tmpbuf, '\0', strlen (tmpbuf));
-    signal (SIGALRM, cyrus_timeout);
     rc = 0;
-    alarm (1);
-    rc = recvfrom (csoc, tmpbuf, sizeof(tmpbuf), 0,
-		   (struct sockaddr *) &cout, &x);
-    alarm (0);
-    if (rc < 1) {
-	rc = IMAP_SERVER_UNAVAILABLE;
+    FD_ZERO(&ssock);
+    FD_SET(csoc, &ssock);
+    tv.tv_sec = 5;
+    tv.tv_usec = 0;
+    rc = select(csoc + 1, &ssock, NULL, NULL, &tv);
+    if (rc > 0) {
+        syslog(LOG_ERR, "Reading sock");
+	rc = recvfrom (csoc, tmpbuf, sizeof(tmpbuf), 0,
+    		   (struct sockaddr *) &cout, &x);
+        if (rc < 1) {
+	    rc = IMAP_SERVER_UNAVAILABLE;
+            send_reply(sfrom, REQ_UNK, who, name, 0, 0, 0);
+            goto done;
+        }
+    } else {
+	syslog(LOG_ERR, "FUD timeout");
+        rc = IMAP_SERVER_UNAVAILABLE;
 	send_reply(sfrom, REQ_UNK, who, name, 0, 0, 0);
 	goto done;
     }


More information about the Info-cyrus mailing list