1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-04 10:41:11 +02:00

28073: allow #! scripts to search path if interpreter not found

This commit is contained in:
Peter Stephenson 2010-07-15 18:44:12 +00:00
parent af0bfaea08
commit 76aef28b31
4 changed files with 52 additions and 20 deletions

View file

@ -1,3 +1,8 @@
2010-07-15 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 28073: Src/exec.c, Src/init.c, Src/utils.c: allow #!
scripts to search path if interpreter not found.
2010-07-15 Doug Kearns <dougkearns@gmail.com>
* 28078: Completion/Unix/Command/_xmlsoft: update.
@ -13374,5 +13379,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.5025 $
* $Revision: 1.5026 $
*****************************************************

View file

@ -461,8 +461,15 @@ zexecve(char *pth, char **argv, char **newenvp)
for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
if (eno == ENOENT) {
char *pprog;
if (*ptr)
*ptr = '\0';
if (*ptr2 != '/' &&
(pprog = pathprog(ptr2, NULL))) {
argv[-2] = ptr2;
argv[-1] = ptr + 1;
execve(pprog, argv - 2, newenvp);
}
zerr("%s: bad interpreter: %s: %e", pth, ptr2,
eno);
} else if (*ptr) {

View file

@ -949,25 +949,7 @@ setupshin(char *runscript)
* With the PATHSCRIPT option, search the path if no
* path was given in the script name.
*/
char **pp, ppmaxlen = 0, *buf;
for (pp = path; *pp; pp++)
{
int len = strlen(*pp);
if (len > ppmaxlen)
ppmaxlen = len;
}
buf = zhalloc(ppmaxlen + strlen(runscript) + 2);
for (pp = path; *pp; pp++) {
sprintf(buf, "%s/%s", *pp, runscript);
/* careful, static buffer used in open() later */
funmeta = unmeta(buf);
if (access(funmeta, F_OK) == 0 &&
stat(funmeta, &st) >= 0 &&
!S_ISDIR(st.st_mode)) {
sfname = buf;
break;
}
}
funmeta = pathprog(runscript, &sfname);
}
if (!sfname ||
(SHIN = movefd(open(funmeta, O_RDONLY | O_NOCTTY)))

View file

@ -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 */
/**/