]>
Commit | Line | Data |
---|---|---|
77cb17e9 | 1 | #include "cache.h" |
d807c4a0 | 2 | #include "exec-cmd.h" |
575ba9d6 | 3 | #include "quote.h" |
20574f55 | 4 | #include "argv-array.h" |
77cb17e9 MO |
5 | #define MAX_ARGS 32 |
6 | ||
384df833 | 7 | static const char *argv_exec_path; |
77cb17e9 | 8 | |
35fb0e86 | 9 | #ifdef RUNTIME_PREFIX |
c1bb33c9 | 10 | static const char *argv0_path; |
026fa0d5 | 11 | |
39b2f6af JK |
12 | static const char *system_prefix(void) |
13 | { | |
14 | static const char *prefix; | |
026fa0d5 | 15 | |
35fb0e86 SP |
16 | assert(argv0_path); |
17 | assert(is_absolute_path(argv0_path)); | |
18 | ||
024aa7d8 JS |
19 | if (!prefix && |
20 | !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) && | |
21 | !(prefix = strip_path_suffix(argv0_path, BINDIR)) && | |
22 | !(prefix = strip_path_suffix(argv0_path, "git"))) { | |
35fb0e86 | 23 | prefix = PREFIX; |
aa094570 | 24 | trace_printf("RUNTIME_PREFIX requested, " |
35fb0e86 SP |
25 | "but prefix computation failed. " |
26 | "Using static fallback '%s'.\n", prefix); | |
27 | } | |
39b2f6af JK |
28 | return prefix; |
29 | } | |
c1bb33c9 JK |
30 | |
31 | void git_extract_argv0_path(const char *argv0) | |
32 | { | |
33 | const char *slash; | |
34 | ||
35 | if (!argv0 || !*argv0) | |
36 | return; | |
37 | ||
38 | slash = find_last_dir_sep(argv0); | |
39 | ||
40 | if (slash) | |
41 | argv0_path = xstrndup(argv0, slash - argv0); | |
42 | } | |
43 | ||
39b2f6af JK |
44 | #else |
45 | ||
46 | static const char *system_prefix(void) | |
47 | { | |
48 | return PREFIX; | |
49 | } | |
50 | ||
c1bb33c9 JK |
51 | void git_extract_argv0_path(const char *argv0) |
52 | { | |
53 | } | |
54 | ||
39b2f6af JK |
55 | #endif /* RUNTIME_PREFIX */ |
56 | ||
57 | char *system_path(const char *path) | |
58 | { | |
59 | struct strbuf d = STRBUF_INIT; | |
60 | ||
61 | if (is_absolute_path(path)) | |
62 | return xstrdup(path); | |
35fb0e86 | 63 | |
39b2f6af | 64 | strbuf_addf(&d, "%s/%s", system_prefix(), path); |
59362e56 | 65 | return strbuf_detach(&d, NULL); |
2de9de5e SP |
66 | } |
67 | ||
384df833 | 68 | void git_set_argv_exec_path(const char *exec_path) |
77cb17e9 | 69 | { |
384df833 | 70 | argv_exec_path = exec_path; |
c90d565a JS |
71 | /* |
72 | * Propagate this setting to external programs. | |
73 | */ | |
74 | setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1); | |
77cb17e9 MO |
75 | } |
76 | ||
77 | ||
78 | /* Returns the highest-priority, location to look for git programs. */ | |
962554c6 | 79 | const char *git_exec_path(void) |
77cb17e9 | 80 | { |
007ac544 | 81 | static char *cached_exec_path; |
77cb17e9 | 82 | |
384df833 SP |
83 | if (argv_exec_path) |
84 | return argv_exec_path; | |
77cb17e9 | 85 | |
007ac544 JK |
86 | if (!cached_exec_path) { |
87 | const char *env = getenv(EXEC_PATH_ENVIRONMENT); | |
88 | if (env && *env) | |
89 | cached_exec_path = xstrdup(env); | |
90 | else | |
91 | cached_exec_path = system_path(GIT_EXEC_PATH); | |
77cb17e9 | 92 | } |
007ac544 | 93 | return cached_exec_path; |
77cb17e9 MO |
94 | } |
95 | ||
511707d4 SP |
96 | static void add_path(struct strbuf *out, const char *path) |
97 | { | |
98 | if (path && *path) { | |
9610decf | 99 | strbuf_add_absolute_path(out, path); |
80ba074f | 100 | strbuf_addch(out, PATH_SEP); |
511707d4 SP |
101 | } |
102 | } | |
103 | ||
e1464ca7 | 104 | void setup_path(void) |
511707d4 SP |
105 | { |
106 | const char *old_path = getenv("PATH"); | |
f285a2d7 | 107 | struct strbuf new_path = STRBUF_INIT; |
511707d4 | 108 | |
8e346283 | 109 | add_path(&new_path, git_exec_path()); |
511707d4 SP |
110 | |
111 | if (old_path) | |
112 | strbuf_addstr(&new_path, old_path); | |
113 | else | |
cb6a22c0 | 114 | strbuf_addstr(&new_path, _PATH_DEFPATH); |
511707d4 SP |
115 | |
116 | setenv("PATH", new_path.buf, 1); | |
117 | ||
118 | strbuf_release(&new_path); | |
119 | } | |
77cb17e9 | 120 | |
20574f55 | 121 | const char **prepare_git_cmd(struct argv_array *out, const char **argv) |
77cb17e9 | 122 | { |
20574f55 JK |
123 | argv_array_push(out, "git"); |
124 | argv_array_pushv(out, argv); | |
125 | return out->argv; | |
4933e5eb SP |
126 | } |
127 | ||
128 | int execv_git_cmd(const char **argv) { | |
20574f55 JK |
129 | struct argv_array nargv = ARGV_ARRAY_INIT; |
130 | ||
131 | prepare_git_cmd(&nargv, argv); | |
132 | trace_argv_printf(nargv.argv, "trace: exec:"); | |
575ba9d6 | 133 | |
511707d4 | 134 | /* execvp() can only ever return if it fails */ |
20574f55 | 135 | sane_execvp("git", (char **)nargv.argv); |
77cb17e9 | 136 | |
511707d4 | 137 | trace_printf("trace: exec failed: %s\n", strerror(errno)); |
575ba9d6 | 138 | |
20574f55 | 139 | argv_array_clear(&nargv); |
511707d4 | 140 | return -1; |
77cb17e9 MO |
141 | } |
142 | ||
143 | ||
9201c707 | 144 | int execl_git_cmd(const char *cmd,...) |
77cb17e9 MO |
145 | { |
146 | int argc; | |
9201c707 JH |
147 | const char *argv[MAX_ARGS + 1]; |
148 | const char *arg; | |
77cb17e9 MO |
149 | va_list param; |
150 | ||
151 | va_start(param, cmd); | |
152 | argv[0] = cmd; | |
153 | argc = 1; | |
154 | while (argc < MAX_ARGS) { | |
155 | arg = argv[argc++] = va_arg(param, char *); | |
156 | if (!arg) | |
157 | break; | |
158 | } | |
159 | va_end(param); | |
160 | if (MAX_ARGS <= argc) | |
161 | return error("too many args to run %s", cmd); | |
162 | ||
163 | argv[argc] = NULL; | |
164 | return execv_git_cmd(argv); | |
165 | } |