add platform specific function which may override invoked command
[git-cheetah/kirill.git] / common / exec.c
bloba6878c7da7aba8234f181fe927291a24b35cfa66
1 #include "cache.h"
3 #include "debug.h"
4 #include "systeminfo.h"
5 #include "exec.h"
7 #define MAX_PROCESSING_TIME (60 * 1000)
8 #define MAX_ARGS 32
10 /* copy from run-command.c */
11 static inline void close_pair(int fd[2])
13 close(fd[0]);
14 close(fd[1]);
17 int exec_program(const char *working_directory,
18 struct strbuf *output, struct strbuf *error_output,
19 int flags, ...)
21 va_list params;
22 const char *argv[MAX_ARGS];
23 char *arg;
24 int argc = 0;
26 va_start(params, flags);
27 do {
28 arg = va_arg(params, char*);
29 argv[argc++] = arg;
30 } while (argc < MAX_ARGS && arg);
31 va_end(params);
33 return exec_program_v(working_directory, output, error_output,
34 flags, argv);
37 int exec_program_v(const char *working_directory,
38 struct strbuf *output, struct strbuf *error_output,
39 int flags, const char **argv)
41 int fdout[2], fderr[2];
42 int s0 = -1, s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */
44 pid_t pid;
45 int status = 0;
46 int ret;
48 reporter *debug = QUIETMODE & flags ? debug_git : debug_git_mbox;
50 if (!git_path()) {
51 debug("[ERROR] Could not find git path");
52 return -1;
55 if (output) {
56 if (pipe(fdout) < 0) {
57 return -ERR_RUN_COMMAND_PIPE;
59 s1 = dup(1);
60 dup2(fdout[1], 1);
62 flags |= WAITMODE;
65 if (error_output) {
66 if (pipe(fderr) < 0) {
67 if (output)
68 close_pair(fdout);
69 return -ERR_RUN_COMMAND_PIPE;
71 s2 = dup(2);
72 dup2(fderr[1], 2);
74 flags |= WAITMODE;
77 pid = fork_process(argv[0], argv, working_directory);
79 if (s1 >= 0)
80 dup2(s1, 1), close(s1);
81 if (s2 >= 0)
82 dup2(s2, 2), close(s2);
84 if (pid < 0) {
85 if (output)
86 close_pair(fdout);
87 if (error_output)
88 close_pair(fderr);
89 return -ERR_RUN_COMMAND_FORK;
92 if (output)
93 close(fdout[1]);
94 if (error_output)
95 close(fderr[1]);
97 if (WAITMODE & flags) {
98 ret = wait_for_process(pid, MAX_PROCESSING_TIME,
99 &status);
100 if (ret) {
101 if (ret < 0) {
102 debug_git("[ERROR] wait_for_process failed (%d); "
103 "wd: %s; cmd: %s",
104 status,
105 working_directory,
106 argv[0]);
108 status = -1;
111 if (output) {
112 strbuf_read(output, fdout[0], 0);
113 debug_git("STDOUT:\r\n%s\r\n*** end of STDOUT ***\r\n", output->buf);
116 if (error_output) {
117 strbuf_read(error_output, fderr[0], 0);
118 debug_git("STDERR:\r\n%s\r\n*** end of STDERR ***\r\n", error_output->buf);
120 } else {
121 status = -ERR_RUN_COMMAND_WAITPID_NOEXIT;
122 debug_git("[ERROR] process timed out; "
123 "wd: %s; cmd: %s",
124 working_directory, argv[0]);
128 if (output)
129 close(fdout[0]);
130 if (error_output)
131 close(fderr[0]);
133 return status;