summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--COPYING2
-rw-r--r--doc/forx.html19
-rw-r--r--doc/index.html4
-rw-r--r--doc/upgrade.html6
-rw-r--r--package/info2
-rw-r--r--src/execline/forx.c32
7 files changed, 51 insertions, 15 deletions
diff --git a/AUTHORS b/AUTHORS
index 0ac10b7..b780d54 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,3 +15,4 @@ Thanks to:
   Vallo Kallaste <kalts@estpak.ee>
   Jorge Almeida <jalmeida@math.ist.utl.pt>
   Olivier Brunel <jjk@jjacky.com>
+  Luis Ressel <aranea@aixah.de>
diff --git a/COPYING b/COPYING
index a49b1ca..f496e31 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2015 Laurent Bercot <ska-skaware@skarnet.org>
+Copyright (c) 2011-2016 Laurent Bercot <ska-skaware@skarnet.org>
 
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
diff --git a/doc/forx.html b/doc/forx.html
index 8bc84b4..31804af 100644
--- a/doc/forx.html
+++ b/doc/forx.html
@@ -29,7 +29,7 @@
 </p>
 
 <pre>
-     forx [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] <em>variable</em> { <em>args...</em> } <em>loop...</em>
+     forx [ -p ] [ -o <em>okcodes</em> | -x <em>breakcodes</em> ] <em>variable</em> { <em>args...</em> } <em>loop...</em>
 </pre>
 
 <ul>
@@ -45,14 +45,9 @@ That block contains a list of <em>args</em>. </li>
 <h2> Options </h2>
 
 <ul>
- <li> <tt>-p</tt>&nbsp;: run in parallel. Do not wait for an instance of
-<em>loop...</em> to exit before spawning the next one. <tt>forx</tt>
-will still wait for all instances of <em>loop</em> to terminate before
-exiting, though. </li>
  <li> <tt>-o</tt>&nbsp;<em>okcodes</em>&nbsp;: <em>okcodes</em> must
-be a comma-separated list of exit codes. If the <tt>-p</tt> flag
-hasn't been given and <em>loop</em> exits with one of the codes in
-<em>okcodes</em>,
+be a comma-separated list of exit codes. If
+<em>loop</em> exits with one of the codes in <em>okcodes</em>,
 forx will run the following instances of the loop, but if the exit code is
 not listed in <em>okcodes</em>, forx will exit immediately with an
 <a href="exitcodes.html">approximation</a> of the same exit code. </li>
@@ -60,6 +55,14 @@ not listed in <em>okcodes</em>, forx will exit immediately with an
 option, but with inverted meaning - the listed exit codes are codes
 that will make forx break the loop and exit, and the unlisted exit
 codes will make it keep looping. </li>
+ <li> <tt>-p</tt>&nbsp;: run in parallel. Do not wait for an instance of
+<em>loop...</em> to exit before spawning the next one. <tt>forx</tt>
+will still wait for all instances of <em>loop</em> to terminate before
+exiting 0. If the <tt>-o</tt> option has been given, <tt>forx</tt>
+will exit 0 if all of the exit codes are in the values listed in the <em>okcodes</em>
+list, else it will exit 1. If the <tt>-x</tt> option has been given,
+<tt>forx</tt> will exit 0 if none of the exit codes are in the values
+listed in the <em>breakcodes</em> list, else it will exit 1. </li>
 </ul>
 
 <h2> Notes </h2>
diff --git a/doc/index.html b/doc/index.html
index ed7ad02..1e13da5 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -51,7 +51,7 @@ shell's syntax, and has no security issues.
  <li> A POSIX-compliant system with a standard C development environment </li>
  <li> GNU make, version 3.81 or later. </li>
  <li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> version
-2.3.8.3 or later. It's a build-time requirement. It's also a run-time
+2.3.10.0 or later. It's a build-time requirement. It's also a run-time
 requirement if you link against the shared version of the skalibs
 library. </li>
 </ul>
@@ -66,7 +66,7 @@ library. </li>
 <h3> Download </h3>
 
 <ul>
- <li> The current released version of execline is <a href="execline-2.1.4.5.tar.gz">2.1.4.5</a>. </li>
+ <li> The current released version of execline is <a href="execline-2.1.5.0.tar.gz">2.1.5.0</a>. </li>
  <li> Alternatively, you can checkout a copy of the execline git repository:
 <pre> git clone git://git.skarnet.org/execline </pre> </li>
 </ul>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 3d77796..7b51c28 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,6 +18,12 @@
 
 <h1> What has changed in execline </h1>
 
+<h2> in 2.1.5.0 </h2>
+
+<ul>
+ <li> skalibs dependency bumped to 2.3.10.0 </li>
+</ul>
+
 <h2> in 2.1.4.5 </h2>
 
 <ul>
diff --git a/package/info b/package/info
index 0ca6d04..08e732d 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
 package=execline
-version=2.1.4.5
+version=2.1.5.0
 category=admin
 package_macro_name=EXECLINE
diff --git a/src/execline/forx.c b/src/execline/forx.c
index ef08ab2..bae2f4b 100644
--- a/src/execline/forx.c
+++ b/src/execline/forx.c
@@ -11,16 +11,35 @@
 #include <execline/config.h>
 #include <execline/execline.h>
 
-#define USAGE "forx [ -p | -o okcode,okcode,... | -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 isok (unsigned short *tab, unsigned int n, int code)
+static int isok (unsigned short const *tab, unsigned int n, int code)
 {
   register unsigned int i = 0 ;
   for (; i < n ; i++) if ((unsigned short)code == tab[i]) break ;
   return i < n ;
 }
 
+static int waitn_code (unsigned short const *tab, unsigned int nbc, pid_t *pids, unsigned int n, int not)
+{
+  int ok = 1 ;
+  while (n)
+  {
+    int wstat ;
+    register unsigned int i = 0 ;
+    register pid_t pid = wait_nointr(&wstat) ;
+    if (pid < 0) return -1 ;
+    for (; i < n ; i++) if (pid == pids[i]) break ;
+    if (i < n)
+    {
+      if (not == isok(tab, nbc, wait_estatus(wstat))) ok = 0 ;
+      pids[i] = pids[--n] ;
+    }
+  }
+  return ok ;
+}
+
 int main (int argc, char const **argv, char const *const *envp)
 {
   char const *x ;
@@ -55,6 +74,8 @@ int main (int argc, char const **argv, char const *const *envp)
 
   if (argc < 2) dieusage() ;
   x = argv[0] ; if (!*x) dieusage() ;
+  if (x[0] == EXECLINE_BLOCK_QUOTE_CHAR)
+    strerr_warnw3x("variable ", x, " starts with a block quoting character") ;
   argv++ ; argc-- ;
   argc1 = el_semicolon(argv) ;
   if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
@@ -89,8 +110,13 @@ int main (int argc, char const **argv, char const *const *envp)
           return wait_estatus(wstat) ;
       }
     }
+
     if (flagpar)
-      if (!waitn(pids, argc1)) strerr_diefu1sys(111, "waitn") ;
+    {
+      register int r = waitn_code(okcodes, nbc, pids, argc1, not) ;
+      if (r < 0) strerr_diefu1sys(111, "waitn") ;
+      else if (!r) return 1 ;
+    }
   }
   return 0 ;
 }