From 04cacfa50524e0e6f11fa82b5a263fac6a8c21ea Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 29 Sep 2008 15:25:12 +0200 Subject: [PATCH] Propagate effects of putenv/setenv/unsetenv to child processes. --- ChangeLog | 6 ++++++ lib/execute.c | 12 ++++++++++-- lib/pipe.c | 12 ++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 75ed5a830..c5412b2ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-09-29 Bruno Haible + Propagate effects of putenv/setenv/unsetenv to child processes. + * lib/execute.c (execute): Use spawnvpe instead of spawnvp. + * lib/pipe.c (create_pipe): Likewise. + +2008-09-29 Bruno Haible + Enable use of shell scripts as executables in mingw. * lib/execute.c (execute): When spawnv fails with error ENOEXEC, run the program as a shell script. diff --git a/lib/execute.c b/lib/execute.c index 47f408520..231f46738 100644 --- a/lib/execute.c +++ b/lib/execute.c @@ -161,15 +161,23 @@ execute (const char *progname, && ((null_stdout && nulloutfd == STDOUT_FILENO) || (null_stderr && nulloutfd == STDERR_FILENO) || close (nulloutfd) >= 0)))) + /* Use spawnvpe and pass the environment explicitly. This is needed if + the program has modified the environment using putenv() or [un]setenv(). + On Windows, programs have two environments, one in the "environment + block" of the process and managed through SetEnvironmentVariable(), and + one inside the process, in the location retrieved by the 'environ' + macro. When using spawnvp() without 'e', the child process inherits a + copy of the environment block - ignoring the effects of putenv() and + [un]setenv(). */ { - exitcode = spawnvp (P_WAIT, prog_path, prog_argv); + exitcode = spawnvpe (P_WAIT, prog_path, prog_argv, environ); if (exitcode < 0 && errno == ENOEXEC) { /* prog is not an native executable. Try to execute it as a shell script. Note that prepare_spawn() has already prepended a hidden element "sh.exe" to prog_argv. */ --prog_argv; - exitcode = spawnvp (P_WAIT, prog_argv[0], prog_argv); + exitcode = spawnvpe (P_WAIT, prog_argv[0], prog_argv, environ); } } if (nulloutfd >= 0) diff --git a/lib/pipe.c b/lib/pipe.c index ebedb0a2d..05bd4ece6 100644 --- a/lib/pipe.c +++ b/lib/pipe.c @@ -202,15 +202,23 @@ create_pipe (const char *progname, we want in the case of STD*_FILENO) and also orig_stdin, orig_stdout, orig_stderr (which is not explicitly wanted but harmless). */ + /* Use spawnvpe and pass the environment explicitly. This is needed if + the program has modified the environment using putenv() or [un]setenv(). + On Windows, programs have two environments, one in the "environment + block" of the process and managed through SetEnvironmentVariable(), and + one inside the process, in the location retrieved by the 'environ' + macro. When using spawnvp() without 'e', the child process inherits a + copy of the environment block - ignoring the effects of putenv() and + [un]setenv(). */ { - child = spawnvp (P_NOWAIT, prog_path, prog_argv); + child = spawnvpe (P_NOWAIT, prog_path, prog_argv, environ); if (child < 0 && errno == ENOEXEC) { /* prog is not an native executable. Try to execute it as a shell script. Note that prepare_spawn() has already prepended a hidden element "sh.exe" to prog_argv. */ --prog_argv; - child = spawnvp (P_NOWAIT, prog_argv[0], prog_argv); + child = spawnvpe (P_NOWAIT, prog_argv[0], prog_argv, environ); } } if (stdinfd >= 0) -- 2.11.0