Fix spurious logging of select error
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 3 Nov 2020 13:14:11 +0000 (13:14 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 3 Nov 2020 13:14:11 +0000 (13:14 +0000)
doc/doc-txt/ChangeLog
src/src/daemon.c

index e61ad62264b8dfeaa6326aeacd405911319567b8..d56454ccc1a1cb9b5564b52545a967622db9f71a 100644 (file)
@@ -134,6 +134,12 @@ JH/27 Bug 2648: fix the passing of an authenticator public-name through spool
       files.  The value is used by the authresults expansion item.  Previously
       if this was used in a router or transport, a crash could result.
 
+JH/28 Fix spurious logging of select error.  Some platforms, notably FreeBSD,
+      have a sufficient incidence of EINTR returns from select that an
+      interaction with other operations done by the main daemon loop exposed
+      a bug in the error-handling.  This was benign apart from the log
+      messages.
+
 
 Exim version 4.94
 -----------------
index 78a4d8ec2ba137fc3d24188ca224a555e8b3d8b3..83131fa1d94330eb439e779cd63bdbf3d16f5d5c 100644 (file)
@@ -2278,7 +2278,7 @@ for (;;)
 
   if (f.daemon_listen)
     {
-    int lcount, select_errno;
+    int lcount;
     int max_socket = 0;
     BOOL select_failed = FALSE;
     fd_set select_listen;
@@ -2333,14 +2333,16 @@ for (;;)
     old one had just finished. Preserve the errno from any select() failure for
     the use of the common select/accept error processing below. */
 
-    select_errno = errno;
-    handle_ending_processes();
-    errno = select_errno;
+      {
+      int select_errno = errno;
+      handle_ending_processes();
 
 #ifndef DISABLE_TLS
-    /* Create or rotate any required keys; handle (delayed) filewatch event */
-    tls_daemon_tick();
+      /* Create or rotate any required keys; handle (delayed) filewatch event */
+      tls_daemon_tick();
 #endif
+      errno = select_errno;
+      }
 
     /* Loop for all the sockets that are currently ready to go. If select
     actually failed, we have set the count to 1 and select_failed=TRUE, so as
@@ -2396,40 +2398,33 @@ for (;;)
           accept_retry_errno = errno;
           accept_retry_select_failed = select_failed;
           }
-        else
-          {
-          if (errno != accept_retry_errno ||
-              select_failed != accept_retry_select_failed ||
-              accept_retry_count >= 50)
+        else if (  errno != accept_retry_errno 
+               || select_failed != accept_retry_select_failed
+               || accept_retry_count >= 50)
             {
-            log_write(0, LOG_MAIN | ((accept_retry_count >= 50)? LOG_PANIC : 0),
+            log_write(0, LOG_MAIN | (accept_retry_count >= 50 ? LOG_PANIC : 0),
               "%d %s() failure%s: %s",
               accept_retry_count,
-              accept_retry_select_failed? "select" : "accept",
-              (accept_retry_count == 1)? "" : "s",
+              accept_retry_select_failed ? "select" : "accept",
+              accept_retry_count == 1 ? "" : "s",
               strerror(accept_retry_errno));
             log_close_all();
             accept_retry_count = 0;
             accept_retry_errno = errno;
             accept_retry_select_failed = select_failed;
             }
-          }
         accept_retry_count++;
         }
-
-      else
-        {
-        if (accept_retry_count > 0)
-          {
-          log_write(0, LOG_MAIN, "%d %s() failure%s: %s",
-            accept_retry_count,
-            accept_retry_select_failed? "select" : "accept",
-            (accept_retry_count == 1)? "" : "s",
-            strerror(accept_retry_errno));
-          log_close_all();
-          accept_retry_count = 0;
-          }
-        }
+      else if (accept_retry_count > 0)
+       {
+       log_write(0, LOG_MAIN, "%d %s() failure%s: %s",
+         accept_retry_count,
+         accept_retry_select_failed ? "select" : "accept",
+         accept_retry_count == 1 ? "" : "s",
+         strerror(accept_retry_errno));
+       log_close_all();
+       accept_retry_count = 0;
+       }
 
       /* If select/accept succeeded, deal with the connection. */