summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-09-26 10:17:00 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-09-26 10:17:00 -0700
commitda59e8ce3fc5a35b3d22dd971ff96f498f655a98 (patch)
treec29c855e17d545e71d657e5630cc6ee364f7f6d8 /stream.c
parentba75167d1e7c609b829978b3f4a748ce3cf69ad9 (diff)
downloadtxr-da59e8ce3fc5a35b3d22dd971ff96f498f655a98.tar.gz
txr-da59e8ce3fc5a35b3d22dd971ff96f498f655a98.tar.bz2
txr-da59e8ce3fc5a35b3d22dd971ff96f498f655a98.zip
New variable: *child-env*.
This specifies the environment to be used for executing programs. * stream.c (open_subprocess, run): Check *child-env* variable and if other than t, then install the environment before execvp. In the spawn-based version of run, we save and restore the environment around the spawn call, if *child-env* is in effect. * sysif.c (child_env_s): New symbol variable. (exec_wrap): If *child-env* is other than t, then save the environment in a list, and install the specified environment before calling execvp. If that function returns, restore the environbment. * sysif.h (child_env_s): Declared. (child_env): New macro. * tests/018/process.tl: New tests. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/stream.c b/stream.c
index 10511ca7..95547e03 100644
--- a/stream.c
+++ b/stream.c
@@ -4516,8 +4516,12 @@ static val open_subprocess(val name, val mode_str, val args, val fun)
if (fun)
funcall(fun);
- if (argv)
+ if (argv) {
+ val ch_env = child_env;
+ if (ch_env != t)
+ replace_env(ch_env);
execvp(argv[0], argv);
+ }
_exit(errno);
} else {
int whichfd;
@@ -4747,6 +4751,7 @@ static val run(val command, val args)
val iter;
int i, nargs, status = 0;
struct save_fds sfds;
+ volatile val save_env, ch_env = child_env;
args = default_null_arg(args);
nargs = c_num(length(args), self) + 1;
@@ -4762,23 +4767,32 @@ static val run(val command, val args)
if (nargs < 0 || nargs == INT_MAX)
uw_throwf(error_s, lit("~a: argument list overflow"), self, nao);
+ if (ch_env != t) {
+ save_env = env();
+ replace_env(ch_env, nil);
+ }
+
wargv = coerce(const wchar_t **, chk_xalloc(nargs + 1, sizeof *wargv, self));
for (i = 0, iter = cons(command, args); iter; i++, iter = cdr(iter))
wargv[i] = c_str(car(iter), self);
wargv[i] = 0;
+ if (status == 0) {
#if HAVE_WSPAWN
- status = _wspawnvp(_P_WAIT, c_str(command, self), wargv);
+ status = _wspawnvp(_P_WAIT, c_str(command, self), wargv);
#else
- status = w_spawnvp(_P_WAIT, c_str(command, self), nargs, wargv);
+ status = w_spawnvp(_P_WAIT, c_str(command, self), nargs, wargv);
#endif
+ }
free(strip_qual(wchar_t **, wargv));
gc_hint(args);
uw_unwind {
+ if (ch_env != t)
+ replace_env(save_env, nil);
fds_restore(&sfds);
}
@@ -4833,7 +4847,10 @@ static val run(val name, val args)
}
if (pid == 0) {
+ val ch_env = child_env;
fds_clobber(&sfds, FDS_IN | FDS_OUT | FDS_ERR);
+ if (ch_env != t)
+ replace_env(ch_env);
execvp(argv[0], argv);
_exit(errno);
} else {