[Toybox] [PATCH] Factor out dhcpd's and syslogd's main loops into a library function

Felix Janda felix.janda at posteo.de
Sun Sep 1 06:54:27 PDT 2013


Both syslogd and dhcpd wait for sockets, signals or a timeout. Currently,
they use select() with its timeout to listen to the sockets and a
self-pipe for the signals.

The new library function instead uses pselect() without a timeout and
alarm(). With pselect() signals are only unblocked during this system
call; so the xwrappers don't need to be aware about interrupted syscalls.
alarm() is used instead of the timeout argument to pselect() so that
the length of the intervals between timeouts is not affected by being
interrupted.

On SIGHUP syslogd restarts. Previously everything relevant was contained
in syslogd_main() and the restarting was implemented by a goto. Now a
longjmp() would be necessary. I instead used an xexec(). Since xexec()
doesn't change the pid the pidfile needs to be unlinked() before
terminating so that xpidfile() doesn't complain. Furthermore if not run
in the foreground syslogd will daemonize() again when restarting. Could
one detect in daemonize() whether daemonizing is necessary?

Felix

# HG changeset patch
# User Felix Janda <felix.janda at posteo.de>
# Date 1378041908 -7200
# Node ID 752d22ece0fe3fa9763fd0b6e231e653cc173890
# Parent  587b7572aac2a64988503458155e1f2546672525
Factor out daemon select() loops into a library function

diff -r 587b7572aac2 -r 752d22ece0fe lib/lib.h
--- a/lib/lib.h	Sun Sep 01 15:13:58 2013 +0200
+++ b/lib/lib.h	Sun Sep 01 15:25:08 2013 +0200
@@ -201,4 +201,7 @@
 char  *astrcat (char *, char *);
 char *xastrcat (char *, char *);
 
+// daemon helper functions
 void daemonize(void);
+void daemon_main_loop(int nfds, fd_set *readfds, long timeout, int *signals,
+                 void (*sighandler)(int), void (*selecthandler)(fd_set *fds));
diff -r 587b7572aac2 -r 752d22ece0fe lib/pending.c
--- a/lib/pending.c	Sun Sep 01 15:13:58 2013 +0200
+++ b/lib/pending.c	Sun Sep 01 15:25:08 2013 +0200
@@ -92,3 +92,41 @@
   dup2(fd, 2);
   if (fd > 2) close(fd);
 }
+
+static int daemon_sig;
+
+static void daemon_sighandler(int sig)
+{
+  daemon_sig = sig;
+}
+
+/*
+ * main loop for daemons listening to signals and file handles
+*/
+void daemon_main_loop(int nfds, fd_set *readfds, long timeout, int *signals,
+                 void (*sighandler)(int), void (*selecthandler)(fd_set *fds))
+{
+  fd_set copy;
+  sigset_t sigmask;
+  struct sigaction action;
+  int *i, ret;
+
+  sigemptyset(&sigmask);
+  action.sa_handler = daemon_sighandler;
+  sigemptyset(&action.sa_mask);
+  action.sa_flags = 0;
+  if (timeout) alarm(timeout);
+  for (i = signals; *i; i++) sigaddset(&sigmask, *i);
+  sigprocmask(SIG_SETMASK, &sigmask, 0);
+  for (i = signals; *i; i++) sigaction(*i, &action, 0);
+
+  for (;;) {
+    memcpy(&copy, &readfds, sizeof(copy));
+    ret = pselect(nfds, &copy, 0, 0, 0, &action.sa_mask);
+    if (ret == -1) {
+      if (errno != EINTR) error_exit ("pselect");
+      if (timeout && daemon_sig == SIGALRM) alarm(timeout);
+      sighandler(daemon_sig);
+    } else selecthandler(&copy);
+  }
+}
diff -r 587b7572aac2 -r 752d22ece0fe toys/pending/dhcpd.c
--- a/toys/pending/dhcpd.c	Sun Sep 01 15:13:58 2013 +0200
+++ b/toys/pending/dhcpd.c	Sun Sep 01 15:25:08 2013 +0200
@@ -206,11 +206,9 @@
     {"msstaticroutes" , DHCP_STCRTS | 0xf9, NULL, 0},
 };
 
