sh: Fix break/continue/return sometimes not skipping the rest of dot script.

In our implementation and most others, a break or continue in a dot script
can break or continue a loop outside the dot script. This should cause all
further commands in the dot script to be skipped. However, cmdloop() did not
know about this and continued to parse and execute commands from the dot
script.

As described in the man page, a return in a dot script in a function returns
from the function, not only from the dot script. There was a similar issue
as with break and continue. In various other shells, the return appears to
return from the dot script, but POSIX seems not very clear about this.
This commit is contained in:
Jilles Tjoelker 2010-08-15 21:06:53 +00:00
parent b0ee1e8ae6
commit ae7c0700dc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=211349
3 changed files with 36 additions and 2 deletions

View File

@ -232,8 +232,9 @@ cmdloop(int top)
}
popstackmark(&smark);
setstackmark(&smark);
if (evalskip == SKIPFILE) {
evalskip = 0;
if (evalskip != 0) {
if (evalskip == SKIPFILE)
evalskip = 0;
break;
}
}

View File

@ -0,0 +1,16 @@
# $FreeBSD$
if [ "$1" != nested ]; then
while :; do
set -- nested
. "$0"
echo bad2
exit 2
done
exit 0
fi
# To trigger the bug, the following commands must be at the top level,
# with newlines in between.
break
echo bad1
exit 1

View File

@ -0,0 +1,17 @@
# $FreeBSD$
if [ "$1" != nested ]; then
f() {
set -- nested
. "$0"
# Allow return to return from the function or the dot script.
return 4
}
f
exit $(($? ^ 4))
fi
# To trigger the bug, the following commands must be at the top level,
# with newlines in between.
return 4
echo bad
exit 1