Update README.MinGW.
[git/mingw.git] / run-command.c
blobeb6fefb98b8a3b0794e44367ee18d0e7c7b40c67
1 #include "cache.h"
2 #include "run-command.h"
3 #include "exec_cmd.h"
4 #include "spawn-pipe.h"
6 int run_command_v_opt(const char **argv, int flags)
8 pid_t pid;
9 int fd_i[2] = { -1, -1 };
10 int fd_o[2] = { -1, -1 };
12 if (flags & RUN_COMMAND_NO_STDIN) {
13 #ifndef __MINGW32__
14 fd_i[0] = open("/dev/null", O_RDWR);
15 #else
16 fd_i[0] = open("nul", O_RDWR);
17 #endif
19 if (flags & RUN_COMMAND_STDOUT_TO_STDERR)
20 fd_o[1] = dup(2);
22 if (flags & RUN_GIT_CMD) {
23 pid = spawnv_git_cmd(argv, fd_i, fd_o);
24 } else {
25 pid = spawnvpe_pipe(argv[0], argv, environ, fd_i, fd_o);
27 if (pid < 0)
28 return -ERR_RUN_COMMAND_FORK;
29 for (;;) {
30 int status, code;
31 pid_t waiting = waitpid(pid, &status, 0);
33 if (waiting < 0) {
34 if (errno == EINTR)
35 continue;
36 error("waitpid failed (%s)", strerror(errno));
37 return -ERR_RUN_COMMAND_WAITPID;
39 if (waiting != pid)
40 return -ERR_RUN_COMMAND_WAITPID_WRONG_PID;
41 if (WIFSIGNALED(status))
42 return -ERR_RUN_COMMAND_WAITPID_SIGNAL;
44 if (!WIFEXITED(status))
45 return -ERR_RUN_COMMAND_WAITPID_NOEXIT;
46 code = WEXITSTATUS(status);
47 if (code)
48 return -code;
49 return 0;
53 int run_command_v(const char **argv)
55 return run_command_v_opt(argv, 0);
58 static int run_command_va_opt(int opt, const char *cmd, va_list param)
60 int argc;
61 const char *argv[MAX_RUN_COMMAND_ARGS];
62 const char *arg;
64 argv[0] = (char*) cmd;
65 argc = 1;
66 while (argc < MAX_RUN_COMMAND_ARGS) {
67 arg = argv[argc++] = va_arg(param, char *);
68 if (!arg)
69 break;
71 if (MAX_RUN_COMMAND_ARGS <= argc)
72 return error("too many args to run %s", cmd);
73 return run_command_v_opt(argv, opt);
76 int run_command_opt(int opt, const char *cmd, ...)
78 va_list params;
79 int r;
81 va_start(params, cmd);
82 r = run_command_va_opt(opt, cmd, params);
83 va_end(params);
84 return r;
87 int run_command(const char *cmd, ...)
89 va_list params;
90 int r;
92 va_start(params, cmd);
93 r = run_command_va_opt(0, cmd, params);
94 va_end(params);
95 return r;