const char *prog_path, char **prog_argv,
bool ignore_sigpipe,
bool null_stdin, bool null_stdout, bool null_stderr,
- bool slave_process, bool exit_on_error)
+ bool slave_process, bool exit_on_error,
+ int *termsigp)
{
#if defined _MSC_VER || defined __MINGW32__
int nullinfd;
int nulloutfd;
+ /* FIXME: Need to free memory allocated by prepare_spawn. */
prog_argv = prepare_spawn (prog_argv);
/* Save standard file handles of parent process. */
&& ((null_stdout && nulloutfd == STDOUT_FILENO)
|| (null_stderr && nulloutfd == STDERR_FILENO)
|| close (nulloutfd) >= 0))))
- exitcode = spawnvp (P_WAIT, prog_path, prog_argv);
+ /* 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, 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 = spawnvpe (P_WAIT, prog_argv[0], prog_argv, environ);
+ }
+ }
if (nulloutfd >= 0)
close (nulloutfd);
if (nullinfd >= 0)
if (null_stdin)
dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
+ if (termsigp != NULL)
+ *termsigp = 0;
+
if (exitcode == -1)
{
if (exit_on_error || !null_stderr)
posix_spawnattr_destroy (&attrs);
if (slave_process)
unblock_fatal_signals ();
+ if (termsigp != NULL)
+ *termsigp = 0;
if (exit_on_error || !null_stderr)
error (exit_on_error ? EXIT_FAILURE : 0, err,
_("%s subprocess failed"), progname);
{
if (slave_process)
unblock_fatal_signals ();
+ if (termsigp != NULL)
+ *termsigp = 0;
if (exit_on_error || !null_stderr)
error (exit_on_error ? EXIT_FAILURE : 0, errno,
_("%s subprocess failed"), progname);
}
return wait_subprocess (child, progname, ignore_sigpipe, null_stderr,
- slave_process, exit_on_error);
+ slave_process, exit_on_error, termsigp);
#endif
}