summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/execline/backtick.c23
-rw-r--r--src/include/execline/execline.h1
-rw-r--r--src/libexecline/deps-lib/execline1
-rw-r--r--src/libexecline/el_modifs_and_exec.c72
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) ;
+}