From: Andi Kleen <a...@linux.intel.com> This patch adds a recursion check to gcc-ar/ranlib/nm. The program avoids to call itself, so it can be directly put into the $PATH as a wrapper for the normal ar etc.
The recursion check will only work on Linux (or systems with Linux like /proc) for now. It should fall back gracefully if it doesn't exist. libiberty/: 2014-08-04 Andi Kleen <a...@linux.intel.com> * pex-unix.c (find_path): Add new function. (pex_unix_exec_child): Use find_path. --- libiberty/pex-unix.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c index addf8ee..ba8ee92 100644 --- a/libiberty/pex-unix.c +++ b/libiberty/pex-unix.c @@ -585,6 +585,41 @@ pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, } #else + +/* Search $PATH for EXE, but avoid recursion. */ + +static char * +find_path (char *exe) +{ + char *p; + char *prefix, *path; + int n; + char *fn; + char me[1024]; + + if (strchr (exe, '/')) + return xstrdup (exe); + p = getenv("PATH"); + if (!p) + return NULL; + memset(me, 0, sizeof me); + n = readlink ("/proc/self/exe", me, sizeof me - 1); + if (n < 0) + return xstrdup (exe); + p = path = xstrdup (p); + while ((prefix = strsep (&path, ":")) != NULL) + { + fn = concat (prefix, "/", exe, NULL); + if (access (fn, X_OK) == 0 + && strcmp (fn, me) != 0) + break; + free (fn); + fn = NULL; + } + free (p); + return fn; +} + /* Implementation of pex->exec_child using standard vfork + exec. */ static pid_t @@ -668,15 +703,15 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, if ((flags & PEX_SEARCH) != 0) { - execvp (executable, to_ptr32 (argv)); - pex_child_error (obj, executable, "execvp", errno); - } - else - { - execv (executable, to_ptr32 (argv)); - pex_child_error (obj, executable, "execv", errno); + char *exe = find_path (executable); + if (exe == NULL) + pex_child_error (obj, executable, "access", errno); + executable = exe; } + execv (executable, to_ptr32 (argv)); + pex_child_error (obj, executable, "execvp", errno); + /* NOTREACHED */ return (pid_t) -1; -- 2.0.1