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:
parent
af0bfaea08
commit
76aef28b31
4 changed files with 52 additions and 20 deletions
|
@ -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 $
|
||||
*****************************************************
|
||||
|
|
|
@ -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) {
|
||||
|
|
20
Src/init.c
20
Src/init.c
|
@ -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)))
|
||||
|
|
38
Src/utils.c
38
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 */
|
||||
|
||||
/**/
|
||||
|
|
Loading…
Reference in a new issue