Skip to content

Commit

Permalink
Non-zero exit status of shell error during EXIT trap
Browse files Browse the repository at this point in the history
This commit backports test cases for traps from:
https://github.com/magicant/yash-rs/blob/905576f650221edfb99d4cb6461ce90d3a0489c2/yash-cli/tests/scripted_test/trap-p.sh

A fix is applied to support the new test cases.
  • Loading branch information
magicant committed May 4, 2024
1 parent f5bbaad commit b59ed7c
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 4 deletions.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ History of Yash

- Added support for the "$POST_PROMPT_COMMAND" variable, whose value
is executed after reading a command line in the interactive shell.
- If the shell exits because of a shell error during the EXIT trap,
the shell now returns the exit status of the error rather than that
of the last command before the EXIT trap.
- [line-editing] Fixed the spurious error message printed when
completing after `git config alias.` with the nounset shell option
enabled.
Expand Down
3 changes: 3 additions & 0 deletions NEWS.ja
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Yash 更新履歴

- "$POST_PROMPT_COMMAND" に対応。対話モードでコマンドを読むごとに
変数の値が実行される
- EXIT トラップ実行中にリダイレクトエラー等でシェルが終了する際、
EXIT トラップ開始直前の終了ステータスではなくエラーの終了
ステータスで終了するようにした
- [行編集] nounset オプション有効時に `git config alias.` に続けて
補完をしようとするとエラーが出るのを修正
- [行編集] カーソルがバックスラッシュの直後にある時に補完をすると
Expand Down
8 changes: 6 additions & 2 deletions exec.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Yash: yet another shell */
/* exec.c: command execution */
/* (C) 2007-2022 magicant */
/* (C) 2007-2024 magicant */

/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -686,7 +686,11 @@ void exec_simple_command(const command_T *c, bool finally_exit)
plfree(argv, free);
done:
if (finally_exit)
exit_shell();
/* If we're running the EXIT trap and the simple command failed with a
* shell error, we should exit with the current exit status indicating
* the error rather than the exit status saved just before entering the
* EXIT trap, so... */
exit_shell_with_status(laststatus); // rather than: exit_shell();
}

/* Executes the simple command that has no expanded words.
Expand Down
24 changes: 22 additions & 2 deletions tests/trap-p.tst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

posix="true"

if [ "$(uname)" = Darwin ]; then
# On macOS, kill(2) does not appear to run any signal handlers
# synchronously, making it impossible for the shell to respond to self-sent
# signals at a predictable time. To work around this issue, the kill
# built-in is called in a subshell on macOS, using the SIGCHLD signal as a
# synchronization trigger.
setup <<\__EOF__
killx() (command kill "$@")
alias kill=killx
__EOF__
fi

test_OE -e USR1 'setting default trap'
trap - USR1
kill -s USR1 $$
Expand Down Expand Up @@ -107,20 +119,28 @@ __IN__
ok
__OUT__

test_O -e n 'fatal shell error in trap'
test_O -e n 'fatal shell error in signal trap'
trap 'set <_no_such_file_' INT
kill -s INT $$
echo not reached
__IN__

test_oE -e 0 '$? is restored after trap is executed'
test_O -e n 'fatal shell error in EXIT trap'
trap 'set <_no_such_file_' EXIT
__IN__

test_oE -e 0 '$? is restored after signal trap is executed'
trap 'false' USR1
kill -s USR1 $$
echo $?
__IN__
0
__OUT__

test_E -e 0 'exit status of EXIT trap does not affect exit status of shell'
trap 'false' EXIT
__IN__

test_oE 'trap command is not affected by assignment in same simple command' \
-c 'foo=1 trap "echo EXIT \$foo" EXIT; foo=2; foo=3 echo $foo'
__IN__
Expand Down

0 comments on commit b59ed7c

Please sign in to comment.