From e1fe79a9e705e3cab8f632cdbe8e1774cdef2761 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Thu, 19 Feb 2015 04:13:20 +0000 Subject: - exit code overhaul: forx, forbacktickx, loopwhilex, if, ifelse, ifte, ifthenelse - new -o option to forx, forbacktickx, loopwhilex - documentation updated - version: rc for 2.1.0.0 --- src/execline/forbacktickx.c | 128 ++++++++++++++++++++++---------------------- src/execline/forx.c | 21 +++++--- src/execline/if.c | 8 +-- src/execline/ifelse.c | 6 +-- src/execline/ifte.c | 6 +-- src/execline/ifthenelse.c | 4 +- src/execline/loopwhilex.c | 25 +++++---- 7 files changed, 105 insertions(+), 93 deletions(-) (limited to 'src') 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 #include -#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 #include -#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 #include -#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) ; } -- cgit v1.2.3