summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2020-12-30 23:06:31 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2020-12-30 23:06:31 +0000
commitf021f61f10c566fcae2f77b1a4b095869076062b (patch)
treece84d18f30a4ebf5f6dc3b7ea1b009ba1a06ffcf /src
parentb6b71f9942fb5f209e183c2ca997f33071c38c71 (diff)
downloadexecline-f021f61f10c566fcae2f77b1a4b095869076062b.tar.xz
Add -E option for variable autoimport
Diffstat (limited to 'src')
-rw-r--r--src/execline/backtick.c82
-rw-r--r--src/execline/deps-exe/getcwd1
-rw-r--r--src/execline/deps-exe/getpid1
-rw-r--r--src/execline/deps-exe/withstdinas1
-rw-r--r--src/execline/forbacktickx.c11
-rw-r--r--src/execline/forstdin.c114
-rw-r--r--src/execline/forx.c39
-rw-r--r--src/execline/getcwd.c36
-rw-r--r--src/execline/getpid.c38
-rw-r--r--src/execline/withstdinas.c59
-rw-r--r--src/include/execline/execline.h7
-rw-r--r--src/libexecline/deps-lib/execline2
-rw-r--r--src/libexecline/el_modif_and_exec.c36
-rw-r--r--src/libexecline/el_modif_and_spawn.c39
-rw-r--r--src/libexecline/el_spawn0.c1
15 files changed, 268 insertions, 199 deletions
diff --git a/src/execline/backtick.c b/src/execline/backtick.c
index fa7403f..9394456 100644
--- a/src/execline/backtick.c
+++ b/src/execline/backtick.c
@@ -12,22 +12,22 @@
#include <execline/execline.h>
-#define USAGE "backtick [ -i | -I | -D default ] [ -N | -n ] var { prog... } remainder..."
+#define USAGE "backtick [ -i | -I | -D default ] [ -N | -n ] [ -E | -e ] var { prog... } remainder..."
#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const **argv, char const *const *envp)
{
subgetopt_t localopt = SUBGETOPT_ZERO ;
- pid_t pid ;
int argc1, fdwstat ;
- stralloc modif = STRALLOC_ZERO ;
- size_t modifstart ;
- int insist = 0, chomp = 1 ;
+ stralloc value = STRALLOC_ZERO ;
+ char const *var ;
+ char const *val ;
+ int insist = 0, chomp = 1, doimport = 0 ;
char const *def = 0 ;
PROG = "backtick" ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "iINnD:", &localopt) ;
+ int opt = subgetopt_r(argc, argv, "iINnD:Ee", &localopt) ;
if (opt < 0) break ;
switch (opt)
{
@@ -36,69 +36,51 @@ int main (int argc, char const **argv, char const *const *envp)
case 'N' : chomp = 0 ; break ;
case 'n' : chomp = 1 ; break ;
case 'D' : def = localopt.arg ; break ;
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
default : dieusage() ;
}
}
argc -= localopt.ind ; argv += localopt.ind ;
if (argc < 2) dieusage() ;
- if (!*argv[0]) strerr_dief1x(100, "empty variable not accepted") ;
- if (!stralloc_cats(&modif, argv[0]) || !stralloc_catb(&modif, "=", 1))
- strerr_diefu1sys(111, "stralloc_catb") ;
- modifstart = modif.len ;
- argc-- ; argv++ ;
+ if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
+ argc-- ; var = *argv++ ;
argc1 = el_semicolon(argv) ;
if (!argc1) strerr_dief1x(100, "empty block") ;
if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
-
argv[argc1] = 0 ;
- pid = child_spawn1_pipe(argv[0], argv, envp, &fdwstat, 1) ;
- if (!pid) strerr_diefu2sys(111, "spawn ", argv[0]) ;
- if (!slurp(&modif, fdwstat)) strerr_diefu1sys(111, "slurp") ;
- close(fdwstat) ;
- if (wait_pid(pid, &fdwstat) < 0) strerr_diefu1sys(111, "wait_pid") ;
+ {
+ pid_t pid = child_spawn1_pipe(argv[0], argv, envp, &fdwstat, 1) ;
+ if (!pid) strerr_diefu2sys(111, "spawn ", argv[0]) ;
+ if (!slurp(&value, fdwstat) || !stralloc_0(&value))
+ strerr_diefu1sys(111, "slurp") ;
+ close(fdwstat) ;
+ if (wait_pid(pid, &fdwstat) < 0) strerr_diefu1sys(111, "wait_pid") ;
+ }
+
+ val = value.s ;
if (wait_status(fdwstat))
{
if (insist >= 2)
if (WIFSIGNALED(fdwstat)) strerr_dief1x(111, "child process crashed") ;
else strerr_dief1x(WEXITSTATUS(fdwstat), "child process exited non-zero") ;
- else if (insist)
- {
- modif.len = modifstart - 1 ;
- chomp = 0 ;
- }
- else if (def)
- {
- modif.len = modifstart ;
- if (!stralloc_cats(&modif, def)) strerr_diefu1sys(111, "stralloc_catb") ;
- }
+ else if (insist) val = 0 ;
+ else if (def) val = def ;
}
- if (argc1 == argc - 1) return 0 ;
- if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_catb") ;
+ else if (strlen(value.s) < value.len - 1)
{
- size_t reallen = strlen(modif.s) ;
- if (reallen < modif.len - 1)
+ if (insist >= 2)
+ strerr_dief1x(1, "child process output contained a null character") ;
+ else if (insist) val = 0 ;
+ else if (def)
{
- if (insist >= 2)
- strerr_dief1x(1, "child process output contained a null character") ;
- else if (insist)
- {
- modif.len = modifstart ;
- modif.s[modif.len - 1] = 0 ;
- chomp = 0 ;
- }
- else if (def)
- {
- modif.len = modifstart ;
- if (!stralloc_catb(&modif, def, strlen(def)+1))
- strerr_diefu1sys(111, "stralloc_catb") ;
- strerr_warnw2x("child process output contained a null character", " - using default instead") ;
- }
- else modif.len = reallen + 1 ;
+ val = def ;
+ strerr_warnw2x("child process output contained a null character", " - using default instead") ;
}
- if (chomp && (modif.s[modif.len - 2] == '\n'))
- modif.s[--modif.len - 1] = 0 ;
}
- xmexec_en(argv + argc1 + 1, envp, modif.s, modif.len, 1) ;
+ else if (chomp && (value.s[value.len - 2] == '\n'))
+ value.s[--value.len - 1] = 0 ;
+ el_modif_and_exec(argv + argc1 + 1, var, val, doimport) ;
}
diff --git a/src/execline/deps-exe/getcwd b/src/execline/deps-exe/getcwd
index e7187fe..97021b5 100644
--- a/src/execline/deps-exe/getcwd
+++ b/src/execline/deps-exe/getcwd
@@ -1 +1,2 @@
+${LIBEXECLINE}
-lskarnet
diff --git a/src/execline/deps-exe/getpid b/src/execline/deps-exe/getpid
index e7187fe..97021b5 100644
--- a/src/execline/deps-exe/getpid
+++ b/src/execline/deps-exe/getpid
@@ -1 +1,2 @@
+${LIBEXECLINE}
-lskarnet
diff --git a/src/execline/deps-exe/withstdinas b/src/execline/deps-exe/withstdinas
index e7187fe..97021b5 100644
--- a/src/execline/deps-exe/withstdinas
+++ b/src/execline/deps-exe/withstdinas
@@ -1 +1,2 @@
+${LIBEXECLINE}
-lskarnet
diff --git a/src/execline/forbacktickx.c b/src/execline/forbacktickx.c
index 1f3a0f1..2fc8bb8 100644
--- a/src/execline/forbacktickx.c
+++ b/src/execline/forbacktickx.c
@@ -12,20 +12,20 @@
#include <execline/config.h>
#include <execline/execline.h>
-#define USAGE "forbacktickx [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var { backtickcmd... } command..."
+#define USAGE "forbacktickx [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -E | -e ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var { backtickcmd... } command..."
#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const *const *argv)
{
char const *delim = "\n" ;
char const *codes = 0 ;
- int crunch = 0, chomp = 1, not = 1, par = 0 ;
+ int crunch = 0, chomp = 1, not = 1, par = 0, doimport = 0 ;
PROG = "forbacktickx" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "pNnCc0d:o:x:", &l) ;
+ int opt = subgetopt_r(argc, argv, "pNnCc0d:o:x:Ee", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -54,6 +54,8 @@ int main (int argc, char const *const *argv)
not = 1 ;
break ;
}
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
default : dieusage() ;
}
}
@@ -65,7 +67,7 @@ int main (int argc, char const *const *argv)
{
unsigned int m = 0, i = 1 ;
int fd = dup(0) ;
- char const *newargv[argc + 18] ;
+ char const *newargv[argc + 19] ;
char fmt[UINT_FMT] ;
if (fd < 0)
{
@@ -81,6 +83,7 @@ int main (int argc, char const *const *argv)
newargv[m++] = EXECLINE_BINPREFIX "unexport" ;
newargv[m++] = "!" ;
newargv[m++] = EXECLINE_BINPREFIX "forstdin" ;
+ newargv[m++] = doimport ? "-E" : "-e" ;
if (par) newargv[m++] = "-p" ;
newargv[m++] = chomp ? "-n" : "-N" ;
if (crunch) newargv[m++] = "-C" ;
diff --git a/src/execline/forstdin.c b/src/execline/forstdin.c
index 336aaa4..bacb1ae 100644
--- a/src/execline/forstdin.c
+++ b/src/execline/forstdin.c
@@ -9,16 +9,14 @@
#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 <execline/config.h>
#include <execline/execline.h>
-#define USAGE "forstdin [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var command..."
+#define USAGE "forstdin [ -E | -e ] [ -p | -o okcode,okcode,... | -x breakcode,breakcode,... ] [ -N | -n ] [ -C | -c ] [ -0 | -d delim ] var command..."
#define dieusage() strerr_dieusage(100, USAGE)
static genalloc pids = GENALLOC_ZERO ; /* pid_t */
@@ -45,19 +43,20 @@ static void parallel_sigchld_handler (int sig)
(void)sig ;
}
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
{
+ stralloc value = STRALLOC_ZERO ;
char const *delim = "\n" ;
size_t delimlen = 1 ;
size_t nbc = 0 ;
unsigned short okcodes[256] ;
- int crunch = 0, chomp = 1, not = 1, eofcode = 1 ;
+ int crunch = 0, chomp = 1, not = 1, eofcode = 1, doimport = 0 ;
PROG = "forstdin" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "pNnCc0d:o:x:", &l) ;
+ int opt = subgetopt_r(argc, argv, "pNnCc0d:o:x:Ee", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -81,81 +80,74 @@ int main (int argc, char const **argv, char const *const *envp)
not = 1 ;
if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
break ;
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
default : dieusage() ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (argc < 2) dieusage() ;
+ if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
+
+ if (pids.s)
{
- stralloc modif = STRALLOC_ZERO ;
- size_t envlen = env_len(envp) ;
- size_t modifstart = strlen(argv[0]) + 1 ;
- char const *newenv[envlen + 2] ;
- if (!stralloc_ready(&modif, modifstart+1))
- strerr_diefu1sys(111, "stralloc_ready") ;
- memcpy(modif.s, argv[0], modifstart - 1) ;
- modif.s[modifstart-1] = '=' ;
- if (pids.s)
- {
- if (sig_catch(SIGCHLD, &parallel_sigchld_handler) < 0)
- strerr_diefu1sys(111, "install SIGCHLD handler") ;
- }
- for (;;)
+ if (sig_catch(SIGCHLD, &parallel_sigchld_handler) < 0)
+ strerr_diefu1sys(111, "install SIGCHLD handler") ;
+ }
+ for (;;)
+ {
+ pid_t pid ;
+ value.len = 0 ;
+ if (delimlen)
{
- pid_t pid ;
- modif.len = modifstart ;
- if (delimlen)
- {
- 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 ;
- }
- if (crunch && modif.len == modifstart + 1) continue ;
- if (chomp) modif.len-- ;
- }
- else
+ int r = skagetlnsep(buffer_0, &value, delim, delimlen) ;
+ if (!r) break ;
+ else if (r < 0)
{
- size_t unread = 0 ;
- if (netstring_get(buffer_0, &modif, &unread) <= 0)
- {
- if (netstring_okeof(buffer_0, unread)) break ;
- else strerr_diefu1sys(111, "netstring_get") ;
- }
- }
- eofcode = 0 ;
- if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_0") ;
- if (!env_mergen(newenv, envlen+2, envp, envlen, modif.s, modif.len, 1))
- strerr_diefu1sys(111, "merge environment") ;
- if (pids.s) sig_block(SIGCHLD) ;
- 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") ;
- sig_unblock(SIGCHLD) ;
+ if (errno != EPIPE) strerr_diefu1sys(111, "skagetlnsep") ;
+ if (chomp) break ;
}
- else
+ if (crunch && value.len == 1) continue ;
+ if (chomp) value.len-- ;
+ }
+ else
+ {
+ size_t unread = 0 ;
+ if (netstring_get(buffer_0, &value, &unread) <= 0)
{
- 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) ;
+ if (netstring_okeof(buffer_0, unread)) break ;
+ else strerr_diefu1sys(111, "netstring_get") ;
}
}
- stralloc_free(&modif) ;
+ eofcode = 0 ;
+ if (!stralloc_0(&value)) strerr_diefu1sys(111, "stralloc_0") ;
+ if (pids.s) sig_block(SIGCHLD) ;
+ pid = el_modif_and_spawn(argv + 1, argv[0], value.s, doimport) ;
+ if (!pid) strerr_diefu2sys(111, "spawn ", argv[1]) ;
+ if (pids.s)
+ {
+ if (!genalloc_append(pid_t, &pids, &pid))
+ strerr_diefu1sys(111, "genalloc_append") ;
+ sig_unblock(SIGCHLD) ;
+ }
+ 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) ;
+ }
}
if (pids.s)
+ {
for (;;)
{
sig_block(SIGCHLD) ;
if (!pids.len) break ;
sig_pause() ;
}
+ }
return eofcode ;
}
diff --git a/src/execline/forx.c b/src/execline/forx.c
index be03794..8e6659b 100644
--- a/src/execline/forx.c
+++ b/src/execline/forx.c
@@ -13,7 +13,7 @@
#include <execline/config.h>
#include <execline/execline.h>
-#define USAGE "forx [ -p ] [ -o okcode,okcode,... | -x breakcode,breakcode,... ] var { values... } command..."
+#define USAGE "forx [ -E | -e ] [ -p ] [ -o okcode,okcode,... | -x breakcode,breakcode,... ] var { values... } command..."
#define dieusage() strerr_dieusage(100, USAGE)
static int isok (unsigned short const *tab, unsigned int n, int code)
@@ -42,19 +42,19 @@ static int waitn_code (unsigned short const *tab, unsigned int nbc, pid_t *pids,
return ok ;
}
-int main (int argc, char const **argv, char const *const *envp)
+int main (int argc, char const **argv)
{
- char const *x ;
- int argc1 ;
+ char const *var ;
unsigned short okcodes[256] ;
size_t nbc = 0 ;
- int flagpar = 0, not = 1 ;
+ int flagpar = 0, not = 1, doimport = 0 ;
+ unsigned int argc1 ;
PROG = "forx" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "po:x:", &l) ;
+ int opt = subgetopt_r(argc, argv, "po:x:Ee", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -67,6 +67,8 @@ int main (int argc, char const **argv, char const *const *envp)
not = 1 ;
if (!ushort_scanlist(okcodes, 256, l.arg, &nbc)) dieusage() ;
break ;
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
default : dieusage() ;
}
}
@@ -74,32 +76,17 @@ int main (int argc, char const **argv, char const *const *envp)
}
if (argc < 2) dieusage() ;
- x = argv[0] ; if (!*x) dieusage() ;
- if (x[0] == EXECLINE_BLOCK_QUOTE_CHAR)
- strerr_warnw3x("variable ", x, " starts with a block quoting character") ;
- argv++ ; argc-- ;
+ if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
+ var = *argv++ ; argc-- ;
argc1 = el_semicolon(argv) ;
if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
if (!argc1 || (argc1 + 1 == argc)) return 0 ;
+
{
- size_t envlen = env_len(envp) ;
- size_t varlen = strlen(x) ;
- unsigned int i = 0 ;
pid_t pids[flagpar ? argc1 : 1] ;
- char const *newenv[envlen + 2] ;
-
- for (; i < (unsigned int)argc1 ; i++)
+ for (unsigned int i = 0 ; i < argc1 ; i++)
{
- pid_t pid ;
- size_t vallen = strlen(argv[i]) ;
- char modif[varlen + vallen + 2] ;
- memcpy(modif, x, varlen) ;
- modif[varlen] = '=' ;
- memcpy(modif + varlen + 1, argv[i], vallen) ;
- modif[varlen + vallen + 1] = 0 ;
- if (!env_mergen(newenv, envlen + 2, envp, envlen, modif, varlen + vallen + 2, 1))
- strerr_diefu1sys(111, "build new environment") ;
- pid = el_spawn0(argv[argc1+1], argv + argc1 + 1, newenv) ;
+ pid_t pid = el_modif_and_spawn(argv + argc1 + 1, var, argv[i], doimport) ;
if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1+1]) ;
if (flagpar) pids[i] = pid ;
else
diff --git a/src/execline/getcwd.c b/src/execline/getcwd.c
index d41bd5a..2a82924 100644
--- a/src/execline/getcwd.c
+++ b/src/execline/getcwd.c
@@ -2,23 +2,39 @@
#include <string.h>
+#include <skalibs/sgetopt.h>
#include <skalibs/strerr2.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
-#include <skalibs/exec.h>
-#define USAGE "getcwd variable prog..."
+#include <execline/execline.h>
+
+#define USAGE "getcwd [ -E | -e ] variable prog..."
+#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const *const *argv)
{
+ int doimport = 0 ;
stralloc sa = STRALLOC_ZERO ;
PROG = "getcwd" ;
- if (argc < 3) strerr_dieusage(100, USAGE) ;
- if (strchr(argv[1], '='))
- strerr_dief2x(100, "invalid variable name: ", argv[1]) ;
- if (!stralloc_cats(&sa, argv[1]) || !stralloc_catb(&sa, "=", 1))
- strerr_diefu1sys(111, "stralloc_catb") ;
- if (sagetcwd(&sa) < 0) strerr_diefu1sys(111, "getcwd") ;
- if (!stralloc_0(&sa)) strerr_diefu1sys(111, "stralloc_catb") ;
- xmexec_n(argv + 2, sa.s, sa.len, 1) ;
+ {
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ int opt = subgetopt_r(argc, argv, "Ee", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ }
+ if (argc < 2) dieusage() ;
+ if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
+
+ if (sagetcwd(&sa) < 0 || !stralloc_0(&sa)) strerr_diefu1sys(111, "getcwd") ;
+ el_modif_and_exec(argv + 1, argv[0], sa.s, doimport) ;
}
diff --git a/src/execline/getpid.c b/src/execline/getpid.c
index 06c4aaf..64866de 100644
--- a/src/execline/getpid.c
+++ b/src/execline/getpid.c
@@ -4,25 +4,37 @@
#include <unistd.h>
#include <skalibs/types.h>
+#include <skalibs/sgetopt.h>
#include <skalibs/strerr2.h>
-#include <skalibs/exec.h>
-#define USAGE "getpid variable prog..."
+#include <execline/execline.h>
+
+#define USAGE "getpid [ -E | -e ] variable prog..."
+#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const *const *argv)
{
- size_t len ;
+ int doimport = 0 ;
+ char fmt[PID_FMT] ;
PROG = "getpid" ;
- if (argc < 3) strerr_dieusage(100, USAGE) ;
- len = strlen(argv[1]) ;
- if (memchr(argv[1], '=', len))
- strerr_dief2x(100, "invalid variable name: ", argv[1]) ;
{
- size_t i = len+1 ;
- char fmt[PID_FMT + len + 2] ;
- memcpy(fmt, argv[1], len) ;
- fmt[len] = '=' ;
- i += pid_fmt(fmt+i, getpid()) ; fmt[i++] = 0 ;
- xmexec_n(argv+2, fmt, i, 1) ;
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ int opt = subgetopt_r(argc, argv, "Ee", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
}
+ if (argc < 2) dieusage() ;
+ if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
+
+ fmt[pid_fmt(fmt, getpid())] = 0 ;
+ el_modif_and_exec(argv + 1, argv[0], fmt, doimport) ;
}
diff --git a/src/execline/withstdinas.c b/src/execline/withstdinas.c
index 467b68b..cd025bf 100644
--- a/src/execline/withstdinas.c
+++ b/src/execline/withstdinas.c
@@ -6,22 +6,23 @@
#include <skalibs/strerr2.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
-#include <skalibs/exec.h>
-#define USAGE "withstdinas [ -i | -I | -D default ] [ -N | -n ] var remainder..."
+#include <execline/execline.h>
+
+#define USAGE "withstdinas [ -i | -I | -D default ] [ -N | -n ] [ -E | -e ] var remainder..."
#define dieusage() strerr_dieusage(100, USAGE)
-int main (int argc, char const **argv)
+int main (int argc, char const *const *argv)
{
subgetopt_t localopt = SUBGETOPT_ZERO ;
- stralloc modif = STRALLOC_ZERO ;
- size_t modifstart ;
- int insist = 0, chomp = 1 ;
+ stralloc value = STRALLOC_ZERO ;
+ int insist = 0, chomp = 1, doimport = 0 ;
char const *def = 0 ;
+ char const *val ;
PROG = "withstdinas" ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "iINnD:", &localopt) ;
+ int opt = subgetopt_r(argc, argv, "iINnD:Ee", &localopt) ;
if (opt < 0) break ;
switch (opt)
{
@@ -30,41 +31,29 @@ int main (int argc, char const **argv)
case 'N' : chomp = 0 ; break ;
case 'n' : chomp = 1 ; break ;
case 'D' : def = localopt.arg ; break ;
+ case 'E' : doimport = 1 ; break ;
+ case 'e' : doimport = 0 ; break ;
default : dieusage() ;
}
}
argc -= localopt.ind ; argv += localopt.ind ;
-
if (!argc) dieusage() ;
- if (!*argv[0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
- if (!stralloc_cats(&modif, argv[0]) || !stralloc_catb(&modif, "=", 1))
- strerr_diefu1sys(111, "stralloc_catb") ;
- modifstart = modif.len ;
- if (!slurp(&modif, 0)) strerr_diefu1sys(111, "slurp") ;
- if (!stralloc_0(&modif)) strerr_diefu1sys(111, "stralloc_catb") ;
+ if (!argv[0][0] || strchr(argv[0], '=')) strerr_dief1x(100, "invalid variable name") ;
+
+ if (!slurp(&value, 0) || !stralloc_0(&value)) strerr_diefu1sys(111, "slurp") ;
+ val = value.s ;
+ if (strlen(value.s) < value.len - 1)
{
- size_t reallen = strlen(modif.s) ;
- if (reallen < modif.len - 1)
+ if (insist >= 2)
+ strerr_dief1x(1, "stdin contained a null character") ;
+ else if (insist) val = 0 ;
+ else if (def)
{
- if (insist >= 2)
- strerr_dief1x(1, "stdin contained a null character") ;
- else if (insist)
- {
- modif.len = modifstart ;
- modif.s[modif.len - 1] = 0 ;
- chomp = 0 ;
- }
- else if (def)
- {
- modif.len = modifstart ;
- if (!stralloc_catb(&modif, def, strlen(def)+1))
- strerr_diefu1sys(111, "stralloc_catb") ;
- strerr_warnw2x("stdin contained a null character", " - using default instead") ;
- }
- else modif.len = reallen + 1 ;
+ val = def ;
+ strerr_warnw2x("stdin contained a null character", " - using default instead") ;
}
- if (chomp && (modif.s[modif.len - 2] == '\n'))
- modif.s[--modif.len - 1] = 0 ;
}
- xmexec0_n(argv + 1, modif.s, modif.len, 1) ;
+ else if (chomp && (value.s[value.len - 2] == '\n'))
+ value.s[--value.len - 1] = 0 ;
+ el_modif_and_exec(argv + 1, argv[0], val, doimport) ;
}
diff --git a/src/include/execline/execline.h b/src/include/execline/execline.h
index bbe4db9..144283d 100644
--- a/src/include/execline/execline.h
+++ b/src/include/execline/execline.h
@@ -4,6 +4,7 @@
#define EXECLINE_H
#include <sys/types.h>
+
#include <skalibs/gccattributes.h>
#include <skalibs/buffer.h>
#include <skalibs/stralloc.h>
@@ -76,4 +77,10 @@ struct elsubst_s
extern int el_substitute (stralloc *, char const *, size_t, char const *, char const *, elsubst_t const *, unsigned int) ;
+
+/* Execution with or without substitution */
+
+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) ;
+
#endif
diff --git a/src/libexecline/deps-lib/execline b/src/libexecline/deps-lib/execline
index 96d4e18..e896f2f 100644
--- a/src/libexecline/deps-lib/execline
+++ b/src/libexecline/deps-lib/execline
@@ -1,5 +1,7 @@
el_execsequence.o
el_getstrict.o
+el_modif_and_exec.o
+el_modif_and_spawn.o
el_parse.o
el_parse_from_buffer.o
el_parse_from_string.o
diff --git a/src/libexecline/el_modif_and_exec.c b/src/libexecline/el_modif_and_exec.c
new file mode 100644
index 0000000..e2a3618
--- /dev/null
+++ b/src/libexecline/el_modif_and_exec.c
@@ -0,0 +1,36 @@
+/* ISC license. */
+
+#include <string.h>
+
+#include <skalibs/env.h>
+#include <skalibs/exec.h>
+
+#include <execline/config.h>
+#include <execline/execline.h>
+
+void el_modif_and_exec (char const *const *argv, char const *var, char const *value, int doimport)
+{
+ size_t varlen = strlen(var) ;
+ size_t modiflen = value ? varlen + strlen(value) + 2 : 1 ;
+ char modifs[modiflen] ;
+ if (value)
+ {
+ memcpy(modifs, var, varlen) ;
+ modifs[varlen] = '=' ;
+ memcpy(modifs + varlen + 1, value, modiflen - varlen - 1) ;
+ }
+ if (doimport)
+ {
+ size_t m = 0 ;
+ char const *newargv[env_len(argv) + 6] ;
+ newargv[m++] = EXECLINE_BINPREFIX "importas" ;
+ newargv[m++] = "-ui" ;
+ newargv[m++] = "--" ;
+ newargv[m++] = var ;
+ newargv[m++] = var ;
+ while (*argv) newargv[m++] = *argv++ ;
+ newargv[m++] = 0 ;
+ xmexec0_n(newargv, value ? modifs : var, value ? modiflen : varlen + 1, 1) ;
+ }
+ else xmexec0_n(argv, value ? modifs : var, value ? modiflen : varlen + 1, 1) ;
+}
diff --git a/src/libexecline/el_modif_and_spawn.c b/src/libexecline/el_modif_and_spawn.c
new file mode 100644
index 0000000..0070052
--- /dev/null
+++ b/src/libexecline/el_modif_and_spawn.c
@@ -0,0 +1,39 @@
+/* ISC license. */
+
+#include <string.h>
+
+#include <skalibs/posixplz.h>
+#include <skalibs/env.h>
+
+#include <execline/config.h>
+#include <execline/execline.h>
+
+pid_t el_modif_and_spawn (char const *const *argv, char const *var, char const *value, int doimport)
+{
+ size_t varlen = strlen(var) ;
+ size_t modiflen = value ? varlen + strlen(value) + 2 : 1 ;
+ size_t envlen = env_len((char const *const *)environ) ;
+ char const *newenv[envlen + 2] ;
+ char modifs[modiflen] ;
+ if (value)
+ {
+ memcpy(modifs, var, varlen) ;
+ modifs[varlen] = '=' ;
+ memcpy(modifs + varlen + 1, value, modiflen - varlen - 1) ;
+ }
+ if (!env_mergen(newenv, envlen + 2, (char const *const *)environ, envlen, value ? modifs : var, value ? modiflen : varlen + 1, 1)) return 0 ;
+ if (doimport)
+ {
+ size_t m = 0 ;
+ char const *newargv[env_len(argv) + 6] ;
+ newargv[m++] = EXECLINE_BINPREFIX "importas" ;
+ newargv[m++] = "-ui" ;
+ newargv[m++] = "--" ;
+ newargv[m++] = var ;
+ newargv[m++] = var ;
+ while (*argv) newargv[m++] = *argv++ ;
+ newargv[m++] = 0 ;
+ return el_spawn0(newargv[0], newargv, newenv) ;
+ }
+ else return el_spawn0(argv[0], argv, newenv) ;
+}
diff --git a/src/libexecline/el_spawn0.c b/src/libexecline/el_spawn0.c
index 7e10902..0cfe017 100644
--- a/src/libexecline/el_spawn0.c
+++ b/src/libexecline/el_spawn0.c
@@ -1,6 +1,7 @@
/* ISC license. */
#include <skalibs/djbunix.h>
+
#include <execline/config.h>
#include <execline/execline.h>