Teach run-command about stdout redirection
authorShawn O. Pearce <spearce@spearce.org>
Mon, 12 Mar 2007 18:37:45 +0000 (14:37 -0400)
committerJunio C Hamano <junkio@cox.net>
Tue, 13 Mar 2007 06:40:17 +0000 (23:40 -0700)
Some potential callers of the run_command family of functions need
to control not only the stdin redirection of the child, but also
the stdout redirection of the child.  This can now be setup much
like the already existing stdin redirection.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
run-command.c
run-command.h

index bef9775e0807200e07c9780c69e3e1bda0c6c874..d20a6ef80c08bcf51ab5e650875ba8994917ca70 100644 (file)
@@ -11,7 +11,8 @@ static inline void close_pair(int fd[2])
 int start_command(struct child_process *cmd)
 {
        int need_in = !cmd->no_stdin && cmd->in < 0;
-       int fdin[2];
+       int need_out = !cmd->stdout_to_stderr && cmd->out < 0;
+       int fdin[2], fdout[2];
 
        if (need_in) {
                if (pipe(fdin) < 0)
@@ -20,10 +21,22 @@ int start_command(struct child_process *cmd)
                cmd->close_in = 1;
        }
 
+       if (need_out) {
+               if (pipe(fdout) < 0) {
+                       if (need_in)
+                               close_pair(fdin);
+                       return -ERR_RUN_COMMAND_PIPE;
+               }
+               cmd->out = fdout[0];
+               cmd->close_out = 1;
+       }
+
        cmd->pid = fork();
        if (cmd->pid < 0) {
                if (need_in)
                        close_pair(fdin);
+               if (need_out)
+                       close_pair(fdout);
                return -ERR_RUN_COMMAND_FORK;
        }
 
@@ -42,6 +55,14 @@ int start_command(struct child_process *cmd)
 
                if (cmd->stdout_to_stderr)
                        dup2(2, 1);
+               else if (need_out) {
+                       dup2(fdout[1], 1);
+                       close_pair(fdout);
+               } else if (cmd->out > 1) {
+                       dup2(cmd->out, 1);
+                       close(cmd->out);
+               }
+
                if (cmd->git_cmd) {
                        execv_git_cmd(cmd->argv);
                } else {
@@ -55,6 +76,11 @@ int start_command(struct child_process *cmd)
        else if (cmd->in)
                close(cmd->in);
 
+       if (need_out)
+               close(fdout[1]);
+       else if (cmd->out > 1)
+               close(cmd->out);
+
        return 0;
 }
 
@@ -62,6 +88,8 @@ int finish_command(struct child_process *cmd)
 {
        if (cmd->close_in)
                close(cmd->in);
+       if (cmd->close_out)
+               close(cmd->out);
 
        for (;;) {
                int status, code;
index ff090679a6fecd66bda4fba804a8ab6555571aa9..1c9126b875970f9739597ef871d9ad19da2cbc14 100644 (file)
@@ -15,7 +15,9 @@ struct child_process {
        const char **argv;
        pid_t pid;
        int in;
+       int out;
        unsigned close_in:1;
+       unsigned close_out:1;
        unsigned no_stdin:1;
        unsigned git_cmd:1; /* if this is to be git sub-command */
        unsigned stdout_to_stderr:1;