From 4d067b3020104a8b19a34fa4d3b6e5e8f3eb036a Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Thu, 26 Feb 2015 01:48:50 +0000 Subject: - added forstdin - rewrote forbacktickx as a wrapper around forstdin - removed el_obsolescent - version: rc for 2.1.1.0 --- src/execline/deps-exe/forbacktickx | 1 - src/execline/deps-exe/forstdin | 2 + src/execline/forbacktickx.c | 155 ++++++++++++------------------------ src/execline/forstdin.c | 157 +++++++++++++++++++++++++++++++++++++ src/include/execline/execline.h | 1 - src/libexecline/deps-lib/execline | 1 - src/libexecline/el_obsolescent.c | 10 --- 7 files changed, 211 insertions(+), 116 deletions(-) create mode 100644 src/execline/deps-exe/forstdin create mode 100644 src/execline/forstdin.c delete mode 100644 src/libexecline/el_obsolescent.c (limited to 'src') 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 -#include -#include +#include #include -#include -#include +#include #include -#include -#include -#include #include -#include -#include -#include #include #include #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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -#include - -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.") ; -} -- cgit v1.2.3