From 0f3990cfa39ee232b140c9a92273ecca7596b2bc Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Sat, 25 Apr 2020 17:45:23 -0700 Subject: [PATCH] Kernel: Support signaling all processes with pid == -1 This is a special case that was previously not implemented. The idea is that you can dispatch a signal to all other processes the calling process has access to. There was some minor refactoring to make the self signal logic into a function so it could easily be easily re-used from do_killall. --- Kernel/Process.cpp | 55 ++++++++++++++++++++++++++++++++++++---------- Kernel/Process.h | 2 ++ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 34e85c72e9..ec5befdc5e 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2219,6 +2219,45 @@ KResult Process::do_killpg(pid_t pgrp, int signal) return error; } +KResult Process::do_killall(int signal) +{ + InterruptDisabler disabler; + + bool any_succeeded = false; + KResult error = KSuccess; + + // Send the signal to all processes we have access to for. + for (auto& process : *g_processes) { + KResult res = KSuccess; + if (process.pid() == m_pid) + res = do_killself(signal); + else + res = do_kill(process, signal); + + if (res.is_success()) + any_succeeded = true; + else + error = res; + } + + if (any_succeeded) + return KSuccess; + return error; +} + +KResult Process::do_killself(int signal) +{ + if (signal == 0) + return KSuccess; + + if (!Thread::current->should_ignore_signal(signal)) { + Thread::current->send_signal(signal, this); + (void)Thread::current->block(Thread::SemiPermanentBlocker::Reason::Signal); + } + + return KSuccess; +} + int Process::sys$kill(pid_t pid, int signal) { if (pid == m_pid) @@ -2228,23 +2267,15 @@ int Process::sys$kill(pid_t pid, int signal) if (signal < 0 || signal >= 32) return -EINVAL; - if (pid <= 0) { + if (pid < -1) { if (pid == INT32_MIN) return -EINVAL; return do_killpg(-pid, signal); } - if (pid == -1) { - // FIXME: Send to all processes. - return -ENOTIMPL; - } + if (pid == -1) + return do_killall(signal); if (pid == m_pid) { - if (signal == 0) - return 0; - if (!Thread::current->should_ignore_signal(signal)) { - Thread::current->send_signal(signal, this); - (void)Thread::current->block(Thread::SemiPermanentBlocker::Reason::Signal); - } - return 0; + return do_killself(signal); } InterruptDisabler disabler; auto* peer = Process::from_pid(pid); diff --git a/Kernel/Process.h b/Kernel/Process.h index 16c10d8705..fb9c505e9c 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -445,6 +445,8 @@ private: KResult do_kill(Process&, int signal); KResult do_killpg(pid_t pgrp, int signal); + KResult do_killall(int signal); + KResult do_killself(int signal); KResultOr do_waitid(idtype_t idtype, int id, int options);