summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-07-01 15:07:25 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-07-01 15:07:25 +0000
commit041057687fc1d4a2f9912fcb86e04517686b3642 (patch)
tree0f0d181cebf9c50bf3e2d9d4a50643eafde9a140
parent88d07936a21c262ec5f86518cce3c85fd1951968 (diff)
downloadzsh-041057687fc1d4a2f9912fcb86e04517686b3642.tar.gz
zsh-041057687fc1d4a2f9912fcb86e04517686b3642.zip
27083: non-zero status on failures to find or execute file in "."
-rw-r--r--ChangeLog7
-rw-r--r--Doc/Zsh/builtins.yo4
-rw-r--r--Src/Modules/newuser.c2
-rw-r--r--Src/builtin.c14
-rw-r--r--Src/init.c27
-rw-r--r--Src/zsh.h11
-rw-r--r--Test/A01grammar.ztst9
7 files changed, 57 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 021f0d81b..7cff1cf67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 $
*****************************************************
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 2ce9aefd1..3047b3371 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -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)
diff --git a/Src/Modules/newuser.c b/Src/Modules/newuser.c
index cc020d5bd..71902da7d 100644
--- a/Src/Modules/newuser.c
+++ b/Src/Modules/newuser.c
@@ -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;
}
diff --git a/Src/builtin.c b/Src/builtin.c
index 01e6b479b..1f41b1e87 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -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;
}
/*
diff --git a/Src/init.c b/Src/init.c
index a3aac3e1c..41e5ecf9f 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -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 */
diff --git a/Src/zsh.h b/Src/zsh.h
index 3854116c0..87b561085 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -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 */
/***********************************/
diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst
index 9d9f49860..3d0337a1c 100644
--- a/Test/A01grammar.ztst
+++ b/Test/A01grammar.ztst
@@ -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'