-struct fd_pair { int rd; int wr; };
 static server_config_t gconfig;
 static server_state_t gstate;
 static uint8_t infomode;
-static struct fd_pair sigfd;
 static int constone = 1;
 
 // calculate options size.
@@ -316,29 +314,6 @@
   }
 }
 
-// Generic signal handler real handling is done in main funcrion.
-static void signal_handler(int sig)
-{
-  unsigned char ch = sig;
-  if (write(sigfd.wr, &ch, 1) != 1) dbg("can't send signal\n");
-}
-
-// signal setup for SIGUSR1 SIGTERM
-static int setup_signal()
-{
-  if (pipe((int *)&sigfd) < 0) {
-    dbg("signal pipe failed\n");
-    return -1;
-  }
-  fcntl(sigfd.wr , F_SETFD, FD_CLOEXEC);
-  fcntl(sigfd.rd , F_SETFD, FD_CLOEXEC);
-  int flags = fcntl(sigfd.wr, F_GETFL);
-  fcntl(sigfd.wr, F_SETFL, flags | O_NONBLOCK);
-  signal(SIGUSR1, signal_handler);
-  signal(SIGTERM, signal_handler);
-  return 0;
-}
-
 // String STR to UINT32 conversion strored in VAR
 static int strtou32(const char *str, void *var)
 {
@@ -1073,15 +1048,114 @@
   return ret;
 }
 
