diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2015-02-26 01:48:50 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2015-02-26 01:48:50 +0000 |
commit | 4d067b3020104a8b19a34fa4d3b6e5e8f3eb036a (patch) | |
tree | 5c5752681d5fef7837d22a5d8fb590d4b6003d1d | |
parent | e1fe79a9e705e3cab8f632cdbe8e1774cdef2761 (diff) | |
download | execline-4d067b3020104a8b19a34fa4d3b6e5e8f3eb036a.tar.gz execline-4d067b3020104a8b19a34fa4d3b6e5e8f3eb036a.tar.xz execline-4d067b3020104a8b19a34fa4d3b6e5e8f3eb036a.zip |
- added forstdin v2.1.1.0
- rewrote forbacktickx as a wrapper around forstdin - removed el_obsolescent - version: rc for 2.1.1.0
-rw-r--r-- | doc/forbacktickx.html | 5 | ||||
-rw-r--r-- | doc/forstdin.html | 78 | ||||
-rw-r--r-- | doc/index.html | 3 | ||||
-rw-r--r-- | doc/upgrade.html | 7 | ||||
-rw-r--r-- | package/deps.mak | 10 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | package/modes | 3 | ||||
-rw-r--r-- | package/targets.mak | 1 | ||||
-rw-r--r-- | src/execline/deps-exe/forbacktickx | 1 | ||||
-rw-r--r-- | src/execline/deps-exe/forstdin | 2 | ||||
-rw-r--r-- | src/execline/forbacktickx.c | 155 | ||||
-rw-r--r-- | src/execline/forstdin.c | 157 | ||||
-rw-r--r-- | src/include/execline/execline.h | 1 | ||||
-rw-r--r-- | src/libexecline/deps-lib/execline | 1 | ||||
-rw-r--r-- | src/libexecline/el_obsolescent.c | 10 |
15 files changed, 312 insertions, 124 deletions
diff --git a/doc/forbacktickx.html b/doc/forbacktickx.html index 0780f3d..979a483 100644 --- a/doc/forbacktickx.html +++ b/doc/forbacktickx.html @@ -76,7 +76,10 @@ split <em>x</em>. </li> <ul> <li> You can start <em>loop...</em> with "import -u <em>variable</em>" -to perform variable substitution. +to perform variable substitution. </li> + <li> forbacktickx is now implemented as a trivial wrapper around the +<a href="pipeline.html">pipeline</a> and +<a href="forstdin.html">forstdin</a> commands. </li> </ul> </body> diff --git a/doc/forstdin.html b/doc/forstdin.html new file mode 100644 index 0000000..e4c5534 --- /dev/null +++ b/doc/forstdin.html @@ -0,0 +1,78 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>execline: the forstdin command</title> + <meta name="Description" content="execline: the forstdin command" /> + <meta name="Keywords" content="execline command forstdin" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">execline</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>forstdin</tt> program </h1> + +<p> +<tt>forstdin</tt> uses its input as loop elements to +run another program. +</p> + +<h2> Interface </h2> + +<p> + In an <a href="execlineb.html">execlineb</a> script: +</p> + +<pre> + forstdin [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] [ -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> <em>loop...</em> +</pre> + +<ul> + <li> <tt>forstdin</tt> reads its standard input as it becomes available, +<a href="el_transform.html#split">splitting</a> it automatically. </li> + <li> For every argument <em>x</em> in the split output, +<tt>forstdin</tt> runs <em>loop...</em> as a child process, with +<em>variable</em>=<em>x</em> added to its environment. </li> + <li><tt>forstdin</tt> then exits 0. +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-p</tt> : parallel mode. Do not wait for a <em>loop...</em> +instance to finish before spawning the next one. <em>forbacktickx</em> will +still wait for all instances of <em>loop</em> to terminate before +exiting, though. </li> + <li> <tt>-0</tt> : accept null characters on its stdin, +using them as delimiters. If this option and a <tt>-d</tt> option are +used simultaneously, the rightmost one wins. </li> + <li> <tt>-o</tt> <em>okcodes</em> : <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>, +forstdin will run the following instances of the loop, but if the exit code is +not listed in <em>okcodes</em>, forstdin will exit immediately with an +<a href="exitcodes.html">approximation</a> of the same exit code. </li> + <li> <tt>-x</tt> <em>breakcodes</em> : like the previous +option, but with inverted meaning - the listed exit codes are codes +that will make forstdin break the loop and exit, and the unlisted exit +codes will make it keep looping. </li> + <li> Other options are used to <a href="el_transform.html">control +the substitution mechanism</a> for every <em>x</em>. Of course, you can't +split <em>x</em>. </li> +</ul> + +<h2> Notes </h2> + +<ul> + <li> You can start <em>loop...</em> with "import -u <em>variable</em>" +to perform variable substitution. </li> +</ul> + +</body> +</html> diff --git a/doc/index.html b/doc/index.html index 5b19477..bc2e020 100644 --- a/doc/index.html +++ b/doc/index.html @@ -66,7 +66,7 @@ library. </li> <h3> Download </h3> <ul> - <li> The current released version of execline is <a href="execline-2.1.0.0.tar.gz">2.1.0.0</a>. </li> + <li> The current released version of execline is <a href="execline-2.1.1.0.tar.gz">2.1.1.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> @@ -167,6 +167,7 @@ to your installation: the shebang lines for your system might be something like </p> <ul> <li><a href="forx.html">The <tt>forx</tt> program</a></li> +<li><a href="forstdin.html">The <tt>forstdin</tt> program</a></li> <li><a href="forbacktickx.html">The <tt>forbacktickx</tt> program</a></li> <li><a href="loopwhilex.html">The <tt>loopwhilex</tt> program</a></li> </ul> diff --git a/doc/upgrade.html b/doc/upgrade.html index b66a215..ce0e74f 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -17,6 +17,13 @@ <h1> What has changed in execline </h1> +<h2> in 2.1.1.0 </h2> + +<ul> + <li> <a href="forstdin.html">forstdin</a> added </li> + <li> forbacktickx rewritten as a wrapper around pipeline and forstdin </li> +</ul> + <h2> in 2.1.0.0 </h2> <ul> diff --git a/package/deps.mak b/package/deps.mak index 4bf3d89..5c77ee5 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -22,6 +22,7 @@ src/execline/fdreserve.o src/execline/fdreserve.lo: src/execline/fdreserve.c src/execline/fdswap.o src/execline/fdswap.lo: src/execline/fdswap.c src/execline/forbacktickx.o src/execline/forbacktickx.lo: src/execline/forbacktickx.c src/include/execline/config.h src/include/execline/execline.h src/execline/foreground.o src/execline/foreground.lo: src/execline/foreground.c src/include/execline/execline.h +src/execline/forstdin.o src/execline/forstdin.lo: src/execline/forstdin.c src/include/execline/config.h src/include/execline/execline.h src/execline/forx.o src/execline/forx.lo: src/execline/forx.c src/include/execline/config.h src/include/execline/execline.h src/execline/getpid.o src/execline/getpid.lo: src/execline/getpid.c src/execline/heredoc.o src/execline/heredoc.lo: src/execline/heredoc.c @@ -46,7 +47,6 @@ src/execline/unexport.o src/execline/unexport.lo: src/execline/unexport.c src/execline/wait.o src/execline/wait.lo: src/execline/wait.c src/include/execline/execline.h src/libexecline/el_execsequence.o src/libexecline/el_execsequence.lo: src/libexecline/el_execsequence.c src/include/execline/execline.h src/libexecline/el_getstrict.o src/libexecline/el_getstrict.lo: src/libexecline/el_getstrict.c src/include/execline/execline.h -src/libexecline/el_obsolescent.o src/libexecline/el_obsolescent.lo: src/libexecline/el_obsolescent.c src/include/execline/execline.h src/libexecline/el_popenv.o src/libexecline/el_popenv.lo: src/libexecline/el_popenv.c src/include/execline/execline.h src/libexecline/el_pushenv.o src/libexecline/el_pushenv.lo: src/libexecline/el_pushenv.c src/include/execline/execline.h src/libexecline/el_semicolon.o src/libexecline/el_semicolon.lo: src/libexecline/el_semicolon.c src/include/execline/execline.h @@ -103,9 +103,11 @@ fdreserve: src/execline/fdreserve.o -lskarnet fdswap: private EXTRA_LIBS := fdswap: src/execline/fdswap.o -lskarnet forbacktickx: private EXTRA_LIBS := -forbacktickx: src/execline/forbacktickx.o ${LIBEXECLINE} -lskarnet +forbacktickx: src/execline/forbacktickx.o -lskarnet foreground: private EXTRA_LIBS := foreground: src/execline/foreground.o ${LIBEXECLINE} -lskarnet +forstdin: private EXTRA_LIBS := +forstdin: src/execline/forstdin.o ${LIBEXECLINE} -lskarnet forx: private EXTRA_LIBS := forx: src/execline/forx.o ${LIBEXECLINE} -lskarnet getpid: private EXTRA_LIBS := @@ -150,5 +152,5 @@ unexport: private EXTRA_LIBS := unexport: src/execline/unexport.o -lskarnet wait: private EXTRA_LIBS := wait: src/execline/wait.o ${LIBEXECLINE} -lskarnet -libexecline.a: src/libexecline/el_execsequence.o src/libexecline/el_getstrict.o src/libexecline/el_obsolescent.o src/libexecline/el_popenv.o src/libexecline/el_pushenv.o src/libexecline/el_semicolon.o src/libexecline/el_spawn0.o src/libexecline/el_spawn1.o src/libexecline/el_substandrun.o src/libexecline/el_substandrun_str.o src/libexecline/el_substitute.o src/libexecline/el_transform.o src/libexecline/el_vardupl.o src/libexecline/exlsn_define.o src/libexecline/exlsn_elglob.o src/libexecline/exlsn_import.o src/libexecline/exlsn_multidefine.o src/libexecline/exlsn_exlp.o src/libexecline/exlsn_main.o src/libexecline/exlsn_free.o src/libexecline/exlp.o -libexecline.so: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.lo src/libexecline/el_obsolescent.lo src/libexecline/el_popenv.lo src/libexecline/el_pushenv.lo src/libexecline/el_semicolon.lo src/libexecline/el_spawn0.lo src/libexecline/el_spawn1.lo src/libexecline/el_substandrun.lo src/libexecline/el_substandrun_str.lo src/libexecline/el_substitute.lo src/libexecline/el_transform.lo src/libexecline/el_vardupl.lo src/libexecline/exlsn_define.lo src/libexecline/exlsn_elglob.lo src/libexecline/exlsn_import.lo src/libexecline/exlsn_multidefine.lo src/libexecline/exlsn_exlp.lo src/libexecline/exlsn_main.lo src/libexecline/exlsn_free.lo src/libexecline/exlp.lo +libexecline.a: src/libexecline/el_execsequence.o src/libexecline/el_getstrict.o src/libexecline/el_popenv.o src/libexecline/el_pushenv.o src/libexecline/el_semicolon.o src/libexecline/el_spawn0.o src/libexecline/el_spawn1.o src/libexecline/el_substandrun.o src/libexecline/el_substandrun_str.o src/libexecline/el_substitute.o src/libexecline/el_transform.o src/libexecline/el_vardupl.o src/libexecline/exlsn_define.o src/libexecline/exlsn_elglob.o src/libexecline/exlsn_import.o src/libexecline/exlsn_multidefine.o src/libexecline/exlsn_exlp.o src/libexecline/exlsn_main.o src/libexecline/exlsn_free.o src/libexecline/exlp.o +libexecline.so: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.lo src/libexecline/el_popenv.lo src/libexecline/el_pushenv.lo src/libexecline/el_semicolon.lo src/libexecline/el_spawn0.lo src/libexecline/el_spawn1.lo src/libexecline/el_substandrun.lo src/libexecline/el_substandrun_str.lo src/libexecline/el_substitute.lo src/libexecline/el_transform.lo src/libexecline/el_vardupl.lo src/libexecline/exlsn_define.lo src/libexecline/exlsn_elglob.lo src/libexecline/exlsn_import.lo src/libexecline/exlsn_multidefine.lo src/libexecline/exlsn_exlp.lo src/libexecline/exlsn_main.lo src/libexecline/exlsn_free.lo src/libexecline/exlp.lo diff --git a/package/info b/package/info index 54dedf4..f57cc18 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=execline -version=2.1.0.0 +version=2.1.1.0 category=admin package_macro_name=EXECLINE diff --git a/package/modes b/package/modes index 332d2c0..8519ef5 100644 --- a/package/modes +++ b/package/modes @@ -18,9 +18,10 @@ fdclose 0755 fdreserve 0755 fdmove 0755 fdswap 0755 -forx 0755 forbacktickx 0755 foreground 0755 +forstdin 0755 +forx 0755 getpid 0755 heredoc 0755 homeof 0755 diff --git a/package/targets.mak b/package/targets.mak index 2b1c0f4..9601f69 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -19,6 +19,7 @@ fdswap \ fdreserve \ forbacktickx \ foreground \ +forstdin \ forx \ getpid \ heredoc \ diff --git a/src/execline/deps-exe/forbacktickx b/src/execline/deps-exe/forbacktickx index 97021b5..e7187fe 100644 --- a/src/execline/deps-exe/forbacktickx +++ b/src/execline/deps-exe/forbacktickx @@ -1,2 +1 @@ -${LIBEXECLINE} -lskarnet diff --git a/src/execline/deps-exe/forstdin b/src/execline/deps-exe/forstdin new file mode 100644 index 0000000..97021b5 --- /dev/null +++ b/src/execline/deps-exe/forstdin @@ -0,0 +1,2 @@ +${LIBEXECLINE} +-lskarnet diff --git a/src/execline/forbacktickx.c b/src/execline/forbacktickx.c index 51f308e..0e58106 100644 --- a/src/execline/forbacktickx.c +++ b/src/execline/forbacktickx.c @@ -1,43 +1,23 @@ /* ISC license. */ -#include <sys/types.h> -#include <errno.h> -#include <skalibs/sgetopt.h> +#include <skalibs/ushort.h> #include <skalibs/bytestr.h> -#include <skalibs/buffer.h> -#include <skalibs/fmtscan.h> +#include <skalibs/sgetopt.h> #include <skalibs/strerr2.h> -#include <skalibs/stralloc.h> -#include <skalibs/genalloc.h> -#include <skalibs/env.h> #include <skalibs/djbunix.h> -#include <skalibs/skamisc.h> -#include <skalibs/netstring.h> -#include <skalibs/ushort.h> #include <execline/config.h> #include <execline/execline.h> #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 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 ; - return i < n ; -} +#define DELIM_DEFAULT " \n\r\t" int main (int argc, char const **argv, char const *const *envp) { - genalloc pids = GENALLOC_ZERO ; /* pid_t */ - char const *delim = " \n\r\t" ; - unsigned int delimlen = 4 ; - char const *x ; - pid_t pidw ; - int fd, argc1 ; - unsigned short okcodes[256] ; - unsigned int nbc = 0 ; - int crunch = 0, chomp = 0, not = 1 ; + char const *delim = DELIM_DEFAULT ; + char const *codes = 0 ; + int crunch = 0, chomp = 0, not = 1, par = 0 ; PROG = "forbacktickx" ; { subgetopt_t l = SUBGETOPT_ZERO ; @@ -48,100 +28,69 @@ int main (int argc, char const **argv, char const *const *envp) switch (opt) { case 'e' : break ; /* compat */ - case 'p' : - { - if (!genalloc_ready(pid_t, &pids, 2)) - strerr_diefu1sys(111, "genalloc_ready") ; - break ; - } + case 'p' : par = 1 ; break ; case 'n' : chomp = 1 ; break ; case 'C' : crunch = 1 ; break ; case 'c' : crunch = 0 ; break ; - case '0' : delim = "" ; delimlen = 1 ; break ; - case 'd' : delim = l.arg ; delimlen = str_len(delim) ; break ; + case '0' : delim = 0 ; break ; + case 'd' : delim = l.arg ; break ; case 'o' : - not = 0 ; + { + unsigned short okcodes[256] ; + unsigned int nbc ; if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ; + codes = l.arg ; + not = 0 ; break ; + } case 'x' : - not = 1 ; + { + unsigned short okcodes[256] ; + unsigned int nbc ; if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ; + codes = l.arg ; + not = 1 ; break ; + } default : dieusage() ; } } argc -= l.ind ; argv += l.ind ; } if (argc < 2) dieusage() ; - x = argv[0] ; if (!*x) dieusage() ; - argv++ ; argc-- ; - argc1 = el_semicolon(argv) ; - 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]) ; + if (!argv[0][0]) dieusage() ; + if (!argv[1][0]) strerr_dief1x(100, "empty block") ; { - 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 (;;) + unsigned int m = 0, i = 1 ; + char const *newargv[argc + 15] ; + newargv[m++] = EXECLINE_BINPREFIX "pipeline" ; + newargv[m++] = "--" ; + while (argv[i] && argv[i][0] != EXECLINE_BLOCK_END_CHAR && (!EXECLINE_BLOCK_END_CHAR || (argv[i][0] && argv[i][1]))) + newargv[m++] = argv[i++] ; + if (!argv[i]) strerr_dief1x(100, "unterminated block") ; + newargv[m++] = "" ; i++ ; + newargv[m++] = EXECLINE_BINPREFIX "unexport" ; + newargv[m++] = "!" ; + newargv[m++] = EXECLINE_BINPREFIX "forstdin" ; + if (par) newargv[m++] = "-p" ; + if (chomp) newargv[m++] = "-n" ; + if (crunch) newargv[m++] = "-C" ; + if (!delim) newargv[m++] = "-0" ; + else if (str_diff(delim, DELIM_DEFAULT)) { - 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) - { - 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) ; - } + newargv[m++] = "-d" ; + newargv[m++] = delim ; + } + if (codes) + { + newargv[m++] = not ? "-x" : "-o" ; + newargv[m++] = codes ; } - stralloc_free(&modif) ; + newargv[m++] = "--" ; + newargv[m++] = argv[0] ; + while (argv[i]) newargv[m++] = argv[i++] ; + newargv[m++] = 0 ; + pathexec_run(newargv[0], newargv, envp) ; + strerr_dieexec(111, newargv[0]) ; } - 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") ; - return 0 ; } diff --git a/src/execline/forstdin.c b/src/execline/forstdin.c new file mode 100644 index 0000000..1e9d5e6 --- /dev/null +++ b/src/execline/forstdin.c @@ -0,0 +1,157 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <errno.h> +#include <skalibs/sgetopt.h> +#include <skalibs/bytestr.h> +#include <skalibs/buffer.h> +#include <skalibs/fmtscan.h> +#include <skalibs/strerr2.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/env.h> +#include <skalibs/sig.h> +#include <skalibs/djbunix.h> +#include <skalibs/skamisc.h> +#include <skalibs/netstring.h> +#include <skalibs/ushort.h> +#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 dieusage() strerr_dieusage(100, USAGE) + +static genalloc pids = GENALLOC_ZERO ; /* pid_t */ + +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 ; + return i < n ; +} + +static void parallel_sigchld_handler (int sig) +{ + pid_t *tab = genalloc_s(pid_t, &pids) ; + unsigned int len = genalloc_len(pid_t, &pids) ; + int wstat ; + for (;;) + { + register int r = wait_pids_nohang(tab, len, &wstat) ; + if (r <= 0) break ; + tab[r-1] = tab[--len] ; + } + genalloc_setlen(pid_t, &pids, len) ; + (void)sig ; +} + +int main (int argc, char const **argv, char const *const *envp) +{ + char const *delim = " \n\r\t" ; + unsigned int delimlen = 4 ; + unsigned short okcodes[256] ; + unsigned int nbc = 0 ; + int crunch = 0, chomp = 0, not = 1 ; + PROG = "forstdin" ; + { + subgetopt_t l = SUBGETOPT_ZERO ; + for (;;) + { + register int opt = subgetopt_r(argc, argv, "pnCc0d:o:x:", &l) ; + if (opt == -1) break ; + switch (opt) + { + case 'p' : + { + if (!genalloc_ready(pid_t, &pids, 1)) + strerr_diefu1sys(111, "genalloc_ready") ; + break ; + } + case 'n' : chomp = 1 ; break ; + case 'C' : crunch = 1 ; break ; + 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' : + not = 1 ; + if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ; + break ; + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + } + if (argc < 2) dieusage() ; + { + stralloc modif = STRALLOC_ZERO ; + unsigned int envlen = env_len(envp) ; + unsigned int modifstart = str_len(argv[0])+1 ; + char const *newenv[envlen + 2] ; + if (!stralloc_ready(&modif, modifstart+1)) + strerr_diefu1sys(111, "stralloc_ready") ; + byte_copy(modif.s, modifstart-1, argv[0]) ; + modif.s[modifstart-1] = '=' ; + if (pids.s) + { + if (sig_catch(SIGCHLD, ¶llel_sigchld_handler) < 0) + strerr_diefu2sys(111, "install", " SIGCHLD handler") ; + } + for (;;) + { + pid_t pid ; + modif.len = modifstart ; + if (delimlen) + { + register int r = skagetlnsep(buffer_0, &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(buffer_0, &modif, &unread) <= 0) + { + if (netstring_okeof(buffer_0, 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[1], argv + 1, newenv) ; + if (!pid) strerr_diefu2sys(111, "spawn ", argv[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[1]) ; + if (not == isok(okcodes, nbc, wait_estatus(wstat))) + return wait_estatus(wstat) ; + } + } + stralloc_free(&modif) ; + } + if (pids.s) + { + if (sig_restore(SIGCHLD) < 0) + strerr_diefu2sys(111, "restore", " SIGCHLD handler") ; + if (!waitn(genalloc_s(pid_t, &pids), genalloc_len(pid_t, &pids))) + strerr_diefu1sys(111, "waitn") ; + } + return 0 ; +} diff --git a/src/include/execline/execline.h b/src/include/execline/execline.h index a5c16ad..1f1ec68 100644 --- a/src/include/execline/execline.h +++ b/src/include/execline/execline.h @@ -15,7 +15,6 @@ extern int el_vardupl (char const *, char const *, unsigned int) gccattr_pure ; extern unsigned int el_getstrict (void) gccattr_const ; -extern void el_obsolescent (void) ; /* Environment shifting */ diff --git a/src/libexecline/deps-lib/execline b/src/libexecline/deps-lib/execline index 69d483d..f3e4e49 100644 --- a/src/libexecline/deps-lib/execline +++ b/src/libexecline/deps-lib/execline @@ -1,6 +1,5 @@ el_execsequence.o el_getstrict.o -el_obsolescent.o el_popenv.o el_pushenv.o el_semicolon.o diff --git a/src/libexecline/el_obsolescent.c b/src/libexecline/el_obsolescent.c deleted file mode 100644 index 42b8a11..0000000 --- a/src/libexecline/el_obsolescent.c +++ /dev/null @@ -1,10 +0,0 @@ -/* ISC license. */ - -#include <skalibs/strerr2.h> -#include <execline/execline.h> - -void el_obsolescent (void) -{ - if (el_getstrict()) - strerr_warnw3x("this command is marked as obsolescent. Please update your script to use the ", PROG, "x command instead.") ; -} |