Merge "Slightly refactor signal handling and fd closing"
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 43490cb..5aca297 100755
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -16,6 +16,8 @@
 
 #include "dnsmasq.h"
 
+#include <sys/stat.h>
+
 #if defined(HAVE_BSD_NETWORK)
 #error Should not HAVE_BSD_NETWORK
 #endif
@@ -75,11 +77,52 @@
 static int check_android_listeners(fd_set *set);
 #endif
 
+void setupSignalHandling() {
+    struct sigaction sigact;
+
+    sigact.sa_handler = sig_handler;
+    sigact.sa_flags = 0;
+    sigemptyset(&sigact.sa_mask);
+    sigaction(SIGUSR1, &sigact, NULL);
+    sigaction(SIGUSR2, &sigact, NULL);
+    sigaction(SIGHUP, &sigact, NULL);
+    sigaction(SIGTERM, &sigact, NULL);
+    sigaction(SIGALRM, &sigact, NULL);
+    sigaction(SIGCHLD, &sigact, NULL);
+
+    /* ignore SIGPIPE */
+    sigact.sa_handler = SIG_IGN;
+    sigaction(SIGPIPE, &sigact, NULL);
+}
+
+void closeUnwantedFileDescriptors() {
+    const long kMaxFd = sysconf(_SC_OPEN_MAX);
+    long i;
+    struct stat stat_buf;
+
+    /* Close any file descriptors we inherited apart from std{in|out|err}. */
+    for (i = 0; i < kMaxFd; i++) {
+        // TODO: Evaluate just skipping STDIN, since netd does not
+        // (intentionally) pass in any other file descriptors.
+        if (i == STDOUT_FILENO || i == STDERR_FILENO || i == STDIN_FILENO) {
+            continue;
+        }
+
+        if (fstat(i, &stat_buf) != 0) {
+            if (errno == EBADF) continue;
+            my_syslog(LOG_ERR, "fstat(%d) error: %d/%s", i, errno, strerror(errno));
+        } else {
+            my_syslog(LOG_ERR, "Closing inherited file descriptor %d (%u:%u)",
+                      i, stat_buf.st_dev, stat_buf.st_ino);
+        }
+        close(i);
+    }
+}
+
 int main (int argc, char **argv)
 {
   int bind_fallback = 0;
   time_t now;
-  struct sigaction sigact;
   struct iname *if_tmp;
   int piperead, pipefd[2], err_pipe[2];
   struct passwd *ent_pw = NULL;
@@ -102,19 +145,7 @@
   textdomain("dnsmasq");
 #endif
 
-  sigact.sa_handler = sig_handler;
-  sigact.sa_flags = 0;
-  sigemptyset(&sigact.sa_mask);
-  sigaction(SIGUSR1, &sigact, NULL);
-  sigaction(SIGUSR2, &sigact, NULL);
-  sigaction(SIGHUP, &sigact, NULL);
-  sigaction(SIGTERM, &sigact, NULL);
-  sigaction(SIGALRM, &sigact, NULL);
-  sigaction(SIGCHLD, &sigact, NULL);
-
-  /* ignore SIGPIPE */
-  sigact.sa_handler = SIG_IGN;
-  sigaction(SIGPIPE, &sigact, NULL);
+  setupSignalHandling();
 
   umask(022); /* known umask, create leases and pid files as 0644 */
 
@@ -133,11 +164,8 @@
 	daemon->lease_file = LEASEFILE;
     }
 #endif
-  
-  /* Close any file descriptors we inherited apart from std{in|out|err} */
-  for (i = 0; i < max_fd; i++)
-    if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
-      close(i);
+
+  closeUnwantedFileDescriptors();
 
 #ifdef HAVE_LINUX_NETWORK
   netlink_init();
@@ -589,43 +617,29 @@
     }
 }
 
-static void sig_handler(int sig)
-{
-  if (pid == 0)
-    {
-      /* ignore anything other than TERM during startup
-	 and in helper proc. (helper ignore TERM too) */
-      if (sig == SIGTERM)
-	exit(EC_MISC);
-    }
-  else if (pid != getpid())
-    {
-      /* alarm is used to kill TCP children after a fixed time. */
-      if (sig == SIGALRM)
-	_exit(0);
-    }
-  else
-    {
-      /* master process */
-      int event, errsave = errno;
-      
-      if (sig == SIGHUP)
-	event = EVENT_RELOAD;
-      else if (sig == SIGCHLD)
-	event = EVENT_CHILD;
-      else if (sig == SIGALRM)
-	event = EVENT_ALARM;
-      else if (sig == SIGTERM)
-	event = EVENT_TERM;
-      else if (sig == SIGUSR1)
-	event = EVENT_DUMP;
-      else if (sig == SIGUSR2)
-	event = EVENT_REOPEN;
-      else
-	return;
+static void sig_handler(int sig) {
+    if (pid == 0) {
+        /* ignore anything other than TERM during startup
+           and in helper proc. (helper ignore TERM too) */
+        if (sig == SIGTERM) exit(EC_MISC);
+    } else if (pid != getpid()) {
+        /* alarm is used to kill TCP children after a fixed time. */
+        if (sig == SIGALRM) _exit(0);
+    } else {
+        /* master process */
+        const int errsave = errno;
+        int event;
 
-      send_event(pipewrite, event, 0); 
-      errno = errsave;
+        if (sig == SIGHUP) event = EVENT_RELOAD;
+        else if (sig == SIGCHLD) event = EVENT_CHILD;
+        else if (sig == SIGALRM) event = EVENT_ALARM;
+        else if (sig == SIGTERM) event = EVENT_TERM;
+        else if (sig == SIGUSR1) event = EVENT_DUMP;
+        else if (sig == SIGUSR2) event = EVENT_REOPEN;
+        else return;
+
+        send_event(pipewrite, event, 0);
+        errno = errsave;
     }
 }