+static void sig_handler(int sig)
+{
+  switch (sig) {
+    case SIGALRM:
+      write_leasefile();
+      if (get_interface(gconfig.interface, &gconfig.ifindex, &gconfig.server_nip, gconfig.server_mac)<0)
+        perror_exit("Interface lost %s\n", gconfig.interface);
+      gconfig.server_nip = htonl(gconfig.server_nip);
+      break;
+    case SIGUSR1:
+      infomsg(infomode, "Received SIGUSR1");
+      write_leasefile();
+      break;
+    case SIGTERM:
+      infomsg(infomode, "Received SIGTERM");
+      write_leasefile();
+      unlink(gconfig.pidfile);
+      exit(0);
+      break;
+  }
+}
+
+static void select_handler(fd_set *rfds)
+{
+  uint8_t *optptr, msgtype = 0;
+  uint32_t serverid = 0, requested_nip = 0;
+  uint32_t reqested_lease = 0;
+  char *hstname = NULL;
+
+  dbg("select listen sock read\n");
+  if (read_packet() < 0) {
+    open_listensock();
+    return;
+  }
+  get_optval((uint8_t*)&gstate.rcvd_pkt.options, DHCP_OPT_MESSAGE_TYPE, &gstate.rqcode);
+  if (gstate.rqcode == 0 || gstate.rqcode < DHCPDISCOVER 
+      || gstate.rqcode > DHCPINFORM) {
+    dbg("no or bad message type option, ignoring packet.\n");
+    return;
+  }
+  get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_SERVER_ID, &serverid);
+  if (serverid && (serverid != gconfig.server_nip)) {
+    dbg("server ID doesn't match, ignoring packet.\n");
+    return;
+  }
+  switch (gstate.rqcode) {
+    case DHCPDISCOVER:
+      msgtype = DHCPOFFER;
+      dbg("Message Type : DHCPDISCOVER\n");
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_REQUESTED_IP, &requested_nip);
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_HOST_NAME, &hstname);
+      reqested_lease = gconfig.offer_time;
+      get_reqparam(&gstate.rqopt);
+      optptr = prepare_send_pkt();
+      gstate.send_pkt.yiaddr = getip_from_pool(requested_nip, gstate.rcvd_pkt.chaddr, &reqested_lease, hstname);
+      if(!gstate.send_pkt.yiaddr){
+        msgtype = DHCPNAK;
+        optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
+        send_packet(1);
+        break;
+      }
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_LEASE_TIME, &reqested_lease);
+      reqested_lease = htonl(get_lease(reqested_lease + time(NULL)));
+      optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
+      optptr = set_optval(optptr, DHCP_OPT_SERVER_ID, &gconfig.server_nip, 4);
+      optptr = set_optval(optptr, DHCP_OPT_LEASE_TIME, &reqested_lease, 4);
+      optptr = set_reqparam(optptr, gstate.rqopt);
+      send_packet(1);
+      break;
+    case DHCPREQUEST:
+      msgtype = DHCPACK;
+      dbg("Message Type : DHCPREQUEST\n");
+      optptr = prepare_send_pkt();
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_REQUESTED_IP, &requested_nip);
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_LEASE_TIME, &reqested_lease);
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_HOST_NAME, &hstname);
+      gstate.send_pkt.yiaddr = getip_from_pool(requested_nip, gstate.rcvd_pkt.chaddr, &reqested_lease, hstname);
+      if (!serverid) reqested_lease = gconfig.max_lease_sec;
+      if (!gstate.send_pkt.yiaddr) {
+        msgtype = DHCPNAK;
+        optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
+        send_packet(1);
+        break;
+      }
+      optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
+      optptr = set_optval(optptr, DHCP_OPT_SERVER_ID, &gconfig.server_nip, 4);
+      reqested_lease = htonl(reqested_lease);
+      optptr = set_optval(optptr, DHCP_OPT_LEASE_TIME, &reqested_lease, 4);
+      send_packet(1);
+      write_leasefile();
+      break;
+    case DHCPDECLINE:// FALL THROUGH
+    case DHCPRELEASE:
+      dbg("Message Type : DHCPDECLINE or DHCPRELEASE \n");
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_SERVER_ID, &serverid);
+      if (serverid != gconfig.server_nip) break;
+      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_REQUESTED_IP, &requested_nip);
+      delip_from_lease(requested_nip, gstate.rcvd_pkt.chaddr, (gstate.rqcode==DHCPRELEASE)?0:gconfig.decline_time);
+      break;
+    default:
+      dbg("Message Type : %u\n", gstate.rqcode);
+      break;
+  }
+}
+
 void dhcpd_main(void)
 {
-  struct timeval tv;
-  int retval;
-  uint8_t *optptr, msgtype = 0;
-  uint32_t waited = 0, serverid = 0, requested_nip = 0;
-  uint32_t reqested_lease = 0, ip_pool_size = 0;
-  char *hstname = NULL;
-  fd_set rfds;
+  uint32_t ip_pool_size;
 
   infomode = LOG_CONSOLE;
   if (!(flag_chk(FLAG_f))) {
@@ -1111,137 +1185,15 @@
     perror_exit("Failed to get interface %s", gconfig.interface);
   gconfig.server_nip = htonl(gconfig.server_nip);
 
-  setup_signal();
   open_listensock();
   fcntl(gstate.listensock, F_SETFD, FD_CLOEXEC);
 
-  for (;;) {
-    uint32_t timestmp = time(NULL);
-    FD_ZERO(&rfds);
-    FD_SET(gstate.listensock, &rfds);
-    FD_SET(sigfd.rd, &rfds);
-    tv.tv_sec = gconfig.auto_time - waited;
-    tv.tv_usec = 0;
-    retval = 0;
-    serverid = 0;
-    msgtype = 0;
+  fd_set rfds;
+  FD_ZERO(&rfds);
+  FD_SET(gstate.listensock, &rfds);
 
-    int maxfd = (sigfd.rd > gstate.listensock)? sigfd.rd : gstate.listensock;
-    dbg("select waiting ....\n");
-    retval = select(maxfd + 1, &rfds, NULL, NULL, (gconfig.auto_time?&tv:NULL));
-    if (retval < 0) {
-      if (errno == EINTR) {
-        waited += (unsigned) time(NULL) - timestmp;
-        continue;
-      }
-      dbg("Error in select wait again...\n");
-      continue;
-    }
-    if (!retval) { // Timed out 
-      dbg("select wait Timed Out...\n");
-      waited = 0;
-      write_leasefile();
-      if (get_interface(gconfig.interface, &gconfig.ifindex, &gconfig.server_nip, gconfig.server_mac)<0)
-        perror_exit("Interface lost %s\n", gconfig.interface);
-      gconfig.server_nip = htonl(gconfig.server_nip);
-      continue;
-    }
-    if (FD_ISSET(sigfd.rd, &rfds)) { // Some Activity on RDFDs : is signal 
-      unsigned char sig;
-      if (read(sigfd.rd, &sig, 1) != 1) {
-        dbg("signal read failed.\n");
-        continue;
-      }
-      switch (sig) {
-      case SIGUSR1:
-        infomsg(infomode, "Received SIGUSR1");
-        write_leasefile();
-        continue;
-      case SIGTERM:
-        infomsg(infomode, "Received SIGTERM");
-        write_leasefile();
-        unlink(gconfig.pidfile);
-        exit(0);
-        break;
-      default: break;
-      }
-    }
-    if (FD_ISSET(gstate.listensock, &rfds)) { // Some Activity on RDFDs : is socket
-      dbg("select listen sock read\n");
-      if (read_packet() < 0) {
-        open_listensock();
-        continue;
-      }
-      waited += time(NULL) - timestmp;
-      get_optval((uint8_t*)&gstate.rcvd_pkt.options, DHCP_OPT_MESSAGE_TYPE, &gstate.rqcode);
-      if (gstate.rqcode == 0 || gstate.rqcode < DHCPDISCOVER 
-          || gstate.rqcode > DHCPINFORM) {
-        dbg("no or bad message type option, ignoring packet.\n");
-        continue;
-      }
-      get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_SERVER_ID, &serverid);
-      if (serverid && (serverid != gconfig.server_nip)) {
-        dbg("server ID doesn't match, ignoring packet.\n");
-        continue;
-      }
-      switch (gstate.rqcode) {
-        case DHCPDISCOVER:
-          msgtype = DHCPOFFER;
-          dbg("Message Type : DHCPDISCOVER\n");
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_REQUESTED_IP, &requested_nip);
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_HOST_NAME, &hstname);
-          reqested_lease = gconfig.offer_time;
-          get_reqparam(&gstate.rqopt);
-          optptr = prepare_send_pkt();
-          gstate.send_pkt.yiaddr = getip_from_pool(requested_nip, gstate.rcvd_pkt.chaddr, &reqested_lease, hstname);
-          if(!gstate.send_pkt.yiaddr){
-            msgtype = DHCPNAK;
-            optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
-            send_packet(1);
-            break;
-          }
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_LEASE_TIME, &reqested_lease);
-          reqested_lease = htonl(get_lease(reqested_lease + time(NULL)));
-          optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
-          optptr = set_optval(optptr, DHCP_OPT_SERVER_ID, &gconfig.server_nip, 4);
-          optptr = set_optval(optptr, DHCP_OPT_LEASE_TIME, &reqested_lease, 4);
-          optptr = set_reqparam(optptr, gstate.rqopt);
-          send_packet(1);
-          break;
-        case DHCPREQUEST:
-          msgtype = DHCPACK;
-          dbg("Message Type : DHCPREQUEST\n");
-          optptr = prepare_send_pkt();
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_REQUESTED_IP, &requested_nip);
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_LEASE_TIME, &reqested_lease);
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_HOST_NAME, &hstname);
-          gstate.send_pkt.yiaddr = getip_from_pool(requested_nip, gstate.rcvd_pkt.chaddr, &reqested_lease, hstname);
-          if (!serverid) reqested_lease = gconfig.max_lease_sec;
-          if (!gstate.send_pkt.yiaddr) {
-            msgtype = DHCPNAK;
-            optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
-            send_packet(1);
-            break;
-          }
-          optptr = set_optval(optptr, DHCP_OPT_MESSAGE_TYPE, &msgtype, 1);
-          optptr = set_optval(optptr, DHCP_OPT_SERVER_ID, &gconfig.server_nip, 4);
-          reqested_lease = htonl(reqested_lease);
-          optptr = set_optval(optptr, DHCP_OPT_LEASE_TIME, &reqested_lease, 4);
-          send_packet(1);
-          write_leasefile();
-          break;
-        case DHCPDECLINE:// FALL THROUGH
-        case DHCPRELEASE:
-          dbg("Message Type : DHCPDECLINE or DHCPRELEASE \n");
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_SERVER_ID, &serverid);
-          if (serverid != gconfig.server_nip) break;
-          get_optval((uint8_t*) &gstate.rcvd_pkt.options, DHCP_OPT_REQUESTED_IP, &requested_nip);
-          delip_from_lease(requested_nip, gstate.rcvd_pkt.chaddr, (gstate.rqcode==DHCPRELEASE)?0:gconfig.decline_time);
-          break;
-        default:
-          dbg("Message Type : %u\n", gstate.rqcode);
-          break;
-      }
-    }
-  }
+  dbg("enter main loop\n");
+  int signals[] = {SIGALRM, SIGUSR1, SIGTERM, 0};
+  daemon_main_loop(gstate.listensock + 1, &rfds, gconfig.auto_time, signals,
+                   sig_handler, select_handler);
 }
