]>
Commit | Line | Data |
---|---|---|
77cb17e9 MO |
1 | #include "cache.h" |
2 | #include "exec_cmd.h" | |
575ba9d6 | 3 | #include "quote.h" |
77cb17e9 MO |
4 | #define MAX_ARGS 32 |
5 | ||
6 | extern char **environ; | |
384df833 | 7 | static const char *argv_exec_path; |
77cb17e9 | 8 | |
4ec22a48 JS |
9 | static const char *builtin_exec_path(void) |
10 | { | |
6fad004a | 11 | #ifndef __MINGW32__ |
4ec22a48 | 12 | return GIT_EXEC_PATH; |
6fad004a JS |
13 | #else |
14 | int len; | |
15 | char *p, *q, *sl; | |
16 | static char *ep; | |
17 | if (ep) | |
18 | return ep; | |
19 | ||
20 | len = strlen(_pgmptr); | |
21 | if (len < 2) | |
22 | return ep = "."; | |
23 | ||
24 | p = ep = xmalloc(len+1); | |
25 | q = _pgmptr; | |
26 | sl = NULL; | |
27 | /* copy program name, turn '\\' into '/', skip last part */ | |
28 | while ((*p = *q)) { | |
29 | if (*q == '\\' || *q == '/') { | |
30 | *p = '/'; | |
31 | sl = p; | |
32 | } | |
33 | p++, q++; | |
34 | } | |
35 | if (sl) | |
36 | *sl = '\0'; | |
37 | else | |
38 | ep[0] = '.', ep[1] = '\0'; | |
39 | return ep; | |
40 | #endif | |
4ec22a48 JS |
41 | } |
42 | ||
2de9de5e SP |
43 | const char *system_path(const char *path) |
44 | { | |
45 | if (!is_absolute_path(path)) { | |
46 | struct strbuf d = STRBUF_INIT; | |
47 | strbuf_addf(&d, "%s/%s", git_exec_path(), path); | |
48 | path = strbuf_detach(&d, NULL); | |
49 | } | |
50 | return path; | |
51 | } | |
52 | ||
384df833 | 53 | void git_set_argv_exec_path(const char *exec_path) |
77cb17e9 | 54 | { |
384df833 | 55 | argv_exec_path = exec_path; |
77cb17e9 MO |
56 | } |
57 | ||
58 | ||
59 | /* Returns the highest-priority, location to look for git programs. */ | |
962554c6 | 60 | const char *git_exec_path(void) |
77cb17e9 MO |
61 | { |
62 | const char *env; | |
63 | ||
384df833 SP |
64 | if (argv_exec_path) |
65 | return argv_exec_path; | |
77cb17e9 | 66 | |
d4ebc36c | 67 | env = getenv(EXEC_PATH_ENVIRONMENT); |
2b601626 | 68 | if (env && *env) { |
77cb17e9 MO |
69 | return env; |
70 | } | |
71 | ||
4ec22a48 | 72 | return builtin_exec_path(); |
77cb17e9 MO |
73 | } |
74 | ||
511707d4 SP |
75 | static void add_path(struct strbuf *out, const char *path) |
76 | { | |
77 | if (path && *path) { | |
78 | if (is_absolute_path(path)) | |
79 | strbuf_addstr(out, path); | |
80 | else | |
81 | strbuf_addstr(out, make_absolute_path(path)); | |
82 | ||
80ba074f | 83 | strbuf_addch(out, PATH_SEP); |
511707d4 SP |
84 | } |
85 | } | |
86 | ||
87 | void setup_path(const char *cmd_path) | |
88 | { | |
89 | const char *old_path = getenv("PATH"); | |
90 | struct strbuf new_path; | |
91 | ||
92 | strbuf_init(&new_path, 0); | |
93 | ||
94 | add_path(&new_path, argv_exec_path); | |
95 | add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT)); | |
4ec22a48 | 96 | add_path(&new_path, builtin_exec_path()); |
511707d4 SP |
97 | add_path(&new_path, cmd_path); |
98 | ||
99 | if (old_path) | |
100 | strbuf_addstr(&new_path, old_path); | |
101 | else | |
102 | strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin"); | |
103 | ||
104 | setenv("PATH", new_path.buf, 1); | |
105 | ||
106 | strbuf_release(&new_path); | |
107 | } | |
77cb17e9 | 108 | |
9201c707 | 109 | int execv_git_cmd(const char **argv) |
77cb17e9 | 110 | { |
7550be0a JH |
111 | int argc; |
112 | const char **nargv; | |
77cb17e9 | 113 | |
7550be0a JH |
114 | for (argc = 0; argv[argc]; argc++) |
115 | ; /* just counting */ | |
116 | nargv = xmalloc(sizeof(*nargv) * (argc + 2)); | |
77cb17e9 | 117 | |
7550be0a JH |
118 | nargv[0] = "git"; |
119 | for (argc = 0; argv[argc]; argc++) | |
120 | nargv[argc + 1] = argv[argc]; | |
121 | nargv[argc + 1] = NULL; | |
122 | trace_argv_printf(nargv, "trace: exec:"); | |
575ba9d6 | 123 | |
511707d4 | 124 | /* execvp() can only ever return if it fails */ |
7550be0a | 125 | execvp("git", (char **)nargv); |
77cb17e9 | 126 | |
511707d4 | 127 | trace_printf("trace: exec failed: %s\n", strerror(errno)); |
575ba9d6 | 128 | |
7550be0a | 129 | free(nargv); |
511707d4 | 130 | return -1; |
77cb17e9 MO |
131 | } |
132 | ||
133 | ||
9201c707 | 134 | int execl_git_cmd(const char *cmd,...) |
77cb17e9 MO |
135 | { |
136 | int argc; | |
9201c707 JH |
137 | const char *argv[MAX_ARGS + 1]; |
138 | const char *arg; | |
77cb17e9 MO |
139 | va_list param; |
140 | ||
141 | va_start(param, cmd); | |
142 | argv[0] = cmd; | |
143 | argc = 1; | |
144 | while (argc < MAX_ARGS) { | |
145 | arg = argv[argc++] = va_arg(param, char *); | |
146 | if (!arg) | |
147 | break; | |
148 | } | |
149 | va_end(param); | |
150 | if (MAX_ARGS <= argc) | |
151 | return error("too many args to run %s", cmd); | |
152 | ||
153 | argv[argc] = NULL; | |
154 | return execv_git_cmd(argv); | |
155 | } |