summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2020-11-23 23:27:31 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2020-11-23 23:27:31 +0000
commita43216278137fe399cdcea6210e580b445e16197 (patch)
tree99249d45157b13afc7b3dbad07416c065e64a153 /src
parent7812e30b70ee3d27c2b01d21d346c52656927858 (diff)
downloadexecline-a43216278137fe399cdcea6210e580b445e16197.tar.gz
execline-a43216278137fe399cdcea6210e580b445e16197.tar.xz
execline-a43216278137fe399cdcea6210e580b445e16197.zip
New forstdin; new trap; prepare for 2.7.0.0
Diffstat (limited to 'src')
-rw-r--r--src/execline/forstdin.c11
-rw-r--r--src/execline/trap.c147
2 files changed, 79 insertions, 79 deletions
diff --git a/src/execline/forstdin.c b/src/execline/forstdin.c
index 95ec4d5..7979811 100644
--- a/src/execline/forstdin.c
+++ b/src/execline/forstdin.c
@@ -3,6 +3,7 @@
 #include <sys/types.h>
 #include <string.h>
 #include <errno.h>
+
 #include <skalibs/types.h>
 #include <skalibs/sgetopt.h>
 #include <skalibs/buffer.h>
@@ -17,7 +18,7 @@
 #include <execline/config.h>
 #include <execline/execline.h>
 
-#define USAGE "forstdin [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -n ] [ -C | -c ] [ -0 | -d delim ] var command..."
+#define USAGE "forstdin [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -e eofcode ] [ -n ] [ -C | -c ] [ -0 | -d delim ] var command..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
 static genalloc pids = GENALLOC_ZERO ; /* pid_t */
@@ -51,12 +52,13 @@ int main (int argc, char const **argv, char const *const *envp)
   size_t nbc = 0 ;
   unsigned short okcodes[256] ;
   int crunch = 0, chomp = 0, not = 1 ;
+  unsigned short eofcode = 0 ;
   PROG = "forstdin" ;
   {
     subgetopt_t l = SUBGETOPT_ZERO ;
     for (;;)
     {
-      int opt = subgetopt_r(argc, argv, "pnCc0d:o:x:", &l) ;
+      int opt = subgetopt_r(argc, argv, "pnCc0d:o:x:e:", &l) ;
       if (opt == -1) break ;
       switch (opt)
       {
@@ -79,6 +81,9 @@ int main (int argc, char const **argv, char const *const *envp)
           not = 1 ;
           if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
           break ;
+        case 'e' :
+          if (!ushort_scan(l.arg, &eofcode)) dieusage() ;
+          break ;
         default : dieusage() ;
       }
     }
@@ -154,5 +159,5 @@ int main (int argc, char const **argv, char const *const *envp)
       if (!pids.len) break ;
       sig_pause() ;
     }
-  return 0 ;
+  return eofcode ;
 }
diff --git a/src/execline/trap.c b/src/execline/trap.c
index 9e5b4d2..0eec7db 100644
--- a/src/execline/trap.c
+++ b/src/execline/trap.c
@@ -4,31 +4,42 @@
 #include <string.h>
 #include <errno.h>
 #include <signal.h>
+
 #include <skalibs/sgetopt.h>
 #include <skalibs/types.h>
 #include <skalibs/nsig.h>
 #include <skalibs/sig.h>
 #include <skalibs/strerr2.h>
-#include <skalibs/tai.h>
 #include <skalibs/iopause.h>
 #include <skalibs/selfpipe.h>
 #include <skalibs/env.h>
 #include <skalibs/djbunix.h>
+
 #include <execline/execline.h>
 
-#define USAGE "trap [ -x ] [ -t timeout ] { signal { cmdline } ... } prog..."
+#define USAGE "trap [ -x ] { signal { cmdline } ... } prog..."
 #define dieusage() strerr_dieusage(100, USAGE) ;
 
 static pid_t pids[SKALIBS_NSIG + 1] ;
 static char const *const *argvs[SKALIBS_NSIG] ; /* initted with 0s */
 
