about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/minutils/s6-uevent-listener.c75
1 files changed, 18 insertions, 57 deletions
diff --git a/src/minutils/s6-uevent-listener.c b/src/minutils/s6-uevent-listener.c
index 29fbc38..e882821 100644
--- a/src/minutils/s6-uevent-listener.c
+++ b/src/minutils/s6-uevent-listener.c
@@ -9,32 +9,28 @@
 #include <errno.h>
 #include <signal.h>
 #include <sys/socket.h>
-#include <sys/wait.h>
 #include <linux/netlink.h>
 #include <skalibs/types.h>
 #include <skalibs/allreadwrite.h>
 #include <skalibs/siovec.h>
 #include <skalibs/buffer.h>
 #include <skalibs/sgetopt.h>
+#include <skalibs/error.h>
 #include <skalibs/strerr2.h>
 #include <skalibs/iopause.h>
 #include <skalibs/djbunix.h>
 #include <skalibs/sig.h>
 #include <skalibs/selfpipe.h>
 
-#define USAGE "s6-uevent-listener [ -v verbosity ] [ -b kbufsz ] helperprogram..."
+#define USAGE "s6-uevent-listener [ -v verbosity ] [ -b kbufsz ]"
 #define dieusage() strerr_dieusage(100, USAGE)
 #define dienomem() strerr_diefu1sys(111, "build string") ;
 
 #define MAXNLSIZE 4096
-#define BUFSIZE 8191
 
-static char buf1[BUFSIZE + 1] ;
-static buffer b1 = BUFFER_INIT(&buffer_write, 1, buf1, BUFSIZE + 1) ;
 static unsigned int cont = 1, verbosity = 1 ;
-static pid_t pid ;
 
-static inline int fd_recvmsg (int fd, struct msghdr *hdr)
+static inline ssize_t fd_recvmsg (int fd, struct msghdr *hdr)
 {
   ssize_t r ;
   do r = recvmsg(fd, hdr, MSG_DONTWAIT) ;
@@ -64,26 +60,6 @@ static inline void handle_signals (void)
         cont = 0 ;
         fd_close(0) ;
         break ;
-      case SIGCHLD :
-      {
-        char fmt[UINT_FMT] ;
-        int wstat ;
-        int r = wait_pid_nohang(pid, &wstat) ;
-        if (r < 0)
-          if (errno != ECHILD) strerr_diefu1sys(111, "wait_pid_nohang") ;
-          else break ;
-        else if (!r) break ;
-        if (WIFSIGNALED(wstat))
-        {
-          fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
-          strerr_dief2x(1, "child crashed with signal ", fmt) ;
-        }
-        else
-        {
-          fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ;
-          strerr_dief2x(1, "child exited ", fmt) ;
-        }
-      }
       default :
         strerr_dief1x(101, "internal error: inconsistent signal state. Please submit a bug-report.") ;
     }
@@ -92,7 +68,8 @@ static inline void handle_signals (void)
 
 static inline void handle_stdout (void)
 {
-  if (!buffer_flush(&b1)) strerr_diefu1sys(111, "flush stdout") ;
+  if (!buffer_flush(buffer_1) && !error_isagain(errno))
+    strerr_diefu1sys(111, "flush stdout") ;
 }
 
 static inline void handle_netlink (void)
@@ -110,7 +87,7 @@ static inline void handle_netlink (void)
     .msg_flags = 0
   } ;
   ssize_t r ;
-  buffer_wpeek(&b1, v) ;
+  buffer_wpeek(buffer_1, v) ;
   siovec_trunc(v, 2, siovec_len(v, 2) - 1) ;
   r = sanitize_read(fd_recvmsg(0, &msg)) ;
   if (r < 0)
@@ -131,14 +108,14 @@ static inline void handle_netlink (void)
   {
     if (verbosity >= 3)
     {
-      char fmt[UINT_FMT] ;
-      fmt[uint_fmt(fmt, nl.nl_pid)] = 0 ;
+      char fmt[PID_FMT] ;
+      fmt[pid_fmt(fmt, nl.nl_pid)] = 0 ;
       strerr_warnw3x("netlink message", " from userspace process ", fmt) ;
     }
     return ;
   }
-  buffer_wseek(&b1, r) ;
-  buffer_putnoflush(&b1, "", 1) ;
+  buffer_wseek(buffer_1, r) ;
+  buffer_putnoflush(buffer_1, "", 1) ;
 }
 
 
@@ -161,45 +138,29 @@ int main (int argc, char const *const *argv, char const *const *envp)
       }
     }
     argc -= l.ind ; argv += l.ind ;
-    if (!argc) strerr_dieusage(100, USAGE) ;
     if (!netlink_init_stdin(kbufsz)) strerr_diefu1sys(111, "init netlink") ;
   }
 
   x[0].fd = selfpipe_init() ;
   if (x[0].fd < 0) strerr_diefu1sys(111, "init selfpipe") ;
   if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ;
-  {
-    sigset_t set ;
-    sigemptyset(&set) ;
-    sigaddset(&set, SIGTERM) ;
-    sigaddset(&set, SIGCHLD) ;
-    if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ;
-  }
-
-  {
-    int fd ;
-    pid = child_spawn1_pipe(argv[0], argv, envp, &fd, 0) ;
-    if (!pid) strerr_diefu2sys(111, "spawn ", argv[0]) ;
-    if (fd_move(1, fd) < 0) strerr_diefu1sys(111, "move pipe to stdout") ;
-    if (ndelay_on(1) < 0) strerr_diefu1sys(111, "make stdout nonblocking") ;
-  }
+  if (selfpipe_trap(SIGTERM) < 0) strerr_diefu1sys(111, "trap SIGTERM") ;
 
   if (verbosity >= 2) strerr_warni1x("starting") ;
 
   while (cont || buffer_len(buffer_1))
   {
     int r ;
-    x[1].events = buffer_len(&b1) ? IOPAUSE_WRITE : 0 ;
-    x[2].events = buffer_available(&b1) >= MAXNLSIZE + 1 ? IOPAUSE_READ : 0 ;
+    x[1].events = buffer_len(buffer_1) ? IOPAUSE_WRITE : 0 ;
+    x[2].events = buffer_available(buffer_1) >= MAXNLSIZE + 1 ? IOPAUSE_READ : 0 ;
     r = iopause(x, 2 + cont, 0, 0) ;
     if (r < 0) strerr_diefu1sys(111, "iopause") ;
     if (!r) continue ;
-    if (x[0].revents & IOPAUSE_EXCEPT)
-      strerr_diefu1x(111, "iopause: trouble with selfpipe") ;
-    if (x[0].revents & IOPAUSE_READ)
-      handle_signals() ;
-    if (x[1].revents & IOPAUSE_WRITE)
-      handle_stdout() ;
+    for (r = 0 ; r < 2 ; r++)
+      if (x[r].revents & IOPAUSE_EXCEPT)
+        x[r].revents |= IOPAUSE_READ | IOPAUSE_WRITE ;
+    if (x[0].revents & IOPAUSE_READ) handle_signals() ;
+    if (x[1].revents & IOPAUSE_WRITE) handle_stdout() ;
     if (cont && x[2].events & IOPAUSE_READ && x[2].revents & IOPAUSE_READ)
       handle_netlink() ;
   }