diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2022-01-09 09:19:01 +0330 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2022-01-09 11:16:17 +0330 |
commit | ea667506405213d9e09116c8c30381c0fdcfe47b (patch) | |
tree | ebaf4e670c96970fea676902117083b0f0f91525 /Userland/Shell/Shell.cpp | |
parent | abaee3a3250e39b24b8e2338a04eb3245862d9a1 (diff) | |
download | serenity-ea667506405213d9e09116c8c30381c0fdcfe47b.zip |
Shell: Make interrupts kill the whole chain and not just the current job
This makes interrupting `sleep 10; echo hi` not print `hi` anymore,
which is the expected behaviour anyway.
Also fixes the problem with fast-running loops "eating" interrupts and
not quitting.
Diffstat (limited to 'Userland/Shell/Shell.cpp')
-rw-r--r-- | Userland/Shell/Shell.cpp | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/Userland/Shell/Shell.cpp b/Userland/Shell/Shell.cpp index 9b9928c2f6..4b129aae76 100644 --- a/Userland/Shell/Shell.cpp +++ b/Userland/Shell/Shell.cpp @@ -1765,7 +1765,12 @@ void Shell::notify_child_event() } if (child_pid == job.pid()) { if (WIFSIGNALED(wstatus) && !WIFSTOPPED(wstatus)) { - job.set_signalled(WTERMSIG(wstatus)); + auto signal = WTERMSIG(wstatus); + job.set_signalled(signal); + if (signal == SIGINT) + raise_error(ShellError::InternalControlFlowInterrupted, "Interrupted"sv, job.command().position); + else if (signal == SIGKILL) + raise_error(ShellError::InternalControlFlowKilled, "Interrupted"sv, job.command().position); } else if (WIFEXITED(wstatus)) { job.set_has_exit(WEXITSTATUS(wstatus)); } else if (WIFSTOPPED(wstatus)) { @@ -1998,6 +2003,8 @@ void Shell::possibly_print_error() const break; case ShellError::InternalControlFlowBreak: case ShellError::InternalControlFlowContinue: + case ShellError::InternalControlFlowInterrupted: + case ShellError::InternalControlFlowKilled: return; case ShellError::None: return; |