diff src/dnsbl.cpp @ 65:1ab70970c8c8

need to cleanup zombie children
author carl
date Sun, 16 Jan 2005 17:40:22 -0800
parents 6add229288a8
children e6a2d0be7c5e
line wrap: on
line diff
--- a/src/dnsbl.cpp	Sun Jan 16 09:20:50 2005 -0800
+++ b/src/dnsbl.cpp	Sun Jan 16 17:40:22 2005 -0800
@@ -70,6 +70,8 @@
 #include <fstream>
 #include <syslog.h>
 #include <pwd.h>
+#include <sys/wait.h>   /* header for waitpid() and various macros */
+#include <signal.h>     /* header for signal functions */
 
 static char* dnsbl_version="$Id$";
 
@@ -97,6 +99,7 @@
     sfsistat mlfi_eom(SMFICTX *ctx);
     sfsistat mlfi_abort(SMFICTX *ctx);
     sfsistat mlfi_close(SMFICTX *ctx);
+    void sig_chld(int signo);
 }
 
 struct ltstr {
@@ -1653,6 +1656,20 @@
 }
 
 
+/*
+ * The signal handler function -- only gets called when a SIGCHLD
+ * is received, ie when a child terminates
+ */
+void sig_chld(int signo)
+{
+    int status;
+    /* Wait for any child without blocking */
+    while (waitpid(-1, &status, WNOHANG) > 0) {
+        // ignore child exit status, we only do this to cleanup zombies
+    }
+}
+
+
 int main(int argc, char**argv)
 {
     bool check   = false;
@@ -1799,17 +1816,6 @@
         memset(&server, '\0', sizeof(server));
         server.sun_family = AF_UNIX;
         strncpy(server.sun_path, resolver_port, sizeof(server.sun_path)-1);
-        // set the socket options
-     ///int      reuse_addr = 1;
-     ///linger linger_opt;
-     ///linger_opt.l_onoff  = 0;    // off
-     ///linger_opt.l_linger = 0;
-     ///setsockopt(resolver_socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&reuse_addr), sizeof(reuse_addr));
-     ///setsockopt(resolver_socket, SOL_SOCKET, SO_LINGER,    reinterpret_cast<char*>(&linger_opt), sizeof(linger_opt));
-     ///// set nonblocking mode
-     ///int     dummy = 0;
-     ///int     flags = fcntl(resolver_socket, F_GETFL, dummy);
-     ///if (flags >= 0) fcntl(resolver_socket, F_SETFL, flags | O_NONBLOCK);
         //try to bind the address to the socket.
         if (bind(resolver_socket, (sockaddr *)&server, sizeof(server)) < 0) {
             // bind failed
@@ -1824,7 +1830,16 @@
             // listen failed
             shutdown(resolver_socket, SHUT_RDWR);
             close(resolver_socket);
-            my_syslog("child failed to listen to the resolver socket");
+            my_syslog("child failed to listen to resolver socket");
+            exit(0);   // failed
+        }
+        // setup sigchld handler to prevent zombies
+        struct sigaction act;
+        act.sa_handler = sig_chld;      // Assign sig_chld as our SIGCHLD handler
+        sigemptyset(&act.sa_mask);      // We don't want to block any other signals in this example
+        act.sa_flags = SA_NOCLDSTOP;    // only want children that have terminated
+        if (sigaction(SIGCHLD, &act, NULL) < 0) {
+            my_syslog("child failed to setup SIGCHLD handler");
             exit(0);   // failed
         }
         while (true) {