浏览代码

Kernel: waitpid() should unblock and -ECHILD if SIG_IGN reaps child

Andreas Kling 6 年之前
父节点
当前提交
23eafdb8d6
共有 2 个文件被更改,包括 8 次插入0 次删除
  1. 3 0
      Kernel/Process.cpp
  2. 5 0
      Kernel/Scheduler.cpp

+ 3 - 0
Kernel/Process.cpp

@@ -1554,6 +1554,9 @@ pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
 
 
     // NOTE: If waitee was -1, m_waitee_pid will have been filled in by the scheduler.
     // NOTE: If waitee was -1, m_waitee_pid will have been filled in by the scheduler.
     Process* waitee_process = Process::from_pid(waitee_pid);
     Process* waitee_process = Process::from_pid(waitee_pid);
+    if (!waitee_process)
+        return -ECHILD;
+
     ASSERT(waitee_process);
     ASSERT(waitee_process);
     if (waitee_process->is_dead()) {
     if (waitee_process->is_dead()) {
         exit_status = reap(*waitee_process);
         exit_status = reap(*waitee_process);

+ 5 - 0
Kernel/Scheduler.cpp

@@ -195,6 +195,11 @@ Thread::WaitBlocker::WaitBlocker(int wait_options, pid_t& waitee_pid)
 bool Thread::WaitBlocker::should_unblock(Thread& thread, time_t, long)
 bool Thread::WaitBlocker::should_unblock(Thread& thread, time_t, long)
 {
 {
     bool should_unblock = false;
     bool should_unblock = false;
+    if (m_waitee_pid != -1) {
+        auto* peer = Process::from_pid(m_waitee_pid);
+        if (!peer)
+            return true;
+    }
     thread.process().for_each_child([&](Process& child) {
     thread.process().for_each_child([&](Process& child) {
         if (m_waitee_pid != -1 && m_waitee_pid != child.pid())
         if (m_waitee_pid != -1 && m_waitee_pid != child.pid())
             return IterationDecision::Continue;
             return IterationDecision::Continue;