static void notify_parent(void)
{
- write(child_notifier, "", 1);
+ /*
+ * execvp failed. If possible, we'd like to let start_command
+ * know, so failures like ENOENT can be handled right away; but
+ * otherwise, finish_command will still report the error.
+ */
+ xwrite(child_notifier, "", 1);
}
static NORETURN void die_child(const char *err, va_list params)
{
- char msg[4096];
- int len = vsnprintf(msg, sizeof(msg), err, params);
- if (len > sizeof(msg))
- len = sizeof(msg);
-
- write(child_err, "fatal: ", 7);
- write(child_err, msg, len);
- write(child_err, "\n", 1);
+ vwritef(child_err, "fatal: ", err, params);
exit(128);
}
+
+static void error_child(const char *err, va_list params)
+{
+ vwritef(child_err, "error: ", err, params);
+}
#endif
static inline void set_cloexec(int fd)
if (code == 127) {
code = -1;
failed_errno = ENOENT;
- if (!silent_exec_failure)
- error("cannot run %s: %s", argv0,
- strerror(ENOENT));
}
} else {
error("waitpid is confused (%s)", argv0);
}
trace_argv_printf(cmd->argv, "trace: run_command:");
+ fflush(NULL);
#ifndef WIN32
{
if (pipe(notify_pipe))
notify_pipe[0] = notify_pipe[1] = -1;
- fflush(NULL);
cmd->pid = fork();
if (!cmd->pid) {
/*
set_cloexec(child_err);
}
set_die_routine(die_child);
+ set_error_routine(error_child);
close(notify_pipe[0]);
set_cloexec(notify_pipe[1]);
} else {
execvp(cmd->argv[0], (char *const*) cmd->argv);
}
- /*
- * Do not check for cmd->silent_exec_failure; the parent
- * process will check it when it sees this exit code.
- */
- if (errno == ENOENT)
+ if (errno == ENOENT) {
+ if (!cmd->silent_exec_failure)
+ error("cannot run %s: %s", cmd->argv[0],
+ strerror(ENOENT));
exit(127);
- else
+ } else {
die_errno("cannot exec '%s'", cmd->argv[0]);
+ }
}
if (cmd->pid < 0)
error("cannot fork() for %s: %s", cmd->argv[0],
else if (cmd->out > 1)
fhout = dup(cmd->out);
- if (cmd->dir)
- die("chdir in start_command() not implemented");
if (cmd->env)
env = make_augmented_environ(cmd->env);
cmd->argv = prepare_shell_cmd(cmd->argv);
}
- cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env,
+ cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env, cmd->dir,
fhin, fhout, fherr);
failed_errno = errno;
if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
close(cmd->out);
if (need_err)
close_pair(fderr);
+ else if (cmd->err)
+ close(cmd->err);
errno = failed_errno;
return -1;
}