# HG changeset patch # User carl # Date 1105926022 28800 # Node ID 1ab70970c8c86c0963dee20c6367b9723d876cfc # Parent 6add229288a808e88b38afc979dc0d6f70bc18e3 need to cleanup zombie children diff -r 6add229288a8 -r 1ab70970c8c8 src/dnsbl.cpp --- 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 #include #include +#include /* header for waitpid() and various macros */ +#include /* 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(&reuse_addr), sizeof(reuse_addr)); - ///setsockopt(resolver_socket, SOL_SOCKET, SO_LINGER, reinterpret_cast(&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) {