27083: non-zero status on failures to find or execute file in "."

This commit is contained in:
Peter Stephenson 2009-07-01 15:07:25 +00:00
parent 88d07936a2
commit 041057687f
7 changed files with 57 additions and 17 deletions

View file

@ -1,5 +1,10 @@
2009-07-01 Peter Stephenson <pws@csr.com>
* 27083: Doc/Zsh/builtins.yo, Src/builtin.c, Src/init.c,
Src/zsh.h, Src/Modules/newuser.c, Test/A01grammar.ztst: "."
returns status 128 on execution failure, 129 on failure to find
file.
* 27080: Doc/Zsh/Zsh/mod_complist.yo, Src/Zle/complist.c: it
wasn't possible to exit menu selection cleanly.
@ -11881,5 +11886,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.4722 $
* $Revision: 1.4723 $
*****************************************************

View file

@ -46,7 +46,9 @@ then commands are read from that file instead of var(file).
If any arguments var(arg) are given,
they become the positional parameters; the old positional
parameters are restored when the var(file) is done executing.
The exit status is the exit status of the last command executed.
If var(file) was not found the return status is 129; if var(file) was found
but contained a syntax error the return status is 128; else the return
status is the exit status of the last command executed.
)
findex(NOTRANS(:))
cindex(expanding parameters)

View file

@ -97,7 +97,7 @@ boot_(UNUSED(Module m))
VARARR(char, buf, strlen(*sp) + 9);
sprintf(buf, "%s/newuser", *sp);
if (!source(buf))
if (source(buf) != SOURCE_NOT_FOUND)
break;
}

View file

@ -4701,9 +4701,10 @@ int
bin_dot(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
{
char **old, *old0 = NULL;
int ret, diddot = 0, dotdot = 0;
int diddot = 0, dotdot = 0;
char *s, **t, *enam, *arg0, *buf;
struct stat st;
enum source_return ret;
if (!*argv)
return 0;
@ -4719,14 +4720,14 @@ bin_dot(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
}
s = unmeta(enam);
errno = ENOENT;
ret = 1;
ret = SOURCE_NOT_FOUND;
/* for source only, check in current directory first */
if (*name != '.' && access(s, F_OK) == 0
&& stat(s, &st) >= 0 && !S_ISDIR(st.st_mode)) {
diddot = 1;
ret = source(enam);
}
if (ret) {
if (ret == SOURCE_NOT_FOUND) {
/* use a path with / in it */
for (s = arg0; *s; s++)
if (*s == '/') {
@ -4739,7 +4740,8 @@ bin_dot(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
ret = source(arg0);
break;
}
if (!*s || (ret && isset(PATHDIRS) && diddot < 2 && dotdot == 0)) {
if (!*s || (ret == SOURCE_NOT_FOUND &&
isset(PATHDIRS) && diddot < 2 && dotdot == 0)) {
pushheap();
/* search path for script */
for (t = path; *t; t++) {
@ -4766,12 +4768,12 @@ bin_dot(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
freearray(pparams);
pparams = old;
}
if (ret)
if (ret == SOURCE_NOT_FOUND)
zwarnnam(name, "%e: %s", errno, enam);
zsfree(arg0);
if (old0)
argzero = old0;
return ret ? ret : lastval;
return ret == SOURCE_OK ? lastval : 127 + ret;
}
/*

View file

@ -99,10 +99,11 @@ mod_export struct hookdef zshhooks[] = {
/* keep executing lists until EOF found */
/**/
void
int
loop(int toplevel, int justonce)
{
Eprog prog;
int err;
pushheap();
if (!toplevel)
@ -201,9 +202,12 @@ loop(int toplevel, int justonce)
if (justonce)
break;
}
err = errflag;
if (!toplevel)
lexrestore();
popheap();
return err;
}
static char *cmd;
@ -1049,10 +1053,13 @@ init_misc(void)
readhistfile(NULL, 0, HFILE_USE_OPTIONS);
}
/* source a file */
/*
* source a file
* Returns one of the SOURCE_* enum values.
*/
/**/
mod_export int
mod_export enum source_return
source(char *s)
{
Eprog prog;
@ -1066,11 +1073,12 @@ source(char *s)
int ocsp;
int otrap_return = trap_return, otrap_state = trap_state;
struct funcstack fstack;
enum source_return ret = SOURCE_OK;
if (!s ||
(!(prog = try_source_file((us = unmeta(s)))) &&
(tempfd = movefd(open(us, O_RDONLY | O_NOCTTY))) == -1)) {
return 1;
return SOURCE_NOT_FOUND;
}
/* save the current shell state */
@ -1121,8 +1129,13 @@ source(char *s)
errflag = 0;
execode(prog, 1, 0);
popheap();
} else
loop(0, 0); /* loop through the file to be sourced */
if (errflag)
ret = SOURCE_ERROR;
} else {
/* loop through the file to be sourced */
if (loop(0, 0))
ret = SOURCE_ERROR;
}
funcstack = funcstack->prev;
sourcelevel--;
@ -1152,7 +1165,7 @@ source(char *s)
cmdstack = ocs;
cmdsp = ocsp;
return 0;
return ret;
}
/* Try to source a file in the home directory */

View file

@ -1725,6 +1725,17 @@ struct nameddir {
#define PRINT_WHENCE_FUNCDEF (1<<9)
#define PRINT_WHENCE_WORD (1<<10)
/* Return values from source() */
enum source_return {
/* Source ran OK */
SOURCE_OK = 0,
/* Internal error sourcing file */
SOURCE_ERROR = 1,
/* File not found */
SOURCE_NOT_FOUND = 2
};
/***********************************/
/* Definitions for history control */
/***********************************/

View file

@ -514,4 +514,11 @@
>value
>not#comment
. ./nonexistent
129: Attempt to "." non-existent file.
?(eval):.:1: no such file or directory: ./nonexistent
echo '[[' >bad_syntax
. ./bad_syntax
128: Attempt to "." file with bad syntax.
?./bad_syntax:2: parse error near `\n'