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