trace_argv_printf(cmd->argv, "trace: run_command:");
#ifndef __MINGW32__
+ fflush(NULL);
cmd->pid = fork();
if (!cmd->pid) {
if (cmd->no_stdin)
unsetenv(*cmd->env);
}
}
+ if (cmd->preexec_cb)
+ cmd->preexec_cb();
if (cmd->git_cmd) {
execv_git_cmd(cmd->argv);
} else {
execvp(cmd->argv[0], (char *const*) cmd->argv);
}
- die("exec %s failed.", cmd->argv[0]);
+ trace_printf("trace: exec '%s' failed: %s\n", cmd->argv[0],
+ strerror(errno));
+ exit(127);
}
#else
int s0 = -1, s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */
#endif
if (cmd->pid < 0) {
+ int err = errno;
if (need_in)
close_pair(fdin);
else if (cmd->in)
close(cmd->out);
if (need_err)
close_pair(fderr);
- return -ERR_RUN_COMMAND_FORK;
+ return err == ENOENT ?
+ -ERR_RUN_COMMAND_EXEC :
+ -ERR_RUN_COMMAND_FORK;
}
if (need_in)
if (!WIFEXITED(status))
return -ERR_RUN_COMMAND_WAITPID_NOEXIT;
code = WEXITSTATUS(status);
- if (code)
+ switch (code) {
+ case 127:
+ return -ERR_RUN_COMMAND_EXEC;
+ case 0:
+ return 0;
+ default:
return -code;
- return 0;
+ }
}
}
return run_command(&cmd);
}
-int run_command_v_opt_cd(const char **argv, int opt, const char *dir)
-{
- struct child_process cmd;
- prepare_run_command_v_opt(&cmd, argv, opt);
- cmd.dir = dir;
- return run_command(&cmd);
-}
-
int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env)
{
struct child_process cmd;
async->out = pipe_out[0];
#ifndef __MINGW32__
+ /* Flush stdio before fork() to avoid cloning buffers */
+ fflush(NULL);
+
async->pid = fork();
if (async->pid < 0) {
error("fork (async) failed: %s", strerror(errno));