From 9fef956317af21ee8bd56b3ee9ee60c4ec1e66dc Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 26 Jul 2008 16:12:56 +0200 Subject: [PATCH] Set up argv0_path correctly, even when argv[0] is just the basename When the program 'git' is in the PATH, the argv[0] is set to the basename. However, argv0_path needs the full path, so add a function to discover the program by traversing the PATH manually. Signed-off-by: Johannes Schindelin --- exec_cmd.c | 29 +++++++++++++++++++++++++++++ exec_cmd.h | 1 + 2 files changed, 30 insertions(+) diff --git a/exec_cmd.c b/exec_cmd.c index 408e4e55e1..8207dd2c35 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -50,6 +50,13 @@ const char *git_extract_argv0_path(const char *argv0) while (argv0 <= slash && !is_dir_sep(*slash)) slash--; + if (slash == argv0) { + argv0 = lookup_program_in_path(argv0); + slash = argv0 + strlen(argv0); + while (argv0 <= slash && !is_dir_sep(*slash)) + slash--; + } + if (slash >= argv0) { argv0_path = xstrndup(argv0, slash - argv0); return slash + 1; @@ -166,3 +173,25 @@ int execl_git_cmd(const char *cmd,...) argv[argc] = NULL; return execv_git_cmd(argv); } + +char *lookup_program_in_path(const char *program) +{ + struct strbuf buf = STRBUF_INIT; + const char *path = getenv("PATH"); + + if (!path || !*path) + return NULL; + + for (;;) { + const char *colon = strchrnul(path, PATH_SEP); + + strbuf_setlen(&buf, 0); + strbuf_addf(&buf, "%.*s/%s", + (int)(colon - path), path, program); + if (!access(buf.buf, X_OK)) + return strbuf_detach(&buf, NULL); + if (!*colon) + return NULL; + path = colon + 1; + } +} diff --git a/exec_cmd.h b/exec_cmd.h index e2b546b615..89f86b66cc 100644 --- a/exec_cmd.h +++ b/exec_cmd.h @@ -9,5 +9,6 @@ extern const char **prepare_git_cmd(const char **argv); extern int execv_git_cmd(const char **argv); /* NULL terminated */ extern int execl_git_cmd(const char *cmd, ...); extern const char *system_path(const char *path); +extern char *lookup_program_in_path(const char *program); #endif /* GIT_EXEC_CMD_H */ -- 2.11.4.GIT