]>
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; | |
7 | static const char *builtin_exec_path = GIT_EXEC_PATH; | |
384df833 | 8 | static const char *argv_exec_path; |
77cb17e9 | 9 | |
384df833 | 10 | void git_set_argv_exec_path(const char *exec_path) |
77cb17e9 | 11 | { |
384df833 | 12 | argv_exec_path = exec_path; |
77cb17e9 MO |
13 | } |
14 | ||
15 | ||
16 | /* Returns the highest-priority, location to look for git programs. */ | |
962554c6 | 17 | const char *git_exec_path(void) |
77cb17e9 MO |
18 | { |
19 | const char *env; | |
20 | ||
384df833 SP |
21 | if (argv_exec_path) |
22 | return argv_exec_path; | |
77cb17e9 | 23 | |
d4ebc36c | 24 | env = getenv(EXEC_PATH_ENVIRONMENT); |
2b601626 | 25 | if (env && *env) { |
77cb17e9 MO |
26 | return env; |
27 | } | |
28 | ||
29 | return builtin_exec_path; | |
30 | } | |
31 | ||
511707d4 SP |
32 | static void add_path(struct strbuf *out, const char *path) |
33 | { | |
34 | if (path && *path) { | |
35 | if (is_absolute_path(path)) | |
36 | strbuf_addstr(out, path); | |
37 | else | |
38 | strbuf_addstr(out, make_absolute_path(path)); | |
39 | ||
40 | strbuf_addch(out, ':'); | |
41 | } | |
42 | } | |
43 | ||
44 | void setup_path(const char *cmd_path) | |
45 | { | |
46 | const char *old_path = getenv("PATH"); | |
47 | struct strbuf new_path; | |
48 | ||
49 | strbuf_init(&new_path, 0); | |
50 | ||
51 | add_path(&new_path, argv_exec_path); | |
52 | add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT)); | |
53 | add_path(&new_path, builtin_exec_path); | |
54 | add_path(&new_path, cmd_path); | |
55 | ||
56 | if (old_path) | |
57 | strbuf_addstr(&new_path, old_path); | |
58 | else | |
59 | strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin"); | |
60 | ||
61 | setenv("PATH", new_path.buf, 1); | |
62 | ||
63 | strbuf_release(&new_path); | |
64 | } | |
77cb17e9 | 65 | |
9201c707 | 66 | int execv_git_cmd(const char **argv) |
77cb17e9 | 67 | { |
511707d4 SP |
68 | struct strbuf cmd; |
69 | const char *tmp; | |
77cb17e9 | 70 | |
511707d4 SP |
71 | strbuf_init(&cmd, 0); |
72 | strbuf_addf(&cmd, "git-%s", argv[0]); | |
77cb17e9 | 73 | |
511707d4 SP |
74 | /* |
75 | * argv[0] must be the git command, but the argv array | |
76 | * belongs to the caller, and may be reused in | |
77 | * subsequent loop iterations. Save argv[0] and | |
78 | * restore it on error. | |
79 | */ | |
80 | tmp = argv[0]; | |
81 | argv[0] = cmd.buf; | |
77cb17e9 | 82 | |
b319ce4c | 83 | trace_argv_printf(argv, "trace: exec:"); |
575ba9d6 | 84 | |
511707d4 SP |
85 | /* execvp() can only ever return if it fails */ |
86 | execvp(cmd.buf, (char **)argv); | |
77cb17e9 | 87 | |
511707d4 | 88 | trace_printf("trace: exec failed: %s\n", strerror(errno)); |
575ba9d6 | 89 | |
511707d4 | 90 | argv[0] = tmp; |
77cb17e9 | 91 | |
511707d4 SP |
92 | strbuf_release(&cmd); |
93 | ||
94 | return -1; | |
77cb17e9 MO |
95 | } |
96 | ||
97 | ||
9201c707 | 98 | int execl_git_cmd(const char *cmd,...) |
77cb17e9 MO |
99 | { |
100 | int argc; | |
9201c707 JH |
101 | const char *argv[MAX_ARGS + 1]; |
102 | const char *arg; | |
77cb17e9 MO |
103 | va_list param; |
104 | ||
105 | va_start(param, cmd); | |
106 | argv[0] = cmd; | |
107 | argc = 1; | |
108 | while (argc < MAX_ARGS) { | |
109 | arg = argv[argc++] = va_arg(param, char *); | |
110 | if (!arg) | |
111 | break; | |
112 | } | |
113 | va_end(param); | |
114 | if (MAX_ARGS <= argc) | |
115 | return error("too many args to run %s", cmd); | |
116 | ||
117 | argv[argc] = NULL; | |
118 | return execv_git_cmd(argv); | |
119 | } |