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