run-command: Redirect stderr to a pipe before redirecting stdout to stderr
authorChristian Couder <chriscool@tuxfamily.org>
Wed, 5 Mar 2008 07:35:16 +0000 (08:35 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 5 Mar 2008 20:18:03 +0000 (12:18 -0800)
With this patch, in the 'start_command' function after forking
we now take care of stderr in the child process before stdout.

This way if 'start_command' is called with a 'child_process'
argument like this:

.err = -1;
.stdout_to_stderr = 1;

then stderr will be redirected to a pipe before stdout is
redirected to stderr. So we can now get the process' stdout
from the pipe (as well as its stderr).

Earlier such a call would have redirected stdout to stderr
before stderr was itself redirected, and therefore stdout
would not have followed stderr, which would not have been
very useful anyway.

Update documentation in 'api-run-command.txt' accordingly.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Acked-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-run-command.txt
run-command.c

index fde3b453211030b7256ccedd100970ef712338bd..c364a22c8f98f6fbb71d4059f7458ed0fa78ed43 100644 (file)
@@ -111,9 +111,10 @@ stderr as follows:
        .no_stdin, .no_stdout, .no_stderr: The respective channel is
                redirected to /dev/null.
 
-       .stdout_to_stderr: stdout of the child is redirected to the
-               parent's stderr (i.e. *not* to what .err or
-               .no_stderr specify).
+       .stdout_to_stderr: stdout of the child is redirected to its
+               stderr. This happens after stderr is itself redirected.
+               So stdout will follow stderr to wherever it is
+               redirected.
 
 To modify the environment of the sub-process, specify an array of
 string pointers (NULL terminated) in .env:
index 743757c36ec0e5667fd8af28800ac095f1581adb..44100a749b09439121073e32e7a3143b54185d31 100644 (file)
@@ -91,6 +91,13 @@ int start_command(struct child_process *cmd)
                        close(cmd->in);
                }
 
+               if (cmd->no_stderr)
+                       dup_devnull(2);
+               else if (need_err) {
+                       dup2(fderr[1], 2);
+                       close_pair(fderr);
+               }
+
                if (cmd->no_stdout)
                        dup_devnull(1);
                else if (cmd->stdout_to_stderr)
@@ -103,13 +110,6 @@ int start_command(struct child_process *cmd)
                        close(cmd->out);
                }
 
-               if (cmd->no_stderr)
-                       dup_devnull(2);
-               else 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));