Add git version defines
[git-cheetah/kirill.git] / common / exec.c
blob9c3dcbdc5b7f31087475dcd9f806d489126e3e89
1 #include "git-compat-util.h"
2 #include "cache.h"
4 #include "debug.h"
5 #include "systeminfo.h"
6 #include "exec.h"
8 #define MAX_PROCESSING_TIME (60 * 1000)
9 #define MAX_ARGS 32
11 /* copy from run-command.c */
12 static inline void close_pair(int fd[2])
14 close(fd[0]);
15 close(fd[1]);
18 int exec_program(const char *working_directory,
19 struct strbuf *output, struct strbuf *error_output,
20 int flags, ...)
22 va_list params;
23 const char *argv[MAX_ARGS];
24 char *arg;
25 int argc = 0;
27 va_start(params, flags);
28 do {
29 arg = va_arg(params, char*);
30 argv[argc++] = arg;
31 } while (argc < MAX_ARGS && arg);
32 va_end(params);
34 return exec_program_v(working_directory, output, error_output,
35 flags, argv);
38 int exec_program_v(const char *working_directory,
39 struct strbuf *output, struct strbuf *error_output,
40 int flags, const char **argv)
42 int fdout[2], fderr[2];
43 int s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */
45 pid_t pid;
46 int status = 0;
47 int ret;
49 reporter *debug = QUIETMODE & flags ? debug_git : debug_git_mbox;
51 if (!git_path()) {
52 debug("[ERROR] Could not find git path");
53 return -1;
56 if (output) {
57 if (pipe(fdout) < 0) {
58 return -ERR_RUN_COMMAND_PIPE;
60 s1 = dup(1);
61 dup2(fdout[1], 1);
63 flags |= WAITMODE;
66 if (error_output) {
67 if (pipe(fderr) < 0) {
68 if (output)
69 close_pair(fdout);
70 return -ERR_RUN_COMMAND_PIPE;
72 s2 = dup(2);
73 dup2(fderr[1], 2);
75 flags |= WAITMODE;
78 pid = fork_process(argv[0], argv, working_directory);
80 if (s1 >= 0)
81 dup2(s1, 1), close(s1);
82 if (s2 >= 0)
83 dup2(s2, 2), close(s2);
85 if (pid < 0) {
86 if (output)
87 close_pair(fdout);
88 if (error_output)
89 close_pair(fderr);
90 return -ERR_RUN_COMMAND_FORK;
93 if (output)
94 close(fdout[1]);
95 if (error_output)
96 close(fderr[1]);
98 if (WAITMODE & flags) {
99 ret = wait_for_process(pid, MAX_PROCESSING_TIME,
100 &status);
101 if (ret) {
102 if (ret < 0) {
103 debug_git("[ERROR] wait_for_process failed (%d); "
104 "wd: %s; cmd: %s",
105 status,
106 working_directory,
107 argv[0]);
109 status = -1;
112 if (output) {
113 strbuf_read(output, fdout[0], 0);
114 debug_git("STDOUT:\r\n%s\r\n*** end of STDOUT ***\r\n", output->buf);
117 if (error_output) {
118 strbuf_read(error_output, fderr[0], 0);
119 debug_git("STDERR:\r\n%s\r\n*** end of STDERR ***\r\n", error_output->buf);
121 } else {
122 status = -ERR_RUN_COMMAND_WAITPID_NOEXIT;
123 debug_git("[ERROR] process timed out; "
124 "wd: %s; cmd: %s",
125 working_directory, argv[0]);
129 if (output)
130 close(fdout[0]);
131 if (error_output)
132 close(fderr[0]);
134 return status;