introduce path seperator define to support multiple platforms
[git-cheetah/kirill.git] / common / exec.c
blobc1179d7d8a478283960f6cbd497fa64fd3774251
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 int fdout[2], fderr[2];
22 int s0 = -1, s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */
24 va_list params;
25 const char *argv[MAX_ARGS];
26 char *arg;
27 int argc = 0;
29 pid_t pid;
30 int status = 0;
31 int ret;
33 reporter *debug = QUIETMODE & flags ? debug_git : debug_git_mbox;
35 if (!git_path()) {
36 debug("[ERROR] Could not find git path");
37 return -1;
40 if (output) {
41 if (pipe(fdout) < 0) {
42 return -ERR_RUN_COMMAND_PIPE;
44 s1 = dup(1);
45 dup2(fdout[1], 1);
47 flags |= WAITMODE;
50 if (error_output) {
51 if (pipe(fderr) < 0) {
52 if (output)
53 close_pair(fdout);
54 return -ERR_RUN_COMMAND_PIPE;
56 s2 = dup(2);
57 dup2(fderr[1], 2);
59 flags |= WAITMODE;
62 va_start(params, flags);
63 do {
64 arg = va_arg(params, char*);
65 argv[argc++] = arg;
66 } while (argc < MAX_ARGS && arg);
67 va_end(params);
69 pid = fork_process(argv[0], argv, working_directory);
71 if (s1 >= 0)
72 dup2(s1, 1), close(s1);
73 if (s2 >= 0)
74 dup2(s2, 2), close(s2);
76 if (pid < 0) {
77 if (output)
78 close_pair(fdout);
79 if (error_output)
80 close_pair(fderr);
81 return -ERR_RUN_COMMAND_FORK;
84 if (output)
85 close(fdout[1]);
86 if (error_output)
87 close(fderr[1]);
89 if (WAITMODE & flags) {
90 ret = wait_for_process(pid, MAX_PROCESSING_TIME,
91 &status);
92 if (ret) {
93 if (ret < 0) {
94 debug_git("[ERROR] wait_for_process failed (%d); "
95 "wd: %s; cmd: %s",
96 status,
97 working_directory,
98 argv[0]);
100 status = -1;
103 if (output) {
104 strbuf_read(output, fdout[0], 0);
105 debug_git("STDOUT:\r\n%s\r\n*** end of STDOUT ***\r\n", output->buf);
108 if (error_output) {
109 strbuf_read(error_output, fderr[0], 0);
110 debug_git("STDERR:\r\n%s\r\n*** end of STDERR ***\r\n", error_output->buf);
112 } else {
113 status = -ERR_RUN_COMMAND_WAITPID_NOEXIT;
114 debug_git("[ERROR] process timed out; "
115 "wd: %s; cmd: %s",
116 working_directory, argv[0]);
120 if (output)
121 close(fdout[0]);
122 if (error_output)
123 close(fderr[0]);
125 return status;