diff options
-rw-r--r-- | run-command.c | 26 | ||||
-rw-r--r-- | run-command.h | 1 |
2 files changed, 25 insertions, 2 deletions
diff --git a/run-command.c b/run-command.c index 7e779d33ee..d00c03bbdf 100644 --- a/run-command.c +++ b/run-command.c @@ -17,8 +17,8 @@ static inline void dup_devnull(int to) int start_command(struct child_process *cmd) { - int need_in, need_out; - int fdin[2], fdout[2]; + int need_in, need_out, need_err; + int fdin[2], fdout[2], fderr[2]; need_in = !cmd->no_stdin && cmd->in < 0; if (need_in) { @@ -41,12 +41,26 @@ int start_command(struct child_process *cmd) cmd->close_out = 1; } + need_err = cmd->err < 0; + if (need_err) { + if (pipe(fderr) < 0) { + if (need_in) + close_pair(fdin); + if (need_out) + close_pair(fdout); + return -ERR_RUN_COMMAND_PIPE; + } + cmd->err = fderr[0]; + } + cmd->pid = fork(); if (cmd->pid < 0) { if (need_in) close_pair(fdin); if (need_out) close_pair(fdout); + if (need_err) + close_pair(fderr); return -ERR_RUN_COMMAND_FORK; } @@ -73,6 +87,11 @@ int start_command(struct child_process *cmd) close(cmd->out); } + if (need_err) { + dup2(fderr[1], 2); + close_pair(fderr); + } + if (cmd->dir && chdir(cmd->dir)) die("exec %s: cd to %s failed (%s)", cmd->argv[0], cmd->dir, strerror(errno)); @@ -102,6 +121,9 @@ int start_command(struct child_process *cmd) else if (cmd->out > 1) close(cmd->out); + if (need_err) + close(fderr[1]); + return 0; } diff --git a/run-command.h b/run-command.h index 7958eb1e0b..35b9fb61f1 100644 --- a/run-command.h +++ b/run-command.h @@ -16,6 +16,7 @@ struct child_process { pid_t pid; int in; int out; + int err; const char *dir; const char *const *env; unsigned close_in:1; |