1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

Fix shell exit on function call redirection error (re: 23f2e23)

This regression also exists on ksh 93v- and ksh2020, from which it
was backported.

Reproducer:

$ (fn() { true; }; fn >/dev/null/ne; true) 2>/dev/null; echo $?
1

Expected output: 0 (as on ksh 93u+).

FreeBSD sh and NetBSD sh are the only other known shells that share
this behaviour. POSIX currently allows both behaviours, but may
require the ksh 93u+ behaviour in future. In any case, this causes
an incompatibility with established ksh behaviour that could easily
break existing ksh scripts.

src/cmd/ksh93/sh/xec.c: sh_exec():
- Commit 23f2e23 introduced a check for jmpval > SH_JMPIO (5).
  When a function call pushes context for a redirection, this is
  done with the jmpval exit value of SH_JMPCMD (6). Change that to
  SH_JMPIO to avoid triggering that check.

src/cmd/ksh93/tests/exit.sh:
- Add regression tests for exit behaviour on various kinds of
  shell errors as listed in the POSIX standard, including an error
  in a redirection of a function call.

Fixes: https://github.com/ksh93/ksh/issues/310
This commit is contained in:
Martijn Dekker 2021-05-19 06:53:56 +02:00
parent 07eb2040e8
commit 0dd115e4b4
3 changed files with 56 additions and 1 deletions

3
NEWS
View file

@ -7,6 +7,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
- Fixed SHLVL so that replacing ksh by itself (exec ksh) will not increase it.
- Fixed a regression introduced on 2020-08-05 that caused a non-interactive
shell to exit if an I/O redirection of a function call encountered an error.
2021-05-13:
- Fixed a bug with 'test -t 1' that was introduced on 2021-04-26:

View file

@ -1550,7 +1550,7 @@ int sh_exec(register const Shnode_t *t, int flags)
if(io)
{
indx = shp->topfd;
sh_pushcontext(shp,buffp,SH_JMPCMD);
sh_pushcontext(shp,buffp,SH_JMPIO);
jmpval = sigsetjmp(buffp->buff,0);
}
if(jmpval == 0)

View file

@ -127,5 +127,57 @@ exp=1
[[ $exp == $status ]] || err_exit 'bare exit after false' \
"(expected '$exp', got '$status')"
# ======
# Exit behaviour for commands, expansions and assignments
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_01
builtin -s | while read cmd
do
[[ $cmd == : ]] && continue # ':' never errors out
("$cmd" --badoption; true) 2>/dev/null \
&& err_exit "Special built-in utility error does not cause shell to exit ($cmd)"
(command "$cmd" --badoption; true) 2>/dev/null \
|| err_exit "Error in special built-in utility prefixed by 'command' causes shell to exit ($cmd)"
done
(command shift 10; true) 2>/dev/null \
|| err_exit "Regular built-in utility error causes shell to exit"
(readonly foo=bar; foo=baz; true) 2>/dev/null \
&& err_exit "Variable assignment error does not cause shell to exit"
(command true ${foo@bar}; true) 2>/dev/null \
&& err_exit "Expansion error does not cause shell to exit"
(/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit "Command not found causes shell to exit"
# Exit behaviour for redirections
(>/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit 'Error in lone redirection causes shell to exit'
(: >/dev/null/nonexistent; true) 2>/dev/null \
&& err_exit 'Redirection error with special built-in utility does not cause shell to exit'
(false >/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit 'Redirection error with regular built-in utility causes shell to exit'
("$(whence -p false)" >/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit 'Redirection error with external command causes shell to exit'
(/dev/null/nonexistent >/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit 'Redirection error with nonexistent command causes shell to exit'
(foo=bar >/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit 'Redirection error with variable assignment causes shell to exit'
({ false; }; >/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit 'Redirection error with compound command causes shell to exit'
# https://github.com/ksh93/ksh/issues/310
(fn() { false; }; fn >/dev/null/nonexistent; true) 2>/dev/null \
|| err_exit 'Redirection error with function execution causes shell to exit'
# ======
exit $((Errors<125?Errors:125))