Date: Sun, 14 Mar 2010 14:24:35 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r205154 - in head: bin/sh tools/regression/bin/sh/builtins tools/regression/bin/sh/errors Message-ID: <201003141424.o2EEOZCP065456@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jilles Date: Sun Mar 14 14:24:35 2010 New Revision: 205154 URL: http://svn.freebsd.org/changeset/base/205154 Log: sh: Do not abort on a redirection error on a compound command. Redirection errors on subshells already did not abort the shell because the redirection is executed in the subshell. Other shells seem to agree that these redirection errors should not abort the shell. Also ensure that the redirections will be cleaned up properly in cases like command eval '{ shift x; } 2>/dev/null' Example: { echo bad; } </var/empty/x; echo good Added: head/tools/regression/bin/sh/builtins/command11.0 (contents, props changed) head/tools/regression/bin/sh/errors/redirection-error6.0 (contents, props changed) Modified: head/bin/sh/eval.c Modified: head/bin/sh/eval.c ============================================================================== --- head/bin/sh/eval.c Sun Mar 14 13:51:12 2010 (r205153) +++ head/bin/sh/eval.c Sun Mar 14 14:24:35 2010 (r205154) @@ -91,6 +91,7 @@ STATIC void evalloop(union node *, int); STATIC void evalfor(union node *, int); STATIC void evalcase(union node *, int); STATIC void evalsubshell(union node *, int); +STATIC void evalredir(union node *, int); STATIC void expredir(union node *); STATIC void evalpipe(union node *); STATIC void evalcommand(union node *, int, struct backcmd *); @@ -221,10 +222,7 @@ evaltree(union node *n, int flags) evaltree(n->nbinary.ch2, flags); break; case NREDIR: - expredir(n->nredir.redirect); - redirect(n->nredir.redirect, REDIR_PUSH); - evaltree(n->nredir.n, flags); - popredir(); + evalredir(n, flags); break; case NSUBSHELL: evalsubshell(n, flags); @@ -415,6 +413,46 @@ evalsubshell(union node *n, int flags) } +/* + * Evaluate a redirected compound command. + */ + +STATIC void +evalredir(union node *n, int flags) +{ + struct jmploc jmploc; + struct jmploc *savehandler; + volatile int in_redirect = 1; + + expredir(n->nredir.redirect); + savehandler = handler; + if (setjmp(jmploc.loc)) { + int e; + + handler = savehandler; + e = exception; + if (e == EXERROR || e == EXEXEC) { + popredir(); + if (in_redirect) { + exitstatus = 2; + return; + } + } + longjmp(handler->loc, 1); + } else { + INTOFF; + handler = &jmploc; + redirect(n->nredir.redirect, REDIR_PUSH); + in_redirect = 0; + INTON; + evaltree(n->nredir.n, flags); + } + INTOFF; + handler = savehandler; + popredir(); + INTON; +} + /* * Compute the names of the files in a redirection list. Added: head/tools/regression/bin/sh/builtins/command11.0 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/regression/bin/sh/builtins/command11.0 Sun Mar 14 14:24:35 2010 (r205154) @@ -0,0 +1,14 @@ +# $FreeBSD$ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +check '"$({ command eval \{ shift x\; \} 2\>/dev/null; } >/dev/null; echo hi)" = hi' + +exit $((failures > 0)) Added: head/tools/regression/bin/sh/errors/redirection-error6.0 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/regression/bin/sh/errors/redirection-error6.0 Sun Mar 14 14:24:35 2010 (r205154) @@ -0,0 +1,12 @@ +# $FreeBSD$ +# A redirection error on a compound command should not abort the shell. +exec 2>/dev/null +{ echo bad; } </var/empty/x +if :; then echo bad; fi </var/empty/x +for i in 1; do echo bad; done </var/empty/x +i=0 +while [ $i = 0 ]; do echo bad; i=1; done </var/empty/x +i=0 +until [ $i != 0 ]; do echo bad; i=1; done </var/empty/x +case i in *) echo bad ;; esac </var/empty/x +exit 0
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003141424.o2EEOZCP065456>