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
This commit is contained in:
parent
a4a58620d3
commit
c3bb858966
@ -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.
|
||||
|
14
tools/regression/bin/sh/builtins/command11.0
Normal file
14
tools/regression/bin/sh/builtins/command11.0
Normal file
@ -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))
|
12
tools/regression/bin/sh/errors/redirection-error6.0
Normal file
12
tools/regression/bin/sh/errors/redirection-error6.0
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user