about summary refs log tree commit diff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2010-07-15 18:44:12 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2010-07-15 18:44:12 +0000
commit76aef28b3147fb5ea944c793452e2d5ca3b348fe (patch)
tree121357302f9a79c0a7452bd16b14d0f435159da1 /Src/utils.c
parentaf0bfaea085e14f531a424e58d4276e426498e65 (diff)
downloadzsh-76aef28b3147fb5ea944c793452e2d5ca3b348fe.tar.gz
zsh-76aef28b3147fb5ea944c793452e2d5ca3b348fe.tar.xz
zsh-76aef28b3147fb5ea944c793452e2d5ca3b348fe.zip
28073: allow #! scripts to search path if interpreter not found
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/Src/utils.c b/Src/utils.c
index 379f9f738..f311abd05 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -606,6 +606,44 @@ zwcwidth(wint_t wc)
 /**/
 #endif /* MULTIBYTE_SUPPORT */
 
+/*
+ * Search the path for prog and return the file name.
+ * The returned value is unmetafied and in the unmeta storage
+ * area (N.B. should be duplicated if not used immediately and not
+ * equal to *namep).
+ *
+ * If namep is not NULL, *namep is set to the metafied programme
+ * name, which is in heap storage.
+ */
+/**/
+char *
+pathprog(char *prog, char **namep)
+{
+    char **pp, ppmaxlen = 0, *buf, *funmeta;
+    struct stat st;
+
+    for (pp = path; *pp; pp++)
+    {
+	int len = strlen(*pp);
+	if (len > ppmaxlen)
+	    ppmaxlen = len;
+    }
+    buf = zhalloc(ppmaxlen + strlen(prog) + 2);
+    for (pp = path; *pp; pp++) {
+	sprintf(buf, "%s/%s", *pp, prog);
+	funmeta = unmeta(buf);
+	if (access(funmeta, F_OK) == 0 &&
+	    stat(funmeta, &st) >= 0 &&
+	    !S_ISDIR(st.st_mode)) {
+	    if (namep)
+		*namep = buf;
+	    return funmeta;
+	}
+    }
+
+    return NULL;
+}
+
 /* get a symlink-free pathname for s relative to PWD */
 
 /**/