Kernel: Deliver SIGCHLD on process exit and ignore it properly

This commit is contained in:
Bananymous 2024-06-03 17:58:24 +03:00
parent 201aee3119
commit 765ccfa18c
3 changed files with 32 additions and 3 deletions

View File

@ -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

View File

@ -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);

View File

@ -279,8 +279,21 @@ namespace Kernel
auto& interrupt_stack = *reinterpret_cast<InterruptStack*>(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))
{