Skip to content

Commit

Permalink
exec: Don't exit on exec failure if interactive
Browse files Browse the repository at this point in the history
This commit implements the new POSIX.1-2024 requirement.

Previously, failure in the exec built-in on an interactive shell caused
the shell to exit only if the POSIXly-correct mode was off. The mode no
longer affects the shell behavior.

The test file "exec-p.tst" is synced with:
https://github.com/magicant/yash-rs/blob/218275d85908442e4aa4c06dbe41d93f6cf62a37/yash-cli/tests/scripted_test/exec-p.sh
  • Loading branch information
magicant committed Nov 14, 2024
1 parent 31a0127 commit 7ba1c96
Show file tree
Hide file tree
Showing 9 changed files with 20 additions and 25 deletions.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
- [line-editing] The completion for the . built-in now suggests
directory names for the first operand even before the user enters a
slash.
- Improved POSIX.1-2024 support:
- An interactive shell no longer exits on an error in the `exec`
built-in, even if the POSIXly-correct mode is on.
- Updated the sample initialization script (yashrc):
- Added aliases h='fc -l' and j='jobs'.
- Added the wrapper function for `doas` in an attempt to remove the
Expand Down
3 changes: 3 additions & 0 deletions NEWS.ja
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
補完候補を表示するようになった
- [行編集] . 組込みコマンドの最初の引数の補完で、スラッシュを入力する
前からディレクトリ名を補完候補として出すようにした
- POSIX.1-2024 のサポートを強化:
- POSIX 準拠モードであっても、対話シェルが `exec` 組込みで失敗した
ときはシェルを終了しないようにした
- 初期化スクリプト (yashrc) のサンプルを更新:
- エイリアス定義 h='fc -l' and j='jobs' を追加
- doas コマンドのラッパー関数を追加し、端末に紛らわしいウィンドウ
Expand Down
5 changes: 2 additions & 3 deletions doc/_exec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ that starts the external command is called in the current
link:exec.html#environment[command execution environment] instead of a
subshell, replacing the shell process with the new command process.

If the shell is in the link:posix.html[POSIXly-correct mode] or not
link:interact.html[interactive], failure in execution of {{command}} causes
the shell to exit immediately.
If the shell is not link:interact.html[interactive], failure in execution of
{{command}} causes the shell to exit immediately.

If an interactive shell that is not in the POSIXly-correct mode has a stopped
link:job.html[job], the shell prints a warning message and refuses to execute
Expand Down
2 changes: 1 addition & 1 deletion doc/interact.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ When the shell is interactive:
- The shell does not exit when the link:_dot.html[dot built-in] fails to find
a script file to read.
- The shell does not exit when the link:_exec.html[exec built-in] fails to
execute a command (if not in the link:posix.html[POSIXly-correct mode]).
execute a command.
- When a job finished for which the link:_wait.html[wait built-in] has been
waiting, the fact is reported (only if link:job.html[job control] is active
and not in the link:posix.html[POSIXly-correct mode]).
Expand Down
2 changes: 1 addition & 1 deletion doc/ja/_exec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Exec コマンドでは、{zwsp}link:posix.html[POSIX 準拠モード]である

Exec コマンドを{{コマンド}}を指定して実行すると、シェルは{zwsp}link:exec.html#simple[単純コマンドの実行]の最後のステップと同様にしてコマンドを実行します。ただし、コマンドは必ず外部コマンドとしてみなされ、関数や組込みコマンドは無視します。そしてその外部コマンドはサブシェルではなく現在の{zwsp}link:exec.html#environment[コマンド実行環境]で exec システムコールを呼び出すことで実行します。これにより、シェルのプロセスは新しく起動するコマンドに置き換わります。

シェルが link:posix.html[POSIX 準拠モード]のときまたは{zwsp}link:interact.html[対話モード]でないとき、コマンドの起動に失敗するとシェルは直ちに終了します。
シェルが{zwsp}link:interact.html[対話モード]でないとき、コマンドの起動に失敗するとシェルは直ちに終了します。

シェルが POSIX 準拠モードではなくかつ対話モードのとき、停止中のジョブがあると、シェルは警告を表示し、コマンドを起動しません。一度 exec が実行されると、シェルが持っているジョブの情報は失われるため、手動でシグナルを送ってジョブを再開または終了させなければならなくなります。警告を無視してコマンドを起動するには +-f+ (+--force+) オプションを付けてください。

Expand Down
2 changes: 1 addition & 1 deletion doc/ja/interact.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dfn:[対話モード]は、利用者が直接シェルを操作することを
- link:_exit.html[Exit 組込みコマンド]でシェルを終了しようとした時、停止している{zwsp}link:job.html[ジョブ]があれば、シェルは警告を表示してすぐには終了しません。このときは続けざまにもう一度 exit コマンドを実行すると本当にシェルを終了させることができます。シェルへの入力が終わりに達した場合も同様です。
- link:_suspend.html[Suspend 組込みコマンド]でシェルを停止させようとした時、シェルがセッションリーダーならエラーを出力して停止しません。
- link:_dot.html[ドット組込みコマンド]で読み込むスクリプトファイルが見つからなくても、シェルは終了しません。
- link:_exec.html[Exec 組込みコマンド]でコマンドの実行に失敗したときでもシェルは終了しません。(link:posix.html[POSIX 準拠モード]のときを除く)
- link:_exec.html[Exec 組込みコマンド]でコマンドの実行に失敗したときでもシェルは終了しません。
- link:_wait.html[Wait 組込みコマンド]で待っているジョブが終了したとき、そのことを示すメッセージを出力します。(link:job.html[ジョブ制御]が有効な時のみ。{zwsp}link:posix.html[POSIX 準拠モード]を除く)
- link:_read.html[Read 組込みコマンド]が二行目以降を読むときプロンプトを出します。
Expand Down
2 changes: 1 addition & 1 deletion exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2300,7 +2300,7 @@ int exec_builtin_2(int argc, void **argv, const wchar_t *as, bool clear)
error2:
free(mbssaveargv0);
error1:
if (posixly_correct || !is_interactive_now)
if (!is_interactive_now)
_Exit(err);
return err;
}
Expand Down
9 changes: 8 additions & 1 deletion tests/exec-p.tst
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,18 @@ foo bar
0
__OUT__

test_O -d -e 127 'executing non-existing command (relative)'
test_O -d -e 127 'executing non-existing command (relative, non-interactive)'
exec ./_no_such_command_
echo not reached
__IN__

test_o -d 'executing non-existing command (relative, interactive)' -i +m
exec ./_no_such_command_
echo $?
__IN__
127
__OUT__

test_x -d -e 0 'redirection error on exec'
command exec <_no_such_file_
status=$?
Expand Down
17 changes: 0 additions & 17 deletions tests/exec-y.tst
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
# exec-y.tst: yash-specific test of the exec built-in

test_O 'execution error kills shell, POSIX, interactive' --posix -i +m
exec ./_no_such_command_
echo not reached
__IN__

test_O 'execution error kills shell, non-POSIX, non-interactive'
exec ./_no_such_command_
echo not reached
__IN__

test_o 'execution error spares shell, non-POSIX, interactive' -i +m
exec ./_no_such_command_
echo reached
__IN__
reached
__OUT__

test_O -d -e 127 'executing non-existing command (empty path)'
PATH=
exec _no_such_command_
Expand Down

0 comments on commit 7ba1c96

Please sign in to comment.