Skip to content

Fix default exit status of exit built-in in trap action #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
- The shell now considers a job to be suspended when any child
process suspends in a pipeline, instead of when all child
processes suspend.
- When the `exit` built-in is used without an operand in a trap
action, the shell now exits with the exit status of the last
command executed before the trap action, instead of the exit
status of the last command executed in the trap action.
- The `read` built-in now returns a more specific exit status
depending on the cause of the error.
- The `read` built-in now supports the `-d` option, which can be
Expand Down
3 changes: 3 additions & 0 deletions NEWS.ja
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
コマンドを破棄して直ちに次のコマンドを読むようになった
- ジョブの全ての子プロセスが停止しなくても、どれかの子プロセスが停止
したときにジョブが停止したとみなすようになった
- トラップの中で終了ステータスを指定せずに `exit` 組込みを実行した
とき、シェルはそのトラップ内で最後に実行したコマンドではなく
トラップの直前に実行したコマンドの終了ステータスを返すようになった
- `read` 組込みは結果に応じてより細分化された終了ステータスを返す
ようになった
- `read` 組込みに行区切り文字を指定する `-d` オプションを追加
Expand Down
2 changes: 1 addition & 1 deletion exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1615,7 +1615,7 @@ void become_child(sigtype_T sigtype)
clear_shellfds(sigtype & t_leave);
is_subshell = true;
suppresserrreturn = false;
exitstatus = -1;
savelaststatus = exitstatus = -1;
}

/* Executes the command substitution and returns the string to substitute with.
Expand Down
3 changes: 1 addition & 2 deletions tests/exit-p.tst
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ trap '(exit 2); exit 3' INT
kill -INT $$
__IN__

# TODO Yash is broken
test_OE -e 0 -f 'default exit status in signal trap'
test_OE -e 0 'default exit status in signal trap'
trap '(exit 2); exit' INT
(exit 1)
kill -INT $$
Expand Down
13 changes: 12 additions & 1 deletion yash.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,13 +391,23 @@ void exit_shell_with_status(int status)
if (status >= 0)
laststatus = status;
assert(laststatus >= 0);

if (exitstatus < 0) {
exitstatus = laststatus;
/* We're not executing the EXIT trap, so execute it now. */
if (status >= 0)
exitstatus = status;
else if (savelaststatus >= 0)
exitstatus = savelaststatus;
else
exitstatus = laststatus;
execute_exit_trap();
} else {
/* We're already executing the EXIT trap, so avoid executing it
* recursively. */
if (status >= 0)
exitstatus = status;
}

#if YASH_ENABLE_HISTORY
finalize_history();
#endif
Expand All @@ -407,6 +417,7 @@ void exit_shell_with_status(int status)
maybe_raise(signal);
}

assert(exitstatus >= 0);
_Exit(exitstatus);
}

Expand Down
Loading