From a5b7a319fb558f5df599de286318029d455ed193 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Sat, 6 Apr 2024 17:54:13 +0000 Subject: Prepare for 2.9.5.0; add ? support in backtick Signed-off-by: Laurent Bercot --- COPYING | 2 +- INSTALL | 2 +- NEWS | 3 +- doc/backtick.html | 21 +++++++++-- doc/index.html | 4 +- doc/upgrade.html | 6 ++- package/deps.mak | 7 ++-- package/info | 2 +- src/execline/backtick.c | 23 +++++++----- src/include/execline/execline.h | 1 + src/libexecline/deps-lib/execline | 1 + src/libexecline/el_modifs_and_exec.c | 72 ++++++++++++++++++++++++++++++++++++ 12 files changed, 119 insertions(+), 25 deletions(-) create mode 100644 src/libexecline/el_modifs_and_exec.c diff --git a/COPYING b/COPYING index 08c9298..2ea7ac0 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2011-2023 Laurent Bercot +Copyright (c) 2011-2024 Laurent Bercot Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/INSTALL b/INSTALL index d9bdcde..adaaf3d 100644 --- a/INSTALL +++ b/INSTALL @@ -6,7 +6,7 @@ Build Instructions - A POSIX-compliant C development environment - GNU make version 3.81 or later - - skalibs version 2.14.1.0 or later: https://skarnet.org/software/skalibs/ + - skalibs version 2.14.1.1 or later: https://skarnet.org/software/skalibs/ - Optional: nsss version 0.2.0.4 or later: https://skarnet.org/software/nsss/ This software will run on any operating system that implements diff --git a/NEWS b/NEWS index c481396..328c2d4 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,10 @@ Changelog for execline. -In 2.9.4.1 +In 2.9.5.0 ---------- - Bugfixes. + - backtick now sets ? when it can be nonzero. In 2.9.4.0 diff --git a/doc/backtick.html b/doc/backtick.html index 14cc031..38c02a2 100644 --- a/doc/backtick.html +++ b/doc/backtick.html @@ -49,10 +49,15 @@ output as a value.
  • -N : store prog1...'s output as is, including the last newline, if any.
  • -n : chomp an ending newline off prog1...'s output. This is the default.
  • -e : no autoimport. This is the default.
  • -
  • -E : autoimport. Instead of exec'ing into -prog2..., exec into importas -ui variable variable -prog2.... This substitutes variable into the command -line instead of putting it into the environment.
  • +
  • -E : autoimport. Before exec'ing into +prog2..., perform a +substitution +so that $? is replaced with prog1...'s exitcode (if +applicable, see below), and +${variable} is replaced with prog1...'s output, +instead of keeping the results in the environment. The variables will not +appear in the environment; if they preexisted in backtick's +environment, they will be removed.
  • @@ -76,5 +81,13 @@ the environment, and execution proceeds. is set to default, and execution proceeds. +

    + If the command line can keep running after prog1 crashes or exits +nonzero, i.e. if one of the -I, -x -or -D has been +given, then backtick also adds the ? variable to the +environment; it then contains an approximation +of prog1's exit code. +

    + diff --git a/doc/index.html b/doc/index.html index 0a226ab..73b7867 100644 --- a/doc/index.html +++ b/doc/index.html @@ -51,7 +51,7 @@ shell's syntax, and has no security issues.
  • A POSIX-compliant system with a standard C development environment
  • GNU make, version 3.81 or later.
  • skalibs version -2.14.1.0 or later. It's a build-time requirement. It's also a run-time +2.14.1.1 or later. It's a build-time requirement. It's also a run-time requirement if you link against the shared version of the skalibs library.
  • @@ -77,7 +77,7 @@ want nsswitch-like functionality:

    Download

      -
    • The current released version of execline is 2.9.4.1.
    • +
    • The current released version of execline is 2.9.5.0.
    • Alternatively, you can checkout a copy of the execline git repository: diff --git a/doc/upgrade.html b/doc/upgrade.html index 6511fe5..262c1e4 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -18,11 +18,13 @@

      What has changed in execline

      -

      in 2.9.4.1

      +

      in 2.9.5.0

      • skalibs -dependency bumped to 2.14.1.0.
      • +dependency bumped to 2.14.1.1. +
      • backtick now sets the ? +environment variable when it can be nonzero.

      in 2.9.4.0

      diff --git a/package/deps.mak b/package/deps.mak index c76a4cc..a8acd4d 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -57,6 +57,7 @@ src/libexecline/el_getstrict.o src/libexecline/el_getstrict.lo: src/libexecline/ src/libexecline/el_gspawn0.o src/libexecline/el_gspawn0.lo: src/libexecline/el_gspawn0.c src/include/execline/config.h src/include/execline/execline.h src/libexecline/el_modif_and_exec.o src/libexecline/el_modif_and_exec.lo: src/libexecline/el_modif_and_exec.c src/include/execline/config.h src/include/execline/execline.h src/libexecline/el_modif_and_spawn.o src/libexecline/el_modif_and_spawn.lo: src/libexecline/el_modif_and_spawn.c src/include/execline/config.h src/include/execline/execline.h +src/libexecline/el_modifs_and_exec.o src/libexecline/el_modifs_and_exec.lo: src/libexecline/el_modifs_and_exec.c src/include/execline/config.h src/include/execline/execline.h src/libexecline/el_parse.o src/libexecline/el_parse.lo: src/libexecline/el_parse.c src/include/execline/execline.h src/libexecline/el_parse_from_buffer.o src/libexecline/el_parse_from_buffer.lo: src/libexecline/el_parse_from_buffer.c src/include/execline/execline.h src/libexecline/el_parse_from_string.o src/libexecline/el_parse_from_string.lo: src/libexecline/el_parse_from_string.c src/include/execline/execline.h @@ -179,12 +180,12 @@ wait: src/execline/wait.o ${LIBEXECLINE} withstdinas: EXTRA_LIBS := -lskarnet withstdinas: src/execline/withstdinas.o ${LIBEXECLINE} ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) -libexecline.a.xyzzy: src/libexecline/el_execsequence.o src/libexecline/el_getstrict.o src/libexecline/el_modif_and_exec.o src/libexecline/el_modif_and_spawn.o src/libexecline/el_parse.o src/libexecline/el_parse_from_buffer.o src/libexecline/el_parse_from_string.o src/libexecline/el_popenv.o src/libexecline/el_pushenv.o src/libexecline/el_semicolon.o src/libexecline/el_spawn0.o src/libexecline/el_gspawn0.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_importas.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.a.xyzzy: src/libexecline/el_execsequence.o src/libexecline/el_getstrict.o src/libexecline/el_modif_and_exec.o src/libexecline/el_modif_and_spawn.o src/libexecline/el_modifs_and_exec.o src/libexecline/el_parse.o src/libexecline/el_parse_from_buffer.o src/libexecline/el_parse_from_string.o src/libexecline/el_popenv.o src/libexecline/el_pushenv.o src/libexecline/el_semicolon.o src/libexecline/el_spawn0.o src/libexecline/el_gspawn0.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_importas.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 else -libexecline.a.xyzzy: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.lo src/libexecline/el_modif_and_exec.lo src/libexecline/el_modif_and_spawn.lo src/libexecline/el_parse.lo src/libexecline/el_parse_from_buffer.lo src/libexecline/el_parse_from_string.lo src/libexecline/el_popenv.lo src/libexecline/el_pushenv.lo src/libexecline/el_semicolon.lo src/libexecline/el_spawn0.lo src/libexecline/el_gspawn0.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_importas.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.xyzzy: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.lo src/libexecline/el_modif_and_exec.lo src/libexecline/el_modif_and_spawn.lo src/libexecline/el_modifs_and_exec.lo src/libexecline/el_parse.lo src/libexecline/el_parse_from_buffer.lo src/libexecline/el_parse_from_string.lo src/libexecline/el_popenv.lo src/libexecline/el_pushenv.lo src/libexecline/el_semicolon.lo src/libexecline/el_spawn0.lo src/libexecline/el_gspawn0.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_importas.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 endif libexecline.so.xyzzy: EXTRA_LIBS := -lskarnet ${SPAWN_LIB} -libexecline.so.xyzzy: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.lo src/libexecline/el_modif_and_exec.lo src/libexecline/el_modif_and_spawn.lo src/libexecline/el_parse.lo src/libexecline/el_parse_from_buffer.lo src/libexecline/el_parse_from_string.lo src/libexecline/el_popenv.lo src/libexecline/el_pushenv.lo src/libexecline/el_semicolon.lo src/libexecline/el_spawn0.lo src/libexecline/el_gspawn0.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_importas.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.so.xyzzy: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.lo src/libexecline/el_modif_and_exec.lo src/libexecline/el_modif_and_spawn.lo src/libexecline/el_modifs_and_exec.lo src/libexecline/el_parse.lo src/libexecline/el_parse_from_buffer.lo src/libexecline/el_parse_from_string.lo src/libexecline/el_popenv.lo src/libexecline/el_pushenv.lo src/libexecline/el_semicolon.lo src/libexecline/el_spawn0.lo src/libexecline/el_gspawn0.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_importas.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 execline: EXTRA_LIBS := -lskarnet ${SPAWN_LIB} ${MAYBEPTHREAD_LIB} execline: src/multicall/execline.o ${LIBEXECLINE} ${LIBNSSS} INTERNAL_LIBS := diff --git a/package/info b/package/info index 1268414..6815b32 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=execline -version=2.9.4.1 +version=2.9.5.0 category=admin package_macro_name=EXECLINE 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 #include +#include #include #include #include @@ -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 + +#include +#include + +#include +#include + +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) ; +} -- cgit 1.4.1