Merge branch 'master' of git://repo.or.cz/alt-git
[git/dscho.git] / exec_cmd.c
blob6aa842bb4f11b0eba5daca83dc3746c51a5c579f
1 #include "cache.h"
2 #include "exec_cmd.h"
3 #include "quote.h"
4 #include "spawn-pipe.h"
5 #define MAX_ARGS 32
7 extern char **environ;
8 static const char *argv_exec_path;
10 static const char *builtin_exec_path(void)
12 #ifndef __MINGW32__
13 return GIT_EXEC_PATH;
14 #else
15 int len;
16 char *p, *q, *sl;
17 static char *ep;
18 if (ep)
19 return ep;
21 len = strlen(_pgmptr);
22 if (len < 2)
23 return ep = ".";
25 p = ep = xmalloc(len+1);
26 q = _pgmptr;
27 sl = NULL;
28 /* copy program name, turn '\\' into '/', skip last part */
29 while ((*p = *q)) {
30 if (*q == '\\' || *q == '/') {
31 *p = '/';
32 sl = p;
34 p++, q++;
36 if (sl)
37 *sl = '\0';
38 else
39 ep[0] = '.', ep[1] = '\0';
40 return ep;
41 #endif
44 void git_set_argv_exec_path(const char *exec_path)
46 argv_exec_path = exec_path;
50 /* Returns the highest-priority, location to look for git programs. */
51 const char *git_exec_path(void)
53 const char *env;
55 if (argv_exec_path)
56 return argv_exec_path;
58 env = getenv(EXEC_PATH_ENVIRONMENT);
59 if (env && *env) {
60 return env;
63 return builtin_exec_path();
66 static void add_path(struct strbuf *out, const char *path)
68 if (path && *path) {
69 if (is_absolute_path(path))
70 strbuf_addstr(out, path);
71 else
72 strbuf_addstr(out, make_absolute_path(path));
74 #ifdef __MINGW32__
75 strbuf_addch(out, ';');
76 #else
77 strbuf_addch(out, ':');
78 #endif
82 void setup_path(const char *cmd_path)
84 const char *old_path = getenv("PATH");
85 struct strbuf new_path;
87 strbuf_init(&new_path, 0);
89 add_path(&new_path, argv_exec_path);
90 add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT));
91 add_path(&new_path, builtin_exec_path());
92 add_path(&new_path, cmd_path);
94 if (old_path)
95 strbuf_addstr(&new_path, old_path);
96 else
97 strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
99 setenv("PATH", new_path.buf, 1);
101 strbuf_release(&new_path);
104 int execv_git_cmd(const char **argv)
106 struct strbuf cmd;
107 const char *tmp;
109 strbuf_init(&cmd, 0);
110 strbuf_addf(&cmd, "git-%s", argv[0]);
113 * argv[0] must be the git command, but the argv array
114 * belongs to the caller, and may be reused in
115 * subsequent loop iterations. Save argv[0] and
116 * restore it on error.
118 tmp = argv[0];
119 argv[0] = cmd.buf;
121 trace_argv_printf(argv, -1, "trace: exec:");
123 /* execvp() can only ever return if it fails */
124 execvp(cmd.buf, (char **)argv);
126 trace_printf("trace: exec failed: %s\n", strerror(errno));
128 argv[0] = tmp;
130 strbuf_release(&cmd);
132 return -1;
136 int execl_git_cmd(const char *cmd,...)
138 int argc;
139 const char *argv[MAX_ARGS + 1];
140 const char *arg;
141 va_list param;
143 va_start(param, cmd);
144 argv[0] = cmd;
145 argc = 1;
146 while (argc < MAX_ARGS) {
147 arg = argv[argc++] = va_arg(param, char *);
148 if (!arg)
149 break;
151 va_end(param);
152 if (MAX_ARGS <= argc)
153 return error("too many args to run %s", cmd);
155 argv[argc] = NULL;
156 return execv_git_cmd(argv);
159 int spawnv_git_cmd(const char **argv, int pin[2], int pout[2])
161 pid_t pid;
162 struct strbuf cmd;
163 const char *tmp;
165 strbuf_init(&cmd, 0);
166 strbuf_addf(&cmd, "git-%s", argv[0]);
168 /* argv[0] must be the git command, but the argv array
169 * belongs to the caller. Save argv[0] and
170 * restore it later.
173 tmp = argv[0];
174 argv[0] = cmd.buf;
176 trace_argv_printf(argv, -1, "trace: exec:");
178 pid = spawnvpe_pipe(cmd.buf, argv, environ,
179 pin, pout);
181 argv[0] = tmp;
182 return pid;