@@ -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;
From: Andi Kleen <ak@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 <ak@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(-)