summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2015-02-19 04:13:20 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2015-02-19 04:13:20 +0000
commite1fe79a9e705e3cab8f632cdbe8e1774cdef2761 (patch)
treefcf1e195e4025ca14b7caea13c0da41fca15ea97 /src
parentc73a41da14650d93801a59b85757a73741be986f (diff)
downloadexecline-e1fe79a9e705e3cab8f632cdbe8e1774cdef2761.tar.gz
execline-e1fe79a9e705e3cab8f632cdbe8e1774cdef2761.tar.xz
execline-e1fe79a9e705e3cab8f632cdbe8e1774cdef2761.zip
- exit code overhaul: forx, forbacktickx, loopwhilex, if, ifelse, ifte, v2.1.0.0
ifthenelse
 - new -o option to forx, forbacktickx, loopwhilex
 - documentation updated
 - version: rc for 2.1.0.0
Diffstat (limited to 'src')
-rw-r--r--src/execline/forbacktickx.c128
-rw-r--r--src/execline/forx.c21
-rw-r--r--src/execline/if.c8
-rw-r--r--src/execline/ifelse.c6
-rw-r--r--src/execline/ifte.c6
-rw-r--r--src/execline/ifthenelse.c4
-rw-r--r--src/execline/loopwhilex.c25
7 files changed, 105 insertions, 93 deletions
diff --git a/src/execline/forbacktickx.c b/src/execline/forbacktickx.c
index f7b1460..51f308e 100644
--- a/src/execline/forbacktickx.c
+++ b/src/execline/forbacktickx.c
@@ -17,10 +17,10 @@
 #include <execline/config.h>
 #include <execline/execline.h>
 
