summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/execline/forx.c32
1 files changed, 29 insertions, 3 deletions
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 ;
}