- || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
- && (!null_stdout
- || nulloutfd == STDOUT_FILENO
- || dup2 (nulloutfd, STDOUT_FILENO) >= 0)
- && (!null_stderr
- || nulloutfd == STDERR_FILENO
- || dup2 (nulloutfd, STDERR_FILENO) >= 0)
- && ((null_stdout && nulloutfd == STDOUT_FILENO)
- || (null_stderr && nulloutfd == STDERR_FILENO)
- || close (nulloutfd) >= 0))))
- exitcode = spawnvp (P_WAIT, prog_path, prog_argv);
+ || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
+ && (!null_stdout
+ || nulloutfd == STDOUT_FILENO
+ || dup2 (nulloutfd, STDOUT_FILENO) >= 0)
+ && (!null_stderr
+ || nulloutfd == STDERR_FILENO
+ || dup2 (nulloutfd, STDERR_FILENO) >= 0)
+ && ((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 = spawnvpe (P_WAIT, prog_path, (const char **) prog_argv,
+ (const char **) 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 = spawnvpe (P_WAIT, prog_argv[0], (const char **) prog_argv,
+ (const char **) environ);
+ }
+ }