diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Doc/Zsh/builtins.yo | 4 | ||||
-rw-r--r-- | Src/Modules/newuser.c | 2 | ||||
-rw-r--r-- | Src/builtin.c | 14 | ||||
-rw-r--r-- | Src/init.c | 27 | ||||
-rw-r--r-- | Src/zsh.h | 11 | ||||
-rw-r--r-- | Test/A01grammar.ztst | 9 |
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' |