Re: [PATCH] Extend runtime prefix computation
- From
Erik Faye-Lund <kusmabite@gmail.com>
- Date
- Nov 30, 2012, 10:20 UTC
- Message-ID
- <CABPQNSYhscHdnTFLye=oif_R84kpdaVsrCK+-174v7Ugrae_yQ@mail.gmail.com>
- In-Reply-To
- <20121127163004.GC7499@science-computing.de>
On Tue, Nov 27, 2012 at 5:30 PM, Michael Weiser <M.Weiser@science-computing.de> wrote:
Show 93 quoted lines
> 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@science-computing.de>
> ---
> - 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?