🌐 AI搜索 & 代理 主页
blob: 9d5703a157fe8e9d8396e0771798e54dc5eea6eb [file] [log] [blame]
Michal Ostrowski77cb17e2006-01-11 02:12:171#include "cache.h"
2#include "exec_cmd.h"
Matthias Lederhofer575ba9d2006-06-25 13:56:183#include "quote.h"
Jeff King20574f52016-02-22 22:44:394#include "argv-array.h"
Michal Ostrowski77cb17e2006-01-11 02:12:175#define MAX_ARGS 32
6
Scott R Parish384df832007-10-27 08:36:517static const char *argv_exec_path;
Johannes Sixte1464ca2008-07-21 19:19:528static const char *argv0_path;
Michal Ostrowski77cb17e2006-01-11 02:12:179
Junio C Hamano59362e52014-11-24 19:33:5410char *system_path(const char *path)
Steffen Prohaska2de9de52008-07-13 20:31:1811{
Steffen Prohaska35fb0e862009-01-18 12:00:1412#ifdef RUNTIME_PREFIX
13 static const char *prefix;
14#else
Steffen Prohaska026fa0d2009-01-18 12:00:0915 static const char *prefix = PREFIX;
Steffen Prohaska35fb0e862009-01-18 12:00:1416#endif
Steffen Prohaska026fa0d2009-01-18 12:00:0917 struct strbuf d = STRBUF_INIT;
18
19 if (is_absolute_path(path))
Junio C Hamano59362e52014-11-24 19:33:5420 return xstrdup(path);
Steffen Prohaska026fa0d2009-01-18 12:00:0921
Steffen Prohaska35fb0e862009-01-18 12:00:1422#ifdef RUNTIME_PREFIX
23 assert(argv0_path);
24 assert(is_absolute_path(argv0_path));
25
Johannes Schindelin024aa7d2009-02-19 19:10:5326 if (!prefix &&
27 !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
28 !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
29 !(prefix = strip_path_suffix(argv0_path, "git"))) {
Steffen Prohaska35fb0e862009-01-18 12:00:1430 prefix = PREFIX;
Johannes Sixtaa094572010-02-23 11:42:5631 trace_printf("RUNTIME_PREFIX requested, "
Steffen Prohaska35fb0e862009-01-18 12:00:1432 "but prefix computation failed. "
33 "Using static fallback '%s'.\n", prefix);
34 }
35#endif
36
Steffen Prohaska026fa0d2009-01-18 12:00:0937 strbuf_addf(&d, "%s/%s", prefix, path);
Junio C Hamano59362e52014-11-24 19:33:5438 return strbuf_detach(&d, NULL);
Steffen Prohaska2de9de52008-07-13 20:31:1839}
40
Steve Haslam4dd47c32009-01-18 12:00:1041const char *git_extract_argv0_path(const char *argv0)
Johannes Sixte1464ca2008-07-21 19:19:5242{
Steffen Prohaska2cd72b02009-01-18 12:00:1143 const char *slash;
44
45 if (!argv0 || !*argv0)
46 return NULL;
Steve Haslam4dd47c32009-01-18 12:00:1047
Alexander Kuleshovf4598232016-02-19 08:44:4848 slash = find_last_dir_sep(argv0);
Steve Haslam4dd47c32009-01-18 12:00:1049
Alexander Kuleshovf4598232016-02-19 08:44:4850 if (slash) {
Steve Haslam4dd47c32009-01-18 12:00:1051 argv0_path = xstrndup(argv0, slash - argv0);
52 return slash + 1;
53 }
54
55 return argv0;
Johannes Sixte1464ca2008-07-21 19:19:5256}
57
Scott R Parish384df832007-10-27 08:36:5158void git_set_argv_exec_path(const char *exec_path)
Michal Ostrowski77cb17e2006-01-11 02:12:1759{
Scott R Parish384df832007-10-27 08:36:5160 argv_exec_path = exec_path;
Johannes Sixtc90d5652009-03-21 22:21:1861 /*
62 * Propagate this setting to external programs.
63 */
64 setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
Michal Ostrowski77cb17e2006-01-11 02:12:1765}
66
67
68/* Returns the highest-priority, location to look for git programs. */
Timo Hirvonen962554c2006-02-26 15:13:4669const char *git_exec_path(void)
Michal Ostrowski77cb17e2006-01-11 02:12:1770{
71 const char *env;
72
Scott R Parish384df832007-10-27 08:36:5173 if (argv_exec_path)
74 return argv_exec_path;
Michal Ostrowski77cb17e2006-01-11 02:12:1775
Junio C Hamanod4ebc362006-12-19 09:28:1576 env = getenv(EXEC_PATH_ENVIRONMENT);
Dmitry V. Levin2b601622006-05-29 00:34:3477 if (env && *env) {
Michal Ostrowski77cb17e2006-01-11 02:12:1778 return env;
79 }
80
Johannes Sixt49fa65a2008-07-23 19:12:1881 return system_path(GIT_EXEC_PATH);
Michal Ostrowski77cb17e2006-01-11 02:12:1782}
83
Scott R Parish511707d2007-10-28 11:17:2084static void add_path(struct strbuf *out, const char *path)
85{
86 if (path && *path) {
René Scharfe9610dec2014-07-28 18:34:4287 strbuf_add_absolute_path(out, path);
Johannes Sixt80ba0742007-12-03 20:55:5788 strbuf_addch(out, PATH_SEP);
Scott R Parish511707d2007-10-28 11:17:2089 }
90}
91
Johannes Sixte1464ca2008-07-21 19:19:5292void setup_path(void)
Scott R Parish511707d2007-10-28 11:17:2093{
94 const char *old_path = getenv("PATH");
Brandon Caseyf285a2d2008-10-09 19:12:1295 struct strbuf new_path = STRBUF_INIT;
Scott R Parish511707d2007-10-28 11:17:2096
Steffen Prohaska8e346282009-01-18 12:00:1397 add_path(&new_path, git_exec_path());
Scott R Parish511707d2007-10-28 11:17:2098
99 if (old_path)
100 strbuf_addstr(&new_path, old_path);
101 else
Chris Webbcb6a22c2010-04-13 09:07:13102 strbuf_addstr(&new_path, _PATH_DEFPATH);
Scott R Parish511707d2007-10-28 11:17:20103
104 setenv("PATH", new_path.buf, 1);
105
106 strbuf_release(&new_path);
107}
Michal Ostrowski77cb17e2006-01-11 02:12:17108
Jeff King20574f52016-02-22 22:44:39109const char **prepare_git_cmd(struct argv_array *out, const char **argv)
Michal Ostrowski77cb17e2006-01-11 02:12:17110{
Jeff King20574f52016-02-22 22:44:39111 argv_array_push(out, "git");
112 argv_array_pushv(out, argv);
113 return out->argv;
Steffen Prohaska4933e5e2008-07-28 05:50:27114}
115
116int execv_git_cmd(const char **argv) {
Jeff King20574f52016-02-22 22:44:39117 struct argv_array nargv = ARGV_ARRAY_INIT;
118
119 prepare_git_cmd(&nargv, argv);
120 trace_argv_printf(nargv.argv, "trace: exec:");
Michal Ostrowski77cb17e2006-01-11 02:12:17121
Scott R Parish511707d2007-10-28 11:17:20122 /* execvp() can only ever return if it fails */
Jeff King20574f52016-02-22 22:44:39123 sane_execvp("git", (char **)nargv.argv);
Dmitry V. Levind6859902006-05-30 14:58:52124
Scott R Parish511707d2007-10-28 11:17:20125 trace_printf("trace: exec failed: %s\n", strerror(errno));
Michal Ostrowski77cb17e2006-01-11 02:12:17126
Jeff King20574f52016-02-22 22:44:39127 argv_array_clear(&nargv);
Michal Ostrowski77cb17e2006-01-11 02:12:17128 return -1;
Michal Ostrowski77cb17e2006-01-11 02:12:17129}
130
131
Junio C Hamano9201c702006-03-05 10:47:29132int execl_git_cmd(const char *cmd,...)
Michal Ostrowski77cb17e2006-01-11 02:12:17133{
134 int argc;
Junio C Hamano9201c702006-03-05 10:47:29135 const char *argv[MAX_ARGS + 1];
136 const char *arg;
Michal Ostrowski77cb17e2006-01-11 02:12:17137 va_list param;
138
139 va_start(param, cmd);
140 argv[0] = cmd;
141 argc = 1;
142 while (argc < MAX_ARGS) {
143 arg = argv[argc++] = va_arg(param, char *);
144 if (!arg)
145 break;
146 }
147 va_end(param);
148 if (MAX_ARGS <= argc)
149 return error("too many args to run %s", cmd);
150
151 argv[argc] = NULL;
152 return execv_git_cmd(argv);
153}