diff mbox

Add recursion check to gcc-ar/ranlib/nm

Message ID 1407250348-21039-1-git-send-email-andi@firstfloor.org
State New
Headers show

Commit Message

Andi Kleen Aug. 5, 2014, 2:52 p.m. UTC
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(-)
diff mbox

Patch

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;