Propagate effects of putenv/setenv/unsetenv to child processes.
authorBruno Haible <bruno@clisp.org>
Mon, 29 Sep 2008 13:25:12 +0000 (15:25 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 29 Sep 2008 19:44:27 +0000 (21:44 +0200)
ChangeLog
lib/execute.c
lib/pipe.c

index 75ed5a830d0c8c803b95cacd473cd3a53b1ca401..c5412b2cea8dda4fda996df03a14a48f7a7dcc05 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-09-29  Bruno Haible  <bruno@clisp.org>
+
+       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  <bruno@clisp.org>
 
        Enable use of shell scripts as executables in mingw.
index 47f408520450e652c72e700147bd54d30f484ec1..231f467380346bdfa1d9bf3eef3062b4527f99e4 100644 (file)
@@ -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)
index ebedb0a2d56778bee03d4a69ec4f1156b1dc01c9..05bd4ece6825508c3b96cf5361f5cd4a15637e6a 100644 (file)
@@ -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)