diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2024-04-06 17:54:13 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2024-04-06 17:54:13 +0000 |
commit | a5b7a319fb558f5df599de286318029d455ed193 (patch) | |
tree | b468c6b2620613aa5f29d793feecb22c94dfedbf /src | |
parent | db852ecd93afc9f893886a132ee58b23579fc79d (diff) | |
download | execline-a5b7a319fb558f5df599de286318029d455ed193.tar.xz |
Prepare for 2.9.5.0; add ? support in backtick
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/execline/backtick.c | 23 | ||||
-rw-r--r-- | src/include/execline/execline.h | 1 | ||||
-rw-r--r-- | src/libexecline/deps-lib/execline | 1 | ||||
-rw-r--r-- | src/libexecline/el_modifs_and_exec.c | 72 |
4 files changed, 87 insertions, 10 deletions
diff --git a/src/execline/backtick.c b/src/execline/backtick.c index 06996bb..b921d7e 100644 --- a/src/execline/backtick.c +++ b/src/execline/backtick.c @@ -4,6 +4,7 @@ #include <sys/wait.h> #include <unistd.h> +#include <skalibs/types.h> #include <skalibs/sgetopt.h> #include <skalibs/strerr.h> #include <skalibs/stralloc.h> @@ -21,9 +22,10 @@ int main (int argc, char const **argv, char const *const *envp) subgetopt localopt = SUBGETOPT_ZERO ; int argc1, fdwstat ; stralloc value = STRALLOC_ZERO ; - char const *var ; - char const *val ; - int insist = 2, chomp = 1, doimport = 0 ; + char val1[UINT_FMT] ; + char const *var[2] = { [1] = "?" } ; + char const *val[2] = { [1] = val1 } ; + int insist = 2, chomp = 1, doimport = 0, allgood = 0 ; char const *def = 0 ; PROG = "backtick" ; for (;;) @@ -47,7 +49,7 @@ int main (int argc, char const **argv, char const *const *envp) if (argc < 2) dieusage() ; if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ; - argc-- ; var = *argv++ ; + argc-- ; var[0] = *argv++ ; argc1 = el_semicolon(argv) ; if (!argc1) strerr_dief1x(100, "empty block") ; if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ; @@ -62,12 +64,12 @@ int main (int argc, char const **argv, char const *const *envp) if (wait_pid(pid, &fdwstat) < 0) strerr_diefu1sys(111, "wait_pid") ; } - val = value.s ; + val[0] = value.s ; if (wait_status(fdwstat)) { if (insist >= 2) strerr_dief1x(wait_estatus(fdwstat), WIFSIGNALED(fdwstat) ? "child process crashed" : "child process exited non-zero") ; - else if (insist) val = def ; + else if (insist) val[0] = def ; } else if (strlen(value.s) < value.len - 1) { @@ -75,13 +77,14 @@ int main (int argc, char const **argv, char const *const *envp) strerr_dief1x(124, "child process output contained a null character") ; else if (insist) { - val = def ; + val[0] = def ; strerr_warnw1x("child process output contained a null character") ; } else value.len = strlen(value.s) + 1 ; } - else insist = 0 ; - if (!insist && chomp && (value.s[value.len - 2] == '\n')) + else allgood = 1 ; + if ((!insist || allgood) && chomp && (value.s[value.len - 2] == '\n')) value.s[--value.len - 1] = 0 ; - el_modif_and_exec(argv + argc1 + 1, var, val, doimport) ; + val1[uint_fmt(val1, wait_estatus(fdwstat))] = 0 ; + el_modifs_and_exec(argv + argc1 + 1, var, val, insist < 2 ? 2 : 1, doimport) ; } diff --git a/src/include/execline/execline.h b/src/include/execline/execline.h index a6fc114..8a204d8 100644 --- a/src/include/execline/execline.h +++ b/src/include/execline/execline.h @@ -82,5 +82,6 @@ extern int el_substitute (stralloc *, char const *, size_t, char const *, char c extern void el_modif_and_exec (char const *const *, char const *, char const *, int) gccattr_noreturn ; extern pid_t el_modif_and_spawn (char const *const *, char const *, char const *, int) ; +extern void el_modifs_and_exec (char const *const *, char const *const *, char const *const *, size_t, int) gccattr_noreturn ; #endif diff --git a/src/libexecline/deps-lib/execline b/src/libexecline/deps-lib/execline index a1f7c74..608fa7f 100644 --- a/src/libexecline/deps-lib/execline +++ b/src/libexecline/deps-lib/execline @@ -2,6 +2,7 @@ el_execsequence.o el_getstrict.o el_modif_and_exec.o el_modif_and_spawn.o +el_modifs_and_exec.o el_parse.o el_parse_from_buffer.o el_parse_from_string.o diff --git a/src/libexecline/el_modifs_and_exec.c b/src/libexecline/el_modifs_and_exec.c new file mode 100644 index 0000000..fe0117c --- /dev/null +++ b/src/libexecline/el_modifs_and_exec.c @@ -0,0 +1,72 @@ +/* ISC license. */ + +#include <string.h> + +#include <skalibs/env.h> +#include <skalibs/exec.h> + +#include <execline/config.h> +#include <execline/execline.h> + +void el_modifs_and_exec (char const *const *argv, char const *const *vars, char const *const *values, size_t n, int doimport) +{ + size_t pos = 0 ; + size_t yeslen = 0 ; + size_t yesn = 0 ; + size_t modiflen = 0 ; + for (size_t i = 0 ; i < n ; i++) + { + size_t len = strlen(vars[i]) + 1 ; + modiflen += len ; + if (values[i]) + { + yesn++ ; + yeslen += len ; + modiflen += 1 + strlen(values[i]) ; + } + } + + char modifs[modiflen ? modiflen : 1] ; + + for (size_t i = 0 ; i < n ; i++) + { + size_t len = strlen(vars[i]) ; + memcpy(modifs + pos, vars[i], len) ; + pos += len ; + if (values[i]) + { + modifs[pos++] = '=' ; + len = strlen(values[i]) ; + memcpy(modifs + pos, values[i], len) ; + pos += len ; + } + modifs[pos++] = 0 ; + } + + if (doimport && yesn) + { + size_t m = 0 ; + size_t ypos = 0 ; + char const *newargv[env_len(argv) + 3 + 5 * yesn] ; + char yesvars[yeslen ? yeslen : 1] ; + newargv[m++] = EXECLINE_BINPREFIX "multisubstitute" ; + for (size_t i = 0 ; i < n ; i++) if (values[i]) + { + size_t len = strlen(vars[i]) + 1 ; + char *p = yesvars + ypos ; + newargv[m++] = " importas" ; + newargv[m++] = " -ui" ; + newargv[m++] = " --" ; + newargv[m++] = p ; + newargv[m++] = p ; + yesvars[ypos++] = ' ' ; + memcpy(yesvars + ypos, vars[i], len) ; + ypos += len ; + } + newargv[m++] = "" ; + while (*argv) newargv[m++] = *argv++ ; + newargv[m++] = 0 ; + xmexec0_n(newargv, modifs, modiflen, n) ; + } + else xmexec0_n(argv, modifs, modiflen, n) ; +} |