From 274b0260f7624c29ca7066f7e503f2ebd0cc6b01 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 1 Mar 2019 15:47:07 +0100 Subject: [PATCH] Kernel: Don't send SIGCHLD to parent process if he has SA_NOCLDWAIT set. Just transfer ownership of the dead process to the colonel and let the scheduler reap it on next iteration. --- Applications/FileManager/main.cpp | 11 +++++++++++ Kernel/Process.cpp | 7 ++++++- Kernel/Scheduler.cpp | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp index 454207e5d86..602af8fa7e0 100644 --- a/Applications/FileManager/main.cpp +++ b/Applications/FileManager/main.cpp @@ -7,11 +7,22 @@ #include #include #include +#include #include #include "DirectoryTableView.h" int main(int argc, char** argv) { + struct sigaction act; + memset(&act, 0, sizeof(act)); + act.sa_flags = SA_NOCLDWAIT; + act.sa_handler = SIG_IGN; + int rc = sigaction(SIGCHLD, &act, nullptr); + if (rc < 0) { + perror("sigaction"); + return 1; + } + GApplication app(argc, argv); auto mkdir_action = GAction::create("New directory...", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/mkdir16.rgb", { 16, 16 }), [] (const GAction&) { diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 5a859c0b0f0..7d0e549c3bc 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2202,7 +2202,12 @@ void Process::finalize() { InterruptDisabler disabler; if (auto* parent_process = Process::from_pid(m_ppid)) { - parent_process->send_signal(SIGCHLD, this); + if (parent_process->m_signal_action_data[SIGCHLD].flags & SA_NOCLDWAIT) { + // NOTE: If the parent doesn't care about this process, let it go. + m_ppid = 0; + } else { + parent_process->send_signal(SIGCHLD, this); + } } } diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 8b89f4e4fb0..d0e091ee346 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -138,7 +138,7 @@ bool Scheduler::pick_next() } if (process.state() == Process::Dead) { - if (current != &process && !Process::from_pid(process.ppid())) { + if (current != &process && (!process.ppid() || !Process::from_pid(process.ppid()))) { auto name = process.name(); auto pid = process.pid(); auto exit_status = Process::reap(process);