diff options
Diffstat (limited to 'exec_cmd.c')
-rw-r--r-- | exec_cmd.c | 104 |
1 files changed, 51 insertions, 53 deletions
diff --git a/exec_cmd.c b/exec_cmd.c index 38545e8bfd..ce192a2d64 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -1,24 +1,18 @@ #include "cache.h" #include "exec_cmd.h" #include "quote.h" +#include "argv-array.h" #define MAX_ARGS 32 static const char *argv_exec_path; + +#ifdef RUNTIME_PREFIX static const char *argv0_path; -const char *system_path(const char *path) +static const char *system_prefix(void) { -#ifdef RUNTIME_PREFIX static const char *prefix; -#else - static const char *prefix = PREFIX; -#endif - struct strbuf d = STRBUF_INIT; - if (is_absolute_path(path)) - return path; - -#ifdef RUNTIME_PREFIX assert(argv0_path); assert(is_absolute_path(argv0_path)); @@ -31,30 +25,44 @@ const char *system_path(const char *path) "but prefix computation failed. " "Using static fallback '%s'.\n", prefix); } -#endif - - strbuf_addf(&d, "%s/%s", prefix, path); - path = strbuf_detach(&d, NULL); - return path; + return prefix; } -const char *git_extract_argv0_path(const char *argv0) +void git_extract_argv0_path(const char *argv0) { const char *slash; if (!argv0 || !*argv0) - return NULL; - slash = argv0 + strlen(argv0); + return; - while (argv0 <= slash && !is_dir_sep(*slash)) - slash--; + slash = find_last_dir_sep(argv0); - if (slash >= argv0) { + if (slash) argv0_path = xstrndup(argv0, slash - argv0); - return slash + 1; - } +} + +#else - return argv0; +static const char *system_prefix(void) +{ + return PREFIX; +} + +void git_extract_argv0_path(const char *argv0) +{ +} + +#endif /* RUNTIME_PREFIX */ + +char *system_path(const char *path) +{ + struct strbuf d = STRBUF_INIT; + + if (is_absolute_path(path)) + return xstrdup(path); + + strbuf_addf(&d, "%s/%s", system_prefix(), path); + return strbuf_detach(&d, NULL); } void git_set_argv_exec_path(const char *exec_path) @@ -70,27 +78,25 @@ void git_set_argv_exec_path(const char *exec_path) /* Returns the highest-priority, location to look for git programs. */ const char *git_exec_path(void) { - const char *env; + static char *cached_exec_path; if (argv_exec_path) return argv_exec_path; - env = getenv(EXEC_PATH_ENVIRONMENT); - if (env && *env) { - return env; + if (!cached_exec_path) { + const char *env = getenv(EXEC_PATH_ENVIRONMENT); + if (env && *env) + cached_exec_path = xstrdup(env); + else + cached_exec_path = system_path(GIT_EXEC_PATH); } - - return system_path(GIT_EXEC_PATH); + return cached_exec_path; } static void add_path(struct strbuf *out, const char *path) { if (path && *path) { - if (is_absolute_path(path)) - strbuf_addstr(out, path); - else - strbuf_addstr(out, make_nonrelative_path(path)); - + strbuf_add_absolute_path(out, path); strbuf_addch(out, PATH_SEP); } } @@ -101,7 +107,6 @@ void setup_path(void) struct strbuf new_path = STRBUF_INIT; add_path(&new_path, git_exec_path()); - add_path(&new_path, argv0_path); if (old_path) strbuf_addstr(&new_path, old_path); @@ -113,32 +118,25 @@ void setup_path(void) strbuf_release(&new_path); } -const char **prepare_git_cmd(const char **argv) +const char **prepare_git_cmd(struct argv_array *out, const char **argv) { - int argc; - const char **nargv; - - for (argc = 0; argv[argc]; argc++) - ; /* just counting */ - nargv = xmalloc(sizeof(*nargv) * (argc + 2)); - - nargv[0] = "git"; - for (argc = 0; argv[argc]; argc++) - nargv[argc + 1] = argv[argc]; - nargv[argc + 1] = NULL; - return nargv; + argv_array_push(out, "git"); + argv_array_pushv(out, argv); + return out->argv; } int execv_git_cmd(const char **argv) { - const char **nargv = prepare_git_cmd(argv); - trace_argv_printf(nargv, "trace: exec:"); + struct argv_array nargv = ARGV_ARRAY_INIT; + + prepare_git_cmd(&nargv, argv); + trace_argv_printf(nargv.argv, "trace: exec:"); /* execvp() can only ever return if it fails */ - execvp("git", (char **)nargv); + sane_execvp("git", (char **)nargv.argv); trace_printf("trace: exec failed: %s\n", strerror(errno)); - free(nargv); + argv_array_clear(&nargv); return -1; } |