From 765ccfa18c91b623891f588f6d766e2cec96dd07 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 3 Jun 2024 17:58:24 +0300 Subject: [PATCH] Kernel: Deliver SIGCHLD on process exit and ignore it properly --- kernel/include/kernel/Process.h | 5 +++++ kernel/kernel/Process.cpp | 4 ++++ kernel/kernel/Thread.cpp | 26 +++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 84bc6b96..9a09082b 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -220,6 +220,11 @@ namespace Kernel ASSERT(signal >= _SIGMIN); ASSERT(signal <= _SIGMAX); ASSERT(signal < 64); + vaddr_t handler = m_signal_handlers[signal]; + if (handler == (vaddr_t)SIG_IGN) + return; + if (handler == (vaddr_t)SIG_DFL && (signal == SIGCHLD || signal == SIGURG)) + return; if (signal < 32) m_signal_pending_mask[0] |= (uint32_t)1 << signal; else diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index ac737e58..3dfd5b10 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -195,8 +195,12 @@ namespace Kernel { SpinLockGuard _(s_process_lock); for (size_t i = 0; i < s_processes.size(); i++) + { + if (m_parent && s_processes[i]->pid() == m_parent) + s_processes[i]->add_pending_signal(SIGCHLD); if (s_processes[i] == this) s_processes.remove(i); + } } ProcFileSystem::get().on_process_delete(*this); diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index 7ecef600..75c60570 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -279,8 +279,21 @@ namespace Kernel auto& interrupt_stack = *reinterpret_cast(kernel_stack_top() - sizeof(InterruptStack)); if (!GDT::is_user_segment(interrupt_stack.cs)) return false; - uint64_t full_pending_mask = m_signal_pending_mask | process().signal_pending_mask();; - return full_pending_mask & ~m_signal_block_mask; + + uint64_t full_pending_mask = m_signal_pending_mask | process().signal_pending_mask(); + uint64_t signals = full_pending_mask & ~m_signal_block_mask; + for (uint8_t i = 0; i < _SIGMAX; i++) + { + if (!(signals & ((uint64_t)1 << i))) + continue; + vaddr_t handler = m_process->m_signal_handlers[i]; + if (handler == (vaddr_t)SIG_IGN) + continue; + if (handler == (vaddr_t)SIG_DFL && (i == SIGCHLD || i == SIGURG)) + continue; + return true; + } + return false; } bool Thread::can_add_signal_to_execute() const @@ -395,7 +408,14 @@ namespace Kernel bool Thread::add_signal(int signal) { SpinLockGuard _(m_signal_lock); - + if (m_process) + { + vaddr_t handler = m_process->m_signal_handlers[signal]; + if (handler == (vaddr_t)SIG_IGN) + return false; + if (handler == (vaddr_t)SIG_DFL && (signal == SIGCHLD || signal == SIGURG)) + return false; + } uint64_t mask = 1ull << signal; if (!(m_signal_block_mask & mask)) {