diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | Doc/Zsh/options.yo | 6 | ||||
-rw-r--r-- | Src/builtin.c | 10 | ||||
-rw-r--r-- | Src/exec.c | 22 | ||||
-rw-r--r-- | Test/A04redirect.ztst | 49 |
5 files changed, 82 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog index bcaab5c63..cb9dcfd71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-02-22 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 28791: Doc/Zsh/options.yo, Src/builtin.c, Src/exec.c, + Test/A04redirect.ztst: exit on errors in special builtins + with POSIXBUILTINS. + 2011-02-21 Peter Stephenson <pws@csr.com> * 28783: Doc/Zsh/options.yo, Src/lex.c, Test/A01grammar.ztst: @@ -14242,5 +14248,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5205 $ +* $Revision: 1.5206 $ ***************************************************** diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 4ecf8f831..892378469 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1871,9 +1871,9 @@ tt(times), tt(trap) and tt(unset). -In addition, a failed redirection after tt(exec) causes a non-interactive -shell to exit and an interactive shell to return to its top-level -processing. +In addition, various error conditions associated with the above builtins +or tt(exec) cause a non-interactive shell to exit and an interactive +shell to return to its top-level processing. ) pindex(POSIX_IDENTIFIERS) pindex(NO_POSIX_IDENTIFIERS) diff --git a/Src/builtin.c b/Src/builtin.c index a85a49a20..aa87dfb7d 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4821,8 +4821,14 @@ bin_dot(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) freearray(pparams); pparams = old; } - if (ret == SOURCE_NOT_FOUND) - zwarnnam(name, "%e: %s", errno, enam); + if (ret == SOURCE_NOT_FOUND) { + if (isset(POSIXBUILTINS)) { + /* hard error in POSIX (we'll exit later) */ + zerrnam(name, "%e: %s", errno, enam); + } else { + zwarnnam(name, "%e: %s", errno, enam); + } + } zsfree(arg0); if (old0) { zsfree(argzero); diff --git a/Src/exec.c b/Src/exec.c index da67465d8..25a2eee38 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2416,6 +2416,8 @@ execcmd(Estate state, int input, int output, int how, int last1) checked = !(cflags & BINF_BUILTIN); break; } + cflags &= ~BINF_BUILTIN & ~BINF_COMMAND; + cflags |= hn->flags; if (!(hn->flags & BINF_PREFIX)) { is_builtin = 1; @@ -2425,8 +2427,6 @@ execcmd(Estate state, int input, int output, int how, int last1) assign = (hn->flags & BINF_MAGICEQUALS); break; } - cflags &= ~BINF_BUILTIN & ~BINF_COMMAND; - cflags |= hn->flags; checked = 0; if ((cflags & BINF_COMMAND) && nextnode(firstnode(args))) { /* check for options to command builtin */ @@ -3297,12 +3297,20 @@ execcmd(Estate state, int input, int output, int how, int last1) fixfds(save); done: - if (redir_err && isset(POSIXBUILTINS)) { - if (!isset(INTERACTIVE)) { - /* We've already _exit'ed if forked */ - exit(1); + if (isset(POSIXBUILTINS) && + (cflags & (BINF_PSPECIAL|BINF_EXEC))) { + /* + * For POSIX-compatibile behaviour with special + * builtins (including exec which we don't usually + * classify as a builtin, we treat all errors as fatal. + */ + if (redir_err || errflag) { + if (!isset(INTERACTIVE)) { + /* We've already _exit'ed if forked */ + exit(1); + } + errflag = 1; } - errflag = 1; } if (newxtrerr) { fil = fileno(newxtrerr); diff --git a/Test/A04redirect.ztst b/Test/A04redirect.ztst index c35977c66..9340b71f0 100644 --- a/Test/A04redirect.ztst +++ b/Test/A04redirect.ztst @@ -378,3 +378,52 @@ echo output' 1:failed exec redir, POSIX_BUILTINS ?zsh:2: no such file or directory: /nonexistent/nonexistent + + $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c ' + set >/nonexistent/nonexistent + echo output' +1:failed special builtin redir, POSIX_BUILTINS +?zsh:2: no such file or directory: /nonexistent/nonexistent + + $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c ' + echo >/nonexistent/nonexistent + echo output' +0:failed unspecial builtin redir, POSIX_BUILTINS +>output +?zsh:2: no such file or directory: /nonexistent/nonexistent + + $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS -c ' + . /nonexistent/nonexistent + echo output' +1:failed dot, POSIX_BUILTINS +?zsh:.:2: no such file or directory: /nonexistent/nonexistent + + $ZTST_testdir/../Src/zsh -f -c ' + . /nonexistent/nonexistent + echo output' +0:failed dot, NO_POSIX_BUILTINS +>output +?zsh:.:2: no such file or directory: /nonexistent/nonexistent + + $ZTST_testdir/../Src/zsh -f <<<' + readonly foo + foo=bar set output + echo output' +0:failed assignment on posix special, NO_POSIX_BUILTINS +>output +?zsh: read-only variable: foo + + $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS <<<' + readonly foo + foo=bar set output + echo output' +1:failed assignment on posix special, POSIX_BUILTINS +?zsh: read-only variable: foo + + $ZTST_testdir/../Src/zsh -f -o POSIX_BUILTINS <<<' + readonly foo + foo=bar echo output + echo output' +0:failed assignment on non-posix-special, POSIX_BUILTINS +>output +?zsh: read-only variable: foo |