diff -r 587b7572aac2 -r 752d22ece0fe toys/pending/syslogd.c
--- a/toys/pending/syslogd.c	Sun Sep 01 15:13:58 2013 +0200
+++ b/toys/pending/syslogd.c	Sun Sep 01 15:25:08 2013 +0200
@@ -68,7 +68,6 @@
 
   struct unsocks *lsocks;  // list of listen sockets
   struct logfile *lfiles;  // list of write logfiles
-  int sigfd[2];
 )
 
 // Lookup numerical code from name
@@ -388,28 +387,71 @@
     TT.lfiles = fnode->next;
     free(fnode);
   }
+  unlink("/var/run/syslogd.pid");
 }
 
-static void signal_handler(int sig)
+static void sighandler(int sig)
 {
-  unsigned char ch = sig;
-  if (write(TT.sigfd[1], &ch, 1) != 1) error_msg("can't send signal");
+  switch(sig) {
+    case SIGALRM:
+      logmsg("<46>-- MARK --", 14);
+      break;
+    case SIGTERM:    /* FALLTHROUGH */
+    case SIGINT:     /* FALLTHROUGH */
+    case SIGQUIT:
+      logmsg("<46>syslogd exiting", 19);
+      if (CFG_TOYBOX_FREE ) cleanup();
+      signal(sig, SIG_DFL);
+      sigset_t ss;
+      sigemptyset(&ss);
+      sigaddset(&ss, sig);
+      sigprocmask(SIG_UNBLOCK, &ss, NULL);
+      raise(sig);
+      _exit(1);  /* Should not reach it */
+      break;
+    case SIGHUP:
+      logmsg("<46>syslogd exiting", 19);
+      cleanup(); //cleanup is done, as we restart syslog.
+      xexec(toys.argv);
+  }
+}
+
+static void selecthandler(fd_set *rfds)
+{
+  struct unsocks *tsd;
+  char *buffer = (toybuf + 2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each
+  int last_len=0;
+
+  for (tsd = TT.lsocks; tsd; tsd = tsd->next) {
+    int sd = tsd->sd;
+    if (FD_ISSET(sd, rfds)) {
+      int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL
+      if (len > 0) {
+        buffer[len] = '\0';
+        if((toys.optflags & FLAG_D) && (len == last_len))
+          if (!memcmp(last_buf, buffer, len)) break;
+
+        memcpy(last_buf, buffer, len);
+        last_len = len;
+        logmsg(buffer, len);
+      }
+      break;
+    }
+  }
 }
 
 void syslogd_main(void)
 {
   struct unsocks *tsd;
-  int nfds, retval, last_len=0;
-  struct timeval tv;
+  int nfds;
   fd_set rfds;        // fds for reading
-  char *temp, *buffer = (toybuf +2048), *last_buf = (toybuf + 3072); //these two buffs are of 1K each
+  char *temp;
 
   if ((toys.optflags & FLAG_p) && (strlen(TT.unix_socket) > 108))
     error_exit("Socket path should not be more than 108");
 
   TT.config_file = (toys.optflags & FLAG_f) ?
                    TT.config_file : "/etc/syslog.conf"; //DEFCONFFILE
-init_jumpin:
   tsd = xzalloc(sizeof(struct unsocks));
 
   tsd->path = (toys.optflags & FLAG_p) ? TT.unix_socket : "/dev/log"; // DEFLOGSOCK
@@ -445,94 +487,25 @@
       continue;
     }
     chmod(tsd->path, 0777);
-    nfds++;
+    nfds = tsd->sd;
   }
   if (!nfds) {
     error_msg("Can't open single socket for listenning.");
     goto clean_and_exit;
   }
 
