Przeglądaj źródła

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.
Brian Gianforcaro 5 lat temu
rodzic
commit
0f3990cfa3
2 zmienionych plików z 45 dodań i 12 usunięć
  1. 43 12
      Kernel/Process.cpp
  2. 2 0
      Kernel/Process.h

+ 43 - 12
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>(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);

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