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.
This commit is contained in:
Brian Gianforcaro 2020-04-25 17:45:23 -07:00 committed by Andreas Kling
parent 597ff9ec93
commit 0f3990cfa3
Notes: sideshowbarker 2024-07-19 07:17:25 +09:00
2 changed files with 45 additions and 12 deletions

View file

@ -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>(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>(Thread::SemiPermanentBlocker::Reason::Signal);
}
return 0;
return do_killself(signal);
}
InterruptDisabler disabler;
auto* peer = Process::from_pid(pid);

View file

@ -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<siginfo_t> do_waitid(idtype_t idtype, int id, int options);