-  // Setup signals
-  if (pipe(TT.sigfd) < 0) error_exit("pipe failed\n");
-
-  fcntl(TT.sigfd[1] , F_SETFD, FD_CLOEXEC);
-  fcntl(TT.sigfd[0] , F_SETFD, FD_CLOEXEC);
-  int flags = fcntl(TT.sigfd[1], F_GETFL);
-  fcntl(TT.sigfd[1], F_SETFL, flags | O_NONBLOCK);
-  signal(SIGHUP, signal_handler);
-  signal(SIGTERM, signal_handler);
-  signal(SIGINT, signal_handler);
-  signal(SIGQUIT, signal_handler);
-
   if (parse_config_file() == -1) goto clean_and_exit;
   open_logfiles();
-  if (!(toys.optflags & FLAG_n)) {
-    daemonize();
-    //don't daemonize again if SIGHUP received.
-    toys.optflags |= FLAG_n;
-  }
+  if (!(toys.optflags & FLAG_n)) daemonize();
   xpidfile("syslogd");
 
   logmsg("<46>Toybox: syslogd started", 27); //27 : the length of message
-  for (;;) {
-    // Add opened socks to rfds for select()
-    FD_ZERO(&rfds);
-    for (tsd = TT.lsocks; tsd; tsd = tsd->next) FD_SET(tsd->sd, &rfds);
-    FD_SET(TT.sigfd[0], &rfds);
-    tv.tv_usec = 0;
-    tv.tv_sec = TT.interval*60;
 
-    retval = select(TT.sigfd[0] + 1, &rfds, NULL, NULL, (TT.interval)?&tv:NULL);
-    if (retval < 0) {
-      if (errno != EINTR) perror_msg("Error in select ");
-    }
-    else if (!retval) logmsg("<46>-- MARK --", 14);
-    else if (FD_ISSET(TT.sigfd[0], &rfds)) { /* May be a signal */
-      unsigned char sig;
-
-      if (read(TT.sigfd[0], &sig, 1) != 1) {
-        error_msg("signal read failed.\n");
-        continue;
-      }
-      switch(sig) {
-        case SIGTERM:    /* FALLTHROUGH */
-        case SIGINT:     /* FALLTHROUGH */
-        case SIGQUIT:
-          logmsg("<46>syslogd exiting", 19);
-          if (CFG_TOYBOX_FREE ) cleanup();
-          signal(sig, SIG_DFL);
-          sigset_t ss;
-          sigemptyset(&ss);
-          sigaddset(&ss, sig);
-          sigprocmask(SIG_UNBLOCK, &ss, NULL);
-          raise(sig);
-          _exit(1);  /* Should not reach it */
-          break;
-        case SIGHUP:
-          logmsg("<46>syslogd exiting", 19);
-          cleanup(); //cleanup is done, as we restart syslog.
-          goto init_jumpin;
-        default: break;
-      }
-    } else { /* Some activity on listen sockets. */
-      for (tsd = TT.lsocks; tsd; tsd = tsd->next) {
-        int sd = tsd->sd;
-        if (FD_ISSET(sd, &rfds)) {
-          int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL
-          if (len > 0) {
-            buffer[len] = '\0';
-            if((toys.optflags & FLAG_D) && (len == last_len))
-              if (!memcmp(last_buf, buffer, len)) break;
-
-            memcpy(last_buf, buffer, len);
-            last_len = len;
-            logmsg(buffer, len);
-          }
-          break;
-        }
-      }
-    }
-  }
+  FD_ZERO(&rfds);
+  for (tsd = TT.lsocks; tsd; tsd = tsd->next) FD_SET(tsd->sd, &rfds);
+  int signals[] = {SIGALRM, SIGHUP, SIGTERM, SIGINT, SIGQUIT, 0};
+  daemon_main_loop(nfds + 1, &rfds, TT.interval*60, signals,
+                   sighandler, selecthandler);
 clean_and_exit:
   logmsg("<46>syslogd exiting", 19);
   if (CFG_TOYBOX_FREE ) cleanup();

 1378043667.0


More information about the Toybox mailing list