Add shutdown flags and install signal handlers at lib init if there are not already...
robs [Thu, 6 Sep 2001 13:06:11 +0000 (13:06 +0000)]
include/fcgios.h
libfcgi/os_unix.c

index 02e033c..a8b3ed6 100755 (executable)
@@ -117,6 +117,22 @@ DLLAPI int OS_IpcClose(int ipcFd);
 DLLAPI int OS_IsFcgi(int sock);
 DLLAPI void OS_SetFlags(int fd, int flags);
 
+#ifdef WIN32
+#define OS_ShutdownNow
+#define OS_ShutdownPending
+#define OS_SigtermHandler
+#define OS_Sigusr1Handler
+#define OS_SigpipeHandler
+#define OS_InstallSignalHandlers
+#else
+void OS_ShutdownNow(void);
+void OS_ShutdownPending(void);
+void OS_SigtermHandler(int signo);
+void OS_Sigusr1Handler(int signo);
+void OS_SigpipeHandler(int signo);
+void OS_InstallSignalHandlers(int force);
+#endif
+
 #if defined (__cplusplus) || defined (c_plusplus)
 } /* terminate extern "C" { */
 #endif
index 5465cad..883bddf 100755 (executable)
@@ -17,7 +17,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: os_unix.c,v 1.28 2001/06/22 14:26:39 robs Exp $";
+static const char rcsid[] = "$Id: os_unix.c,v 1.29 2001/09/06 13:06:12 robs Exp $";
 #endif /* not lint */
 
 #include "fcgi_config.h"
@@ -41,6 +41,7 @@ static const char rcsid[] = "$Id: os_unix.c,v 1.28 2001/06/22 14:26:39 robs Exp
 #include <string.h>
 #include <sys/time.h>
 #include <sys/un.h>
+#include <signal.h>
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -99,6 +100,64 @@ static fd_set writeFdSetPost;
 static int numWrPosted = 0;
 static int volatile maxFd = -1;
 
+static int shutdownPending = FALSE;
+static int shutdownNow = FALSE;
+
+void OS_ShutdownNow()
+{
+    shutdownNow = TRUE;
+    shutdownPending = TRUE;
+}
+
+void OS_ShutdownPending()
+{
+    shutdownPending = TRUE;
+}
+
+void OS_SigtermHandler(int signo)
+{
+    OS_ShutdownNow();
+}
+
+void OS_Sigusr1Handler(int signo)
+{
+    OS_ShutdownPending();
+}
+
+void OS_SigpipeHandler(int signo)
+{
+    ;
+}
+
+static void installSignalHandler(int signo, const struct sigaction * act, int force)
+{
+    struct sigaction sa;
+
+    sigaction(signo, NULL, &sa);
+
+    if (force || sa.sa_handler == SIG_DFL) 
+    {
+        sigaction(signo, act, NULL);
+    }
+}
+
+void OS_InstallSignalHandlers(int force)
+{
+    struct sigaction sa;
+
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+
+    sa.sa_handler = OS_SigpipeHandler;
+    installSignalHandler(SIGPIPE, &sa, force);
+
+    sa.sa_handler = OS_Sigusr1Handler;
+    installSignalHandler(SIGUSR1, &sa, force);
+
+    sa.sa_handler = OS_SigtermHandler;
+    installSignalHandler(SIGTERM, &sa, force);
+}
+
 /*
  *--------------------------------------------------------------
  *
@@ -135,7 +194,11 @@ int OS_LibInit(int stdioFds[3])
     FD_ZERO(&writeFdSet);
     FD_ZERO(&readFdSetPost);
     FD_ZERO(&writeFdSetPost);
+
+    OS_InstallSignalHandlers(FALSE);
+
     libInitialized = TRUE;
+
     return 0;
 }
 
@@ -156,6 +219,8 @@ int OS_LibInit(int stdioFds[3])
  */
 void OS_LibShutdown()
 {
+    OS_ShutdownNow();
+
     if(!libInitialized)
         return;
 
@@ -407,6 +472,7 @@ int OS_FcgiConnect(char *bindPath)
  */
 int OS_Read(int fd, char * buf, size_t len)
 {
+    if (shutdownNow) return -1;
     return(read(fd, buf, len));
 }
 
@@ -428,6 +494,7 @@ int OS_Read(int fd, char * buf, size_t len)
  */
 int OS_Write(int fd, char * buf, size_t len)
 {
+    if (shutdownNow) return -1;
     return(write(fd, buf, len));
 }
 
@@ -1062,7 +1129,7 @@ static int is_af_unix_keeper(const int fd)
  */
 int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs)
 {
-    int socket;
+    int socket = -1;
     union {
         struct sockaddr_un un;
         struct sockaddr_in in;
@@ -1079,14 +1146,29 @@ int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs)
 #else
                 int len = sizeof(sa);
 #endif
+                if (shutdownPending) break;
+                /* There's a window here */
+
                 socket = accept(listen_sock, (struct sockaddr *)&sa, &len);
-            } while (socket < 0 && errno == EINTR && !fail_on_intr);
+            } while (socket < 0 
+                     && errno == EINTR 
+                     && (! fail_on_intr && ! shutdownPending));
 
             if (socket < 0) {
                 if (!is_reasonable_accept_errno(errno)) {
                     int errnoSave = errno;
+
                     ReleaseLock(listen_sock);
-                    errno = errnoSave;
+                    
+                    if (shutdownPending) 
+                    {
+                        OS_LibShutdown();
+                    }
+                    else 
+                    {
+                        errno = errnoSave;
+                    }
+
                     return (-1);
                 }
                 errno = 0;