Skip to content

Commit

Permalink
Kernel: Support signaling all processes with pid == -1
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bgianfo authored and awesomekling committed Apr 26, 2020
1 parent 597ff9e commit 0f3990c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 12 deletions.
55 changes: 43 additions & 12 deletions Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions Kernel/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ class Process : public InlineLinkedListNode<Process> {

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);

Expand Down

0 comments on commit 0f3990c

Please sign in to comment.