-#define USAGE "forbacktickx [ -p | -x breakcode,breakcode,... ] [ -n ] [ -C | -c ] [ -0 | -d delim ] var { backtickcmd... } command..."
+#define USAGE "forbacktickx [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -n ] [ -C | -c ] [ -0 | -d delim ] var { backtickcmd... } command..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-static int isbreak (unsigned short *tab, unsigned int n, int code)
+static int isok (unsigned short *tab, unsigned int n, int code)
 {
   register unsigned int i = 0 ;
   for (; i < n ; i++) if ((unsigned short)code == tab[i]) break ;
@@ -33,16 +33,17 @@ int main (int argc, char const **argv, char const *const *envp)
   char const *delim = " \n\r\t" ;
   unsigned int delimlen = 4 ;
   char const *x ;
-  int argc1 ;
-  unsigned short breakcodes[256] ;
+  pid_t pidw ;
+  int fd, argc1 ;
+  unsigned short okcodes[256] ;
   unsigned int nbc = 0 ;
-  int crunch = 0, chomp = 0 ;
+  int crunch = 0, chomp = 0, not = 1 ;
   PROG = "forbacktickx" ;
   {
     subgetopt_t l = SUBGETOPT_ZERO ;
     for (;;)
     {
-      register int opt = subgetopt_r(argc, argv, "epnCc0d:x:", &l) ;
+      register int opt = subgetopt_r(argc, argv, "epnCc0d:o:x:", &l) ;
       if (opt == -1) break ;
       switch (opt)
       {
@@ -58,8 +59,13 @@ int main (int argc, char const **argv, char const *const *envp)
         case 'c' : crunch = 0 ; break ;
         case '0' : delim = "" ; delimlen = 1 ; break ;
         case 'd' : delim = l.arg ; delimlen = str_len(delim) ; break ;
+        case 'o' :
+          not = 0 ;
+          if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
+          break ;
         case 'x' :
-          if (!ushort_scanlist(breakcodes, 256, l.arg, &nbc)) dieusage() ;
+          not = 1 ;
+          if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
           break ;
         default : dieusage() ;
       }
@@ -73,73 +79,69 @@ int main (int argc, char const **argv, char const *const *envp)
   if (!argc1) strerr_dief1x(100, "empty block") ;
   if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
   argv[argc1] = 0 ;
+  pidw = el_spawn1(argv[0], argv, envp, &fd, 1) ;
+  if (!pidw) strerr_diefu2sys(111, "spawn ", argv[0]) ;
   {
-    int fd ;
-    pid_t pidw = el_spawn1(argv[0], argv, envp, &fd, 1) ;
-    if (!pidw) strerr_diefu2sys(111, "spawn ", argv[0]) ;
+    char buf[BUFFER_INSIZE] ;
+    buffer b = BUFFER_INIT(&buffer_read, fd, buf, BUFFER_INSIZE) ;
+    stralloc modif = STRALLOC_ZERO ;
+    unsigned int envlen = env_len(envp) ;
+    unsigned int modifstart = str_len(x)+1 ;
+    char const *newenv[envlen + 2] ;
+    if (!stralloc_ready(&modif, modifstart+1))
+      strerr_diefu1sys(111, "stralloc_ready") ;
+    byte_copy(modif.s, modifstart-1, x) ;
+    modif.s[modifstart-1] = '=' ;
+    for (;;)
     {
-      char buf[BUFFER_INSIZE] ;
-      buffer b = BUFFER_INIT(&buffer_read, fd, buf, BUFFER_INSIZE) ;
-      stralloc modif = STRALLOC_ZERO ;
-      unsigned int envlen = env_len(envp) ;
-      unsigned int modifstart = str_len(x)+1 ;
-      char const *newenv[envlen + 2] ;
-      if (!stralloc_ready(&modif, modifstart+1))
-        strerr_diefu1sys(111, "stralloc_ready") ;
-      byte_copy(modif.s, modifstart-1, x) ;
-      modif.s[modifstart-1] = '=' ;
-      for (;;)
+      pid_t pid ;
+      modif.len = modifstart ;
+      if (delimlen)
       {
-        pid_t pid ;
-        modif.len = modifstart ;
-        if (delimlen)
-        {
-          register int r = skagetlnsep(&b, &modif, delim, delimlen) ;
-          if (!r) break ;
-          else if (r < 0)
-          {
-            if (errno != EPIPE) strerr_diefu1sys(111, "skagetlnsep") ;
-            if (chomp) break ;
-          }
-          else modif.len-- ;
-          if ((modif.len == modifstart) && crunch) continue ;
-        }
-        else
-        {
-          unsigned int unread = 0 ;
-          if (netstring_get(&b, &modif, &unread) <= 0)
-          {
-            if (netstring_okeof(&b, unread)) break ;
-            else strerr_diefu1sys(111, "netstring_get") ;
-          }
-        }
-        if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_0") ;
-        if (!env_merge(newenv, envlen+2, envp, envlen, modif.s, modif.len))
-          strerr_diefu1sys(111, "merge environment") ;
-        pid = el_spawn0(argv[argc1 + 1], argv + argc1 + 1, newenv) ;
-        if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1+1]) ;
-        if (pids.s)
+        register int r = skagetlnsep(&b, &modif, delim, delimlen) ;
+        if (!r) break ;
+        else if (r < 0)
         {
-          if (!genalloc_append(pid_t, &pids, &pid))
-            strerr_diefu1sys(111, "genalloc_append") ;
+          if (errno != EPIPE) strerr_diefu1sys(111, "skagetlnsep") ;
+          if (chomp) break ;
         }
-        else
+        else modif.len-- ;
+        if ((modif.len == modifstart) && crunch) continue ;
+      }
+      else
+      {
+        unsigned int unread = 0 ;
+        if (netstring_get(&b, &modif, &unread) <= 0)
         {
-          int wstat ;
-          if (wait_pid(pid, &wstat) < 0)
-            strerr_diefu2sys(111, "wait for ", argv[argc1 + 1]) ;
-          if (isbreak(breakcodes, nbc, wait_status(wstat)))
-            return wait_status(wstat) ;
+          if (netstring_okeof(&b, unread)) break ;
+          else strerr_diefu1sys(111, "netstring_get") ;
         }
       }
-      stralloc_free(&modif) ;
+      if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_0") ;
+      if (!env_merge(newenv, envlen+2, envp, envlen, modif.s, modif.len))
+        strerr_diefu1sys(111, "merge environment") ;
+      pid = el_spawn0(argv[argc1 + 1], argv + argc1 + 1, newenv) ;
+      if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1+1]) ;
+      if (pids.s)
+      {
+        if (!genalloc_append(pid_t, &pids, &pid))
+          strerr_diefu1sys(111, "genalloc_append") ;
+      }
+      else
+      {
+        int wstat ;
+        if (wait_pid(pid, &wstat) < 0)
+          strerr_diefu2sys(111, "wait for ", argv[argc1 + 1]) ;
+        if (not == isok(okcodes, nbc, wait_estatus(wstat)))
+          return wait_estatus(wstat) ;
+      }
     }
-    fd_close(fd) ;
-    if (!genalloc_append(pid_t, &pids, &pidw))
-      strerr_diefu1sys(111, "genalloc_append") ;
+    stralloc_free(&modif) ;
   }
+  fd_close(fd) ;
+  if (!genalloc_append(pid_t, &pids, &pidw))
+    strerr_diefu1sys(111, "genalloc_append") ;
   if (!waitn(genalloc_s(pid_t, &pids), genalloc_len(pid_t, &pids)))
     strerr_diefu1sys(111, "waitn") ;
-  /* genalloc_free(pid_t, &pids) ; */
   return 0 ;
 }
