diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2020-12-30 23:06:31 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2020-12-30 23:06:31 +0000 |
commit | f021f61f10c566fcae2f77b1a4b095869076062b (patch) | |
tree | ce84d18f30a4ebf5f6dc3b7ea1b009ba1a06ffcf | |
parent | b6b71f9942fb5f209e183c2ca997f33071c38c71 (diff) | |
download | execline-f021f61f10c566fcae2f77b1a4b095869076062b.tar.gz execline-f021f61f10c566fcae2f77b1a4b095869076062b.tar.xz execline-f021f61f10c566fcae2f77b1a4b095869076062b.zip |
Add -E option for variable autoimport
-rw-r--r-- | doc/backtick.html | 14 | ||||
-rw-r--r-- | doc/forbacktickx.html | 7 | ||||
-rw-r--r-- | doc/forstdin.html | 7 | ||||
-rw-r--r-- | doc/forx.html | 7 | ||||
-rw-r--r-- | doc/getcwd.html | 12 | ||||
-rw-r--r-- | doc/getpid.html | 12 | ||||
-rw-r--r-- | doc/withstdinas.html | 7 | ||||
-rw-r--r-- | package/deps.mak | 24 | ||||
-rw-r--r-- | src/execline/backtick.c | 82 | ||||
-rw-r--r-- | src/execline/deps-exe/getcwd | 1 | ||||
-rw-r--r-- | src/execline/deps-exe/getpid | 1 | ||||
-rw-r--r-- | src/execline/deps-exe/withstdinas | 1 | ||||
-rw-r--r-- | src/execline/forbacktickx.c | 11 | ||||
-rw-r--r-- | src/execline/forstdin.c | 114 | ||||
-rw-r--r-- | src/execline/forx.c | 39 | ||||
-rw-r--r-- | src/execline/getcwd.c | 36 | ||||
-rw-r--r-- | src/execline/getpid.c | 38 | ||||
-rw-r--r-- | src/execline/withstdinas.c | 59 | ||||
-rw-r--r-- | src/include/execline/execline.h | 7 | ||||
-rw-r--r-- | src/libexecline/deps-lib/execline | 2 | ||||
-rw-r--r-- | src/libexecline/el_modif_and_exec.c | 36 | ||||
-rw-r--r-- | src/libexecline/el_modif_and_spawn.c | 39 | ||||
-rw-r--r-- | src/libexecline/el_spawn0.c | 1 |
23 files changed, 333 insertions, 224 deletions
diff --git a/doc/backtick.html b/doc/backtick.html index 1f77432..91e963a 100644 --- a/doc/backtick.html +++ b/doc/backtick.html @@ -30,7 +30,7 @@ environment variable, then executes another program. </p> <pre> - backtick [ -i | -I | -D <em>default</em> ] [ -N | -n ] <em>variable</em> { <em>prog1...</em> } <em>prog2...</em> + backtick [ -i | -I | -D <em>default</em> ] [ -N | -n ] [ -E | -e ] <em>variable</em> { <em>prog1...</em> } <em>prog2...</em> </pre> <ul> @@ -48,6 +48,11 @@ output as a value. </li> <ul> <li> <tt>-N</tt> : store <em>prog1...</em>'s output as is, including the last newline, if any. </li> <li> <tt>-n</tt> : chomp an ending newline off <em>prog1...</em>'s output. This is the default. </li> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. Instead of exec'ing into +<em>prog2...</em>, exec into <tt>importas -ui <em>variable</em> <em>variable</em> +<em>prog2...</em></tt>. This substitutes <em>variable</em> into the command +line instead of putting it into the environment. </li> </ul> <p> @@ -69,12 +74,5 @@ or to whatever <em>prog1...</em> wrote before crashing; then execution proceeds. </li> </ul> -<h2> Notes </h2> - -<ul> - <li> You can start <em>prog2...</em> with "importas -u <em>variable</em> <em>variable</em>" -to perform variable substitution. </li> -</ul> - </body> </html> diff --git a/doc/forbacktickx.html b/doc/forbacktickx.html index d28ad0b..cbf33b5 100644 --- a/doc/forbacktickx.html +++ b/doc/forbacktickx.html @@ -30,7 +30,7 @@ run another program. </p> <pre> - forbacktickx [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] [ -N | -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> { <em>gen...</em> } <em>loop...</em> + forbacktickx [ -E | -e ] [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] [ -N | -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> { <em>gen...</em> } <em>loop...</em> </pre> <ul> @@ -65,6 +65,11 @@ not listed in <em>okcodes</em>, forbacktickx will exit immediately with an option, but with inverted meaning - the listed exit codes are codes that will make forbacktickx break the loop and exit, and the unlisted exit codes will make it keep looping. </li> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. Instead of spawning +<em>loop...</em>, spawn <tt>importas -ui <em>variable</em> <em>variable</em> +<em>loop...</em></tt>. This substitutes <em>variable</em> into the command +line instead of putting it into the environment. </li> </ul> <p> diff --git a/doc/forstdin.html b/doc/forstdin.html index 74644b4..3b00d7d 100644 --- a/doc/forstdin.html +++ b/doc/forstdin.html @@ -30,7 +30,7 @@ run another program. </p> <pre> - forstdin [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] [ -N | -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> <em>loop...</em> + forstdin [ -E | -e ] [ -p | -o <em>okcodes</em> | -x <em>breakcodes</em> ] [ -N | -n ] [ -C | -c ] [ -0 | -d <em>delim</em> ] <em>variable</em> <em>loop...</em> </pre> <ul> @@ -61,6 +61,11 @@ not listed in <em>okcodes</em>, forstdin will exit immediately with an option, but with inverted meaning - the listed exit codes are codes that will make forstdin break the loop and exit, and the unlisted exit codes will make it keep looping. </li> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. Instead of spawning +<em>loop...</em>, spawn <tt>importas -ui <em>variable</em> <em>variable</em> +<em>loop...</em></tt>. This substitutes <em>variable</em> into the command +line instead of putting it into the environment. </li> </ul> <p> diff --git a/doc/forx.html b/doc/forx.html index 1c2a61c..8f1d558 100644 --- a/doc/forx.html +++ b/doc/forx.html @@ -29,7 +29,7 @@ </p> <pre> - forx [ -p ] [ -o <em>okcodes</em> | -x <em>breakcodes</em> ] <em>variable</em> { <em>args...</em> } <em>loop...</em> + forx [ -E | -e ] [ -p ] [ -o <em>okcodes</em> | -x <em>breakcodes</em> ] <em>variable</em> { <em>args...</em> } <em>loop...</em> </pre> <ul> @@ -63,6 +63,11 @@ will exit 0 if all of the exit codes are in the values listed in the <em>okcodes list, else it will exit 1. If the <tt>-x</tt> option has been given, <tt>forx</tt> will exit 0 if none of the exit codes are in the values listed in the <em>breakcodes</em> list, else it will exit 1. </li> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. Instead of spawning +<em>loop...</em>, spawn <tt>importas -ui <em>variable</em> <em>variable</em> +<em>loop...</em></tt>. This substitutes <em>variable</em> into the command +line instead of putting it into the environment. </li> </ul> <h2> Notes </h2> diff --git a/doc/getcwd.html b/doc/getcwd.html index 9735630..d3e7e27 100644 --- a/doc/getcwd.html +++ b/doc/getcwd.html @@ -27,7 +27,7 @@ then executes a program. <h2> Interface </h2> <pre> - getcwd <em>var</em> <em>prog...</em> + getcwd [ -E | -e ] <em>var</em> <em>prog...</em> </pre> <p> @@ -37,6 +37,16 @@ into the <em>var</em> variable, then execs into <em>prog</em> with its arguments. </p> +<h2> Options </h2> + +<ul> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. Instead of exec'ing into +<em>prog...</em>, exec into <tt>importas -ui <em>var</em> <em>var</em> +<em>prog...</em></tt>. This substitutes <em>var</em> into the command +line instead of putting it into the environment. </li> +</ul> + <h2> Notes </h2> <ul> diff --git a/doc/getpid.html b/doc/getpid.html index ca363df..5a849e8 100644 --- a/doc/getpid.html +++ b/doc/getpid.html @@ -26,7 +26,7 @@ then executes a program. <h2> Interface </h2> <pre> - getpid <em>var</em> <em>prog...</em> + getpid [ -E | -e ] <em>var</em> <em>prog...</em> </pre> <p> @@ -34,6 +34,16 @@ then executes a program. execs into <em>prog</em> with its arguments. </p> +<h2> Options </h2> + +<ul> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. Instead of exec'ing into +<em>prog...</em>, exec into <tt>importas -ui <em>var</em> <em>var</em> +<em>prog...</em></tt>. This substitutes <em>var</em> into the command +line instead of putting it into the environment. </li> +</ul> + <h2> Notes </h2> <ul> diff --git a/doc/withstdinas.html b/doc/withstdinas.html index ccd69d7..5b9e653 100644 --- a/doc/withstdinas.html +++ b/doc/withstdinas.html @@ -31,7 +31,7 @@ environment variable. </p> <pre> - withstdinas [ -i | -I | -D <em>default</em> ] [ -N | -n ] <em>variable</em> <em>prog...</em> + withstdinas [ -i | -I | -D <em>default</em> ] [ -N | -n ] [ -E | -e ] <em>variable</em> <em>prog...</em> </pre> <ul> @@ -46,6 +46,11 @@ environment variable. <ul> <li> <tt>-N</tt> : do not chomp an ending newline off stdin. </li> <li> <tt>-n</tt> : chomp an ending newline off stdin. This is the default. </li> + <li> <tt>-e</tt> : no autoimport. This is the default. </li> + <li> <tt>-E</tt> : autoimport. Instead of exec'ing into +<em>prog...</em>, exec into <tt>importas -ui <em>variable</em> <em>variable</em> +<em>prog...</em></tt>. This substitutes <em>variable</em> into the command +line instead of putting it into the environment. </li> </ul> <p> diff --git a/package/deps.mak b/package/deps.mak index 3aac760..6bfce8e 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -24,10 +24,10 @@ src/execline/fdreserve.o src/execline/fdreserve.lo: src/execline/fdreserve.c src/execline/fdswap.o src/execline/fdswap.lo: src/execline/fdswap.c src/execline/forbacktickx.o src/execline/forbacktickx.lo: src/execline/forbacktickx.c src/include/execline/config.h src/include/execline/execline.h src/execline/foreground.o src/execline/foreground.lo: src/execline/foreground.c src/include/execline/execline.h -src/execline/forstdin.o src/execline/forstdin.lo: src/execline/forstdin.c src/include/execline/config.h src/include/execline/execline.h +src/execline/forstdin.o src/execline/forstdin.lo: src/execline/forstdin.c src/include/execline/execline.h src/execline/forx.o src/execline/forx.lo: src/execline/forx.c src/include/execline/config.h src/include/execline/execline.h -src/execline/getcwd.o src/execline/getcwd.lo: src/execline/getcwd.c -src/execline/getpid.o src/execline/getpid.lo: src/execline/getpid.c +src/execline/getcwd.o src/execline/getcwd.lo: src/execline/getcwd.c src/include/execline/execline.h +src/execline/getpid.o src/execline/getpid.lo: src/execline/getpid.c src/include/execline/execline.h src/execline/heredoc.o src/execline/heredoc.lo: src/execline/heredoc.c src/execline/homeof.o src/execline/homeof.lo: src/execline/homeof.c src/execline/if.o src/execline/if.lo: src/execline/if.c src/include/execline/execline.h @@ -46,10 +46,12 @@ src/execline/shift.o src/execline/shift.lo: src/execline/shift.c src/include/exe src/execline/trap.o src/execline/trap.lo: src/execline/trap.c src/include/execline/execline.h src/execline/tryexec.o src/execline/tryexec.lo: src/execline/tryexec.c src/include/execline/execline.h src/execline/unexport.o src/execline/unexport.lo: src/execline/unexport.c -src/execline/wait.o src/execline/wait.lo: src/execline/wait.c src/include/execline/execline.h -src/execline/withstdinas.o src/execline/withstdinas.lo: src/execline/withstdinas.c +src/execline/wait.o src/execline/wait.lo: src/execline/wait.c src/include/execline/config.h src/include/execline/execline.h +src/execline/withstdinas.o src/execline/withstdinas.lo: src/execline/withstdinas.c src/include/execline/execline.h src/libexecline/el_execsequence.o src/libexecline/el_execsequence.lo: src/libexecline/el_execsequence.c src/include/execline/execline.h src/libexecline/el_getstrict.o src/libexecline/el_getstrict.lo: src/libexecline/el_getstrict.c 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_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 @@ -123,9 +125,9 @@ forstdin: src/execline/forstdin.o ${LIBEXECLINE} forx: EXTRA_LIBS := -lskarnet ${SPAWN_LIB} forx: src/execline/forx.o ${LIBEXECLINE} getcwd: EXTRA_LIBS := -lskarnet -getcwd: src/execline/getcwd.o +getcwd: src/execline/getcwd.o ${LIBEXECLINE} getpid: EXTRA_LIBS := -lskarnet -getpid: src/execline/getpid.o +getpid: src/execline/getpid.o ${LIBEXECLINE} heredoc: EXTRA_LIBS := -lskarnet heredoc: src/execline/heredoc.o homeof: EXTRA_LIBS := -lskarnet ${MAYBEPTHREAD_LIB} @@ -165,14 +167,14 @@ unexport: src/execline/unexport.o wait: EXTRA_LIBS := -lskarnet wait: src/execline/wait.o ${LIBEXECLINE} withstdinas: EXTRA_LIBS := -lskarnet -withstdinas: src/execline/withstdinas.o +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_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_spawn1.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_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_spawn1.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_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_spawn1.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_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_spawn1.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 -libexecline.so.xyzzy: src/libexecline/el_execsequence.lo src/libexecline/el_getstrict.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_spawn1.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_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_spawn1.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 posix-cd: EXTRA_LIBS := -lskarnet posix-cd: src/posix/posix-cd.o posix-umask: EXTRA_LIBS := -lskarnet 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, ¶llel_sigchld_handler) < 0) - strerr_diefu1sys(111, "install SIGCHLD handler") ; - } - for (;;) + if (sig_catch(SIGCHLD, ¶llel_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> |