2 #include "run-command.h"
4 #include "spawn-pipe.h"
6 static inline void close_pair(int fd
[2])
12 int start_command(struct child_process
*cmd
)
14 int need_in
, need_out
;
15 int fdin
[2] = { -1, -1 };
16 int fdout
[2] = { -1, -1 };
18 need_in
= !cmd
->no_stdin
&& cmd
->in
< 0;
21 return -ERR_RUN_COMMAND_PIPE
;
26 need_out
= !cmd
->no_stdout
27 && !cmd
->stdout_to_stderr
30 if (pipe(fdout
) < 0) {
33 return -ERR_RUN_COMMAND_PIPE
;
41 fdin
[0] = open("/dev/null", O_RDWR
);
49 fdout
[1] = open("/dev/null", O_RDWR
);
50 else if (cmd
->stdout_to_stderr
)
54 } else if (cmd
->out
> 1) {
59 cmd
->pid
= spawnv_git_cmd(cmd
->argv
, fdin
, fdout
);
61 cmd
->pid
= spawnvpe_pipe(cmd
->argv
[0], cmd
->argv
, environ
, fdin
, fdout
);
69 return -ERR_RUN_COMMAND_FORK
;
75 int finish_command(struct child_process
*cmd
)
84 pid_t waiting
= waitpid(cmd
->pid
, &status
, 0);
89 error("waitpid failed (%s)", strerror(errno
));
90 return -ERR_RUN_COMMAND_WAITPID
;
92 if (waiting
!= cmd
->pid
)
93 return -ERR_RUN_COMMAND_WAITPID_WRONG_PID
;
94 if (WIFSIGNALED(status
))
95 return -ERR_RUN_COMMAND_WAITPID_SIGNAL
;
97 if (!WIFEXITED(status
))
98 return -ERR_RUN_COMMAND_WAITPID_NOEXIT
;
99 code
= WEXITSTATUS(status
);
106 int run_command(struct child_process
*cmd
)
108 int code
= start_command(cmd
);
111 return finish_command(cmd
);
114 int run_command_v_opt(const char **argv
, int opt
)
116 struct child_process cmd
;
117 memset(&cmd
, 0, sizeof(cmd
));
119 cmd
.no_stdin
= opt
& RUN_COMMAND_NO_STDIN
? 1 : 0;
120 cmd
.git_cmd
= opt
& RUN_GIT_CMD
? 1 : 0;
121 cmd
.stdout_to_stderr
= opt
& RUN_COMMAND_STDOUT_TO_STDERR
? 1 : 0;
122 return run_command(&cmd
);