diff --git a/src/execline/forx.c b/src/execline/forx.c
index 25d6d44..ef08ab2 100644
--- a/src/execline/forx.c
+++ b/src/execline/forx.c
@@ -11,10 +11,10 @@
 #include <execline/config.h>
 #include <execline/execline.h>
 
-#define USAGE "forx [ -p | -x breakcode,breakcode,... ] var { values... } command..."
+#define USAGE "forx [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] var { values... } command..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-static int isbreak (unsigned short *tab, unsigned int n, int code)
+static int isok (unsigned short *tab, unsigned int n, int code)
 {
   register unsigned int i = 0 ;
   for (; i < n ; i++) if ((unsigned short)code == tab[i]) break ;
@@ -25,22 +25,27 @@ int main (int argc, char const **argv, char const *const *envp)
 {
   char const *x ;
   int argc1 ;
-  unsigned short breakcodes[256] ;
+  unsigned short okcodes[256] ;
   unsigned int nbc = 0 ;
-  int flagpar = 0 ;
+  int flagpar = 0, not = 1 ;
   PROG = "forx" ;
   {
     subgetopt_t l = SUBGETOPT_ZERO ;
     for (;;)
     {
-      register int opt = subgetopt_r(argc, argv, "epx:", &l) ;
+      register int opt = subgetopt_r(argc, argv, "epo:x:", &l) ;
       if (opt == -1) break ;
       switch (opt)
       {
         case 'e' : break ; /* compat */
         case 'p' : flagpar = 1 ; break ;
+        case 'o' :
+          not = 0 ;
+          if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
+          break ;
         case 'x' :
-          if (!ushort_scanlist(breakcodes, 256, l.arg, &nbc)) dieusage() ;
+          not = 1 ;
+          if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
           break ;
         default : dieusage() ;
       }
@@ -80,8 +85,8 @@ int main (int argc, char const **argv, char const *const *envp)
         int wstat ;
         if (wait_pid(pid, &wstat) == -1)
           strerr_diefu2sys(111, "wait for ", argv[argc1+1]) ;
-        if (isbreak(breakcodes, nbc, wait_status(wstat)))
-          return wait_status(wstat) ;
+        if (not == isok(okcodes, nbc, wait_estatus(wstat)))
+          return wait_estatus(wstat) ;
       }
     }
     if (flagpar)
diff --git a/src/execline/if.c b/src/execline/if.c
index 9d0b4b4..410e118 100644
--- a/src/execline/if.c
+++ b/src/execline/if.c
@@ -15,9 +15,8 @@ int main (int argc, char const **argv, char const *const *envp)
 {
   int argc1, wstat ;
   pid_t pid ;
-  unsigned int not = 0 ;
+  int not = 0, flagnormalcrash = 0 ;
   unsigned short e = 1 ;
-  int flagnormalcrash = 0 ;
   PROG = "if" ;
   {
     subgetopt_t l = SUBGETOPT_ZERO ;
@@ -36,6 +35,7 @@ int main (int argc, char const **argv, char const *const *envp)
     }
     argc -= l.ind ; argv += l.ind ;
   }
+  if (e > 255) strerr_dief1x(100, "invalid exit code") ;
   argc1 = el_semicolon(argv) ;
   if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
   argv[argc1] = 0 ;
@@ -46,9 +46,9 @@ int main (int argc, char const **argv, char const *const *envp)
   {
     char fmt[UINT_FMT] ;
     fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
-    strerr_dief2x(1, "child crashed with signal ", fmt) ;
+    strerr_dief2x(128 + WTERMSIG(wstat), "child crashed with signal ", fmt) ;
   }
-  if (not == !wait_status(wstat)) return (int)e ;
+  if (not == !wait_estatus(wstat)) return e ;
   pathexec0_run(argv+argc1+1, envp) ;
   strerr_dieexec(111, argv[argc1+1]) ;
 }
diff --git a/src/execline/ifelse.c b/src/execline/ifelse.c
index 6d8801e..edf7cdf 100644
--- a/src/execline/ifelse.c
+++ b/src/execline/ifelse.c
@@ -45,10 +45,10 @@ int main (int argc, char const **argv, char const *const *envp)
   if (!flagnormalcrash && WIFSIGNALED(wstat))
   {
     char fmt[UINT_FMT] ;
-    fmt[uint_fmt(fmt, WSTOPSIG(wstat))] = 0 ;
-    strerr_dief2x(1, "child crashed with signal ", fmt) ;
+    fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
+    strerr_dief2x(128 + WTERMSIG(wstat), "child crashed with signal ", fmt) ;
   }
-  if (not != !wait_status(wstat)) argv[argc2] = 0 ; else argv += argc2+1 ;
+  if (not != !wait_estatus(wstat)) argv[argc2] = 0 ; else argv += argc2+1 ;
   pathexec0_run(argv, envp) ;
   strerr_dieexec(111, *argv) ;
 }
