From 8582a068992a453e328a622584148b971b37b9b0 Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Sat, 16 May 2020 03:02:14 +0430 Subject: [PATCH] Kernel + LibC: Handle running processes in do_waitid() --- Kernel/Process.cpp | 56 +++++++++++++++---------------------- Kernel/Scheduler.cpp | 3 +- Libraries/LibC/sys/wait.cpp | 3 ++ 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 84cc455a73..393f93a58a 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -73,9 +76,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -2429,31 +2429,6 @@ KResultOr Process::do_waitid(idtype_t idtype, int id, int options) return KResult(-ECHILD); } - if (options & WNOHANG) { - // FIXME: Figure out what WNOHANG should do with stopped children. - if (idtype == P_ALL) { - InterruptDisabler disabler; - siginfo_t siginfo; - memset(&siginfo, 0, sizeof(siginfo)); - for_each_child([&siginfo](Process& process) { - if (process.is_dead()) - siginfo = reap(process); - return IterationDecision::Continue; - }); - return siginfo; - } else if (idtype == P_PID) { - InterruptDisabler disabler; - auto* waitee_process = Process::from_pid(id); - if (!waitee_process) - return KResult(-ECHILD); - if (waitee_process->is_dead()) - return reap(*waitee_process); - } else { - // FIXME: Implement other PID specs. - return KResult(-EINVAL); - } - } - pid_t waitee_pid; // FIXME: WaitBlocker should support idtype/id specs directly. @@ -2466,9 +2441,8 @@ KResultOr Process::do_waitid(idtype_t idtype, int id, int options) return KResult(-EINVAL); } - if (!(options & WNOHANG)) - if (Thread::current->block(options, waitee_pid) != Thread::BlockResult::WokeNormally) - return KResult(-EINTR); + if (Thread::current->block(options, waitee_pid) != Thread::BlockResult::WokeNormally) + return KResult(-EINTR); InterruptDisabler disabler; @@ -2484,13 +2458,29 @@ KResultOr Process::do_waitid(idtype_t idtype, int id, int options) auto* waitee_thread = Thread::from_tid(waitee_pid); if (!waitee_thread) return KResult(-ECHILD); - ASSERT(waitee_thread->state() == Thread::State::Stopped); + ASSERT((options & WNOHANG) || waitee_thread->state() == Thread::State::Stopped); siginfo_t siginfo; memset(&siginfo, 0, sizeof(siginfo)); siginfo.si_signo = SIGCHLD; siginfo.si_pid = waitee_process->pid(); siginfo.si_uid = waitee_process->uid(); - siginfo.si_code = CLD_STOPPED; + + switch (waitee_thread->state()) { + case Thread::State::Stopped: + siginfo.si_code = CLD_STOPPED; + break; + case Thread::State::Running: + case Thread::State::Runnable: + case Thread::State::Blocked: + case Thread::State::Dying: + case Thread::State::Queued: + siginfo.si_code = CLD_CONTINUED; + break; + default: + ASSERT_NOT_REACHED(); + break; + } + siginfo.si_status = waitee_thread->m_stop_signal; return siginfo; } diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index e600161437..c1126d9bde 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -274,7 +274,8 @@ bool Thread::WaitBlocker::should_unblock(Thread& thread, time_t, long) } bool wait_finished = ((m_wait_options & WEXITED) && child_exited) - || ((m_wait_options & WSTOPPED) && child_stopped); + || ((m_wait_options & WSTOPPED) && child_stopped) + || (m_wait_options & WNOHANG); if (!wait_finished) return IterationDecision::Continue; diff --git a/Libraries/LibC/sys/wait.cpp b/Libraries/LibC/sys/wait.cpp index 1131c07d57..e3c92483ff 100644 --- a/Libraries/LibC/sys/wait.cpp +++ b/Libraries/LibC/sys/wait.cpp @@ -72,6 +72,9 @@ pid_t waitpid(pid_t waitee, int* wstatus, int options) case CLD_STOPPED: *wstatus = siginfo.si_status << 8 | 0x7f; break; + case CLD_CONTINUED: + *wstatus = 0; + return 0; // return 0 if running default: ASSERT_NOT_REACHED(); }