On Tue, Nov 27, 2012 at 5:30 PM, Michael Weiser <M.Weiser@xxxxxxxxxxxxxxxxxxxx> wrote: > Support determining the binaries' installation path at runtime even if > called without any path components (i.e. via search path). Implement > fallback to compiled-in prefix if determination fails or is impossible. > > Signed-off-by: Michael Weiser <weiser@xxxxxxxxxxxxxxxxxxxx> > --- > - Has two very minor memory leaks - function is called only once per > program execution. Do we care? Alternative: Use static buffer instead. > > exec_cmd.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------------- > 1 files changed, 53 insertions(+), 15 deletions(-) > > diff --git a/exec_cmd.c b/exec_cmd.c > index 125fa6f..d50d7f8 100644 > --- a/exec_cmd.c > +++ b/exec_cmd.c > @@ -4,28 +4,22 @@ > #define MAX_ARGS 32 > > static const char *argv_exec_path; > -static const char *argv0_path; > +static const char *argv0_path = NULL; > > const char *system_path(const char *path) > { > -#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)); > - > - if (!prefix && > - !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) && > - !(prefix = strip_path_suffix(argv0_path, BINDIR)) && > - !(prefix = strip_path_suffix(argv0_path, "git"))) { > + if (!argv0_path || > + !is_absolute_path(argv0_path) || > + (!(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) && > + !(prefix = strip_path_suffix(argv0_path, BINDIR)) && > + !(prefix = strip_path_suffix(argv0_path, "git")))) { > prefix = PREFIX; > trace_printf("RUNTIME_PREFIX requested, " > "but prefix computation failed. " > @@ -41,20 +35,64 @@ const char *system_path(const char *path) > const char *git_extract_argv0_path(const char *argv0) > { > const char *slash; > + char *abs_argv0 = NULL; > > if (!argv0 || !*argv0) > return NULL; > slash = argv0 + strlen(argv0); > > + /* walk to the first slash from the end */ > while (argv0 <= slash && !is_dir_sep(*slash)) > slash--; > > + /* if there was a slash ... */ > if (slash >= argv0) { > - argv0_path = xstrndup(argv0, slash - argv0); > - return slash + 1; > + /* ... it's either an absolute path */ > + if (is_absolute_path(argv0)) { > + /* FIXME: memory leak here */ > + argv0_path = xstrndup(argv0, slash - argv0); > + return slash + 1; > + } > + > + /* ... or a relative path, in which case we have to make it > + * absolute first and do the whole thing again */ > + abs_argv0 = xstrdup(real_path(argv0)); > + } else { > + /* argv0 is no path at all, just a name. Resolve it into a > + * path. Unfortunately, this gets system specific. */ > +#if defined(__linux__) > + struct stat st; > + if (!stat("/proc/self/exe", &st)) { > + abs_argv0 = xstrdup(real_path("/proc/self/exe")); > + } > +#elif defined(__APPLE__) > + /* Mac OS X has realpath, which incidentally allocates its own > + * memory, which in turn is why we do all the xstrdup's in the > + * other cases. */ > + abs_argv0 = realpath(argv0, NULL); > +#endif ...perhaps a "GetModuleFileName(NULL, ...)" for Windows is in place here? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html