diff --git a/src/execline/ifte.c b/src/execline/ifte.c
index 3fe021e..eae19c6 100644
--- a/src/execline/ifte.c
+++ b/src/execline/ifte.c
@@ -46,14 +46,14 @@ int main (int argc, char const **argv, char const *const *envp)
   {
     char fmt[UINT_FMT] ;
     fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
-    strerr_dief2x(1, "child crashed with signal ", fmt) ;
+    strerr_dief2x(128 + WTERMSIG(wstat), "child crashed with signal ", fmt) ;
   }
-  if (not != !wait_status(wstat)) argv[argc1] = 0 ;
-  else
+  if (not == !wait_estatus(wstat))
   {
     argv += argc1 + 1 ;
     argv[argc2] = 0 ;
   }
+  else argv[argc1] = 0 ;
   pathexec0_run(argv, envp) ;
   strerr_dieexec(111, *argv) ;
 }
diff --git a/src/execline/ifthenelse.c b/src/execline/ifthenelse.c
index 9960222..2d71fec 100644
--- a/src/execline/ifthenelse.c
+++ b/src/execline/ifthenelse.c
@@ -52,9 +52,9 @@ int main (int argc, char const **argv, char const *const *envp)
     {
       char fmt[UINT_FMT] ;
       fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
-      strerr_dief2x(1, "child crashed with signal ", fmt) ;
+      strerr_dief2x(128 + WTERMSIG(wstat), "child crashed with signal ", fmt) ;
     }
-    if (wait_status(wstat))
+    if (wait_estatus(wstat))
     {
       argv += argc2 + 1 ;
       argc2 = argc3 ;
diff --git a/src/execline/loopwhilex.c b/src/execline/loopwhilex.c
index 5cb6a4e..d2955ad 100644
--- a/src/execline/loopwhilex.c
+++ b/src/execline/loopwhilex.c
@@ -8,10 +8,10 @@
 #include <skalibs/djbunix.h>
 #include <execline/execline.h>
 
-#define USAGE "loopwhilex [ -n ] [ -x exitcode,exitcode,... ] prog..."
+#define USAGE "loopwhilex [ -n ] [ -o okcode,okcode,... | -x exitcode,exitcode,... ] prog..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
-static int isbreak (unsigned short *tab, unsigned int n, int code)
+static int isok (unsigned short *tab, unsigned int n, int code)
 {
   register unsigned int i = 0 ;
   for (; i < n ; i++) if ((unsigned short)code == tab[i]) break ;
@@ -21,21 +21,26 @@ static int isbreak (unsigned short *tab, unsigned int n, int code)
 int main (int argc, char const *const *argv, char const *const *envp)
 {
   int wstat ;
-  int not = 0, cont = 1 ;
-  unsigned short breakcodes[256] ;
+  int not = 0, cont = 1, rev = 0 ;
+  unsigned short okcodes[256] ;
   unsigned int nbc = 0 ;
   PROG = "loopwhilex" ;
   {
     subgetopt_t l = SUBGETOPT_ZERO ;
     for (;;)
     {
-      register int opt = subgetopt_r(argc, argv, "nx:", &l) ;
+      register int opt = subgetopt_r(argc, argv, "no:x:", &l) ;
       if (opt == -1) break ;
       switch (opt)
       {
         case 'n' : not = 1 ; break ;
+        case 'o' :
+          rev = 0 ;
+          if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
+          break ;
         case 'x' :
-          if (!ushort_scanlist(breakcodes, 256, l.arg, &nbc)) dieusage() ;
+          rev = 1 ;
+          if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
           break ;
         default : dieusage() ;
       }
@@ -46,17 +51,17 @@ int main (int argc, char const *const *argv, char const *const *envp)
 
   if (!nbc)
   {
-    breakcodes[0] = 0 ;
+    okcodes[0] = 0 ;
     nbc = 1 ;
-    not = !not ;
   }
+  else if (rev) not = !not ;
 
   while (cont)
   {
     pid_t pid = el_spawn0(argv[0], argv, envp) ;
     if (!pid) strerr_diefu2sys(111, "spawn ", argv[0]) ;
     if (wait_pid(pid, &wstat) < 0) strerr_diefu1sys(111, "wait_pid") ;
-    cont = not == isbreak(breakcodes, nbc, wait_status(wstat)) ;
+    cont = not != isok(okcodes, nbc, wait_estatus(wstat)) ;
   }
-  return WIFSIGNALED(wstat) ? WTERMSIG(wstat) : 0 ;
+  return wait_estatus(wstat) ;
 }