diff options
author | Johannes Sixt <johannes.sixt@telecom.at> | 2007-10-19 21:47:58 +0200 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2007-10-21 01:30:40 -0400 |
commit | f3b33f1d220056243d3c1da154d3859410630189 (patch) | |
tree | 28970fae26a6dd7bfccd1472a7bed7ea9c07b436 /run-command.c | |
parent | 477822c35dbf3d5f16fce1425638e761e60ede3d (diff) | |
download | git-f3b33f1d220056243d3c1da154d3859410630189.tar.gz |
Have start_command() create a pipe to read the stderr of the child.
This adds another stanza that allocates a pipe that is connected to the
child's stderr and that the caller can read from. In order to request this
pipe, the caller sets cmd->err to -1.
The implementation is not exactly modeled after the stdout case: For stdout
the caller can supply an existing file descriptor, but this facility is
nowhere needed in the stderr case. Additionally, the caller is required to
close cmd->err.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'run-command.c')
-rw-r--r-- | run-command.c | 26 |
1 files changed, 24 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; } |