-static void action (unsigned int i, char const *const *envp)
+static inline void action (unsigned int i, char const *const *envp, size_t envlen)
 {
   if (argvs[i])
   {
     if (!pids[i])
     {
-      pids[i] = child_spawn0(argvs[i][0], argvs[i], envp) ;
+      char const *newenvp[envlen + 3] ;
+      char modif[9 + PID_FMT + UINT_FMT] = "!=" ;
+      size_t m = 2 ;
+      m += pid_fmt(modif + m, pids[SKALIBS_NSIG]) ;
+      modif[m++] = 0 ;
+      memcpy(modif + m, "SIGNAL=", 7) ; m += 7 ;
+      m += uint_fmt(modif + m, i) ;
+      modif[m++] = 0 ;
+      if (!env_merge(newenvp, envlen + 3, envp, envlen, modif, m))
+        strerr_diefu1sys(111, "adjust environment for child") ;
+      pids[i] = child_spawn0(argvs[i][0], argvs[i], newenvp) ;
       if (!pids[i]) strerr_diefu2sys(111, "spawn ", argvs[i][0]) ;
     }
   }
@@ -37,13 +48,15 @@ static void action (unsigned int i, char const *const *envp)
 
 int main (int argc, char const **argv, char const *const *envp)
 {
-  tain_t tto ;
+  size_t envlen = env_len(envp) ;
+  iopause_fd x = { .events = IOPAUSE_READ } ;
+  sigset_t set ;
   int xfersigs = 0 ;
-  int argc1, spfd ;
+  unsigned int argc1 ;
   unsigned int i = 0 ;
   PROG = "trap" ;
+
   {
-    unsigned int t = 0 ;
     subgetopt_t l = SUBGETOPT_ZERO ;
     for (;;)
     {
@@ -52,110 +65,92 @@ int main (int argc, char const **argv, char const *const *envp)
       switch (opt)
       {
         case 'x' : xfersigs = 1 ; break ;
-        case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
         default : dieusage() ;
       }
     }
     argc -= l.ind ; argv += l.ind ;
-    if (t) tain_from_millisecs(&tto, t) ;
-    else tto = tain_infinite_relative ;
   }
-
   if (!argc) dieusage() ;
+
   argc1 = el_semicolon(argv) ;
   if (!argc1) strerr_dief1x(100, "empty block") ;
   if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
   if (argc1 + 1 == argc) dieusage() ;
   argv[argc1] = 0 ;
-  tain_now_set_stopwatch_g() ;
-  spfd = selfpipe_init() ;
-  if (spfd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
-
-  while (i < (unsigned int)argc1)
+  while (i < argc1)
   {
-    int argc2 ;
+    unsigned int argc2 ;
     int sig = 0 ;
-    if (!sig0_scan(argv[i], &sig) && strcasecmp(argv[i], "timeout"))
+    if (!sig0_scan(argv[i], &sig) && strcasecmp(argv[i], "default"))
       strerr_dief3x(100, "unrecognized", " directive: ", argv[i]) ;
     argc2 = el_semicolon(argv + ++i) ;
-    if (!argc2)
-      strerr_dief3x(100, "empty", " internal block for directive ", argv[i-1]) ;
     if (i + argc2 >= argc1)
       strerr_dief3x(100, "unterminated", " internal block for directive ", argv[i-1]) ;
     if (argvs[sig])
       strerr_dief3x(100, "duplicate", " directive: ", argv[i-1]) ;
-    if (sig && selfpipe_trap(sig) < 0)
-      strerr_diefu2sys(111, "trap ", argv[i-1]) ;
+    switch (sig)
+    {
+      case SIGCHLD : strerr_dief2x(100, "SIGCHLD", " cannot be trapped") ;
+      case SIGKILL : strerr_dief2x(100, "SIGKILL", " cannot be trapped") ;
+      case SIGSTOP : strerr_dief2x(100, "SIGSTOP", " cannot be trapped") ;
+      default :
+        argvs[sig] = argv + i ;
+        break ;
+    }
     argv[i + argc2] = 0 ;
-    argvs[sig] = argv + i ;
     i += argc2 + 1 ;
   }
-  if (!argvs[SIGCHLD] && selfpipe_trap(SIGCHLD) < 0)
-    strerr_diefu2sys(111, "trap ", "SIGCHLD") ;
+
+  if (argvs[0])
+    for (i = 1 ; i < SKALIBS_NSIG ; i++)
+      if (!argvs[i])
+        argvs[i] = argvs[0] ;
 
   if (xfersigs)
   {
-    sigset_t full ;
-    sigfillset(&full) ;
-    sigdelset(&full, SIGCHLD) ;
-    sigdelset(&full, SIGKILL) ;
-    sigdelset(&full, SIGSTOP) ;
+    sigfillset(&set) ;
+    sigdelset(&set, SIGCHLD) ;
+    sigdelset(&set, SIGKILL) ;
+    sigdelset(&set, SIGSTOP) ;
+  }
+  else
+  {
+    sigemptyset(&set) ;
     for (i = 1 ; i < SKALIBS_NSIG ; i++)
-      if (!argvs[i] && sigismember(&full, i) > 0 && selfpipe_trap(i) < 0)
-      {
-        char fmt[UINT_FMT] ;
-        fmt[uint_fmt(fmt, i)] = 0 ;
-        strerr_diefu4sys(111, "auto-", "trap ", "signal ", fmt) ;
-      }
+      if (argvs[i])
+        sigaddset(&set, i) ;
   }
 
+  x.fd = selfpipe_init() ;
+  if (x.fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
+  if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ;
+
   pids[SKALIBS_NSIG] = child_spawn0(argv[argc1 + 1], argv + argc1 + 1, envp) ;
   if (!pids[SKALIBS_NSIG]) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ;
 
+ loop:
+  if (iopause_g(&x, 1, 0) < 0) strerr_diefu1sys(111, "iopause") ;
+  for (;;)
   {
-    iopause_fd x = { .fd = spfd, .events = IOPAUSE_READ } ;
-    size_t envlen = env_len(envp) ;
-    char modif[2 + PID_FMT] = "!=" ;
-    size_t l = 2 + pid_fmt(modif + 2, pids[SKALIBS_NSIG]) ;
-    char const *newenvp[envlen + 2] ;
-    modif[l++] = 0 ;
-    if (!env_merge(newenvp, envlen + 2, envp, envlen, modif, l))
-      strerr_diefu1sys(111, "adjust environment") ;
-    for (;;)
+    int r = selfpipe_read() ;
+    switch (r)
     {
-      tain_t deadline ;
-      int r ;
-      tain_add_g(&deadline, &tto) ;
-      r = iopause_g(&x, 1, &deadline) ;
-      if (r < 0) strerr_diefu1sys(111, "iopause") ;
-      if (!r) action(0, newenvp) ;
-      else
-      {
-        int cont = 1 ;
-        while (cont)
+      case -1 : strerr_diefu1sys(111, "selfpipe_read") ;
+      case 0 : goto loop ;
+      case SIGCHLD :
+        for (;;)
         {
-          r = selfpipe_read() ;
-          switch (r)
-          {
-            case -1 : strerr_diefu1sys(111, "selfpipe_read") ;
-            case 0 : cont = 0 ; break ;
-            case SIGCHLD :
-              for (;;)
-              {
-                int wstat ;
-                ssize_t id = wait_pids_nohang(pids, SKALIBS_NSIG + 1, &wstat) ;
-                if (id < 0 && errno != ECHILD)
-                  strerr_diefu1sys(111, "wait") ;
-                if (id <= 0) break ;
-                pids[id - 1] = 0 ;
-                if (id == SKALIBS_NSIG + 1) return wait_estatus(wstat) ;
-              }
-              if (!argvs[SIGCHLD]) break ;
-            default :
-              action(r, newenvp) ;
-          }
+          int wstat ;
+          ssize_t id = wait_pids_nohang(pids, SKALIBS_NSIG + 1, &wstat) ;
+          if (id < 0 && errno != ECHILD)
+            strerr_diefu1sys(111, "wait") ;
+          if (id <= 0) break ;
+          pids[id - 1] = 0 ;
+          if (id == SKALIBS_NSIG + 1) return wait_estatus(wstat) ;
         }
-      }
+        break ;
+      default :
+        action(r, envp, envlen) ;
     }
   }
 }