Kernel/LibC: Implement sigsuspend
This commit is contained in:
@@ -2651,6 +2651,20 @@ namespace Kernel
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_sigsuspend(const sigset_t* set)
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_pointer_access(set, sizeof(sigset_t), false));
|
||||
|
||||
auto& thread = Thread::current();
|
||||
thread.set_suspend_signal_mask(*set & ~(SIGKILL | SIGSTOP));
|
||||
|
||||
while (!thread.is_interrupted_by_signal())
|
||||
Processor::scheduler().block_current_thread(nullptr, -1, &m_process_lock);
|
||||
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime)
|
||||
{
|
||||
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(addr);
|
||||
|
||||
@@ -547,6 +547,12 @@ namespace Kernel
|
||||
m_signal_pending_mask &= ~(1ull << signal);
|
||||
process().remove_pending_signal(signal);
|
||||
|
||||
if (m_signal_suspend_mask.has_value())
|
||||
{
|
||||
m_signal_block_mask = m_signal_suspend_mask.value();
|
||||
m_signal_suspend_mask.clear();
|
||||
}
|
||||
|
||||
if (signal_handler == (vaddr_t)SIG_IGN)
|
||||
;
|
||||
else if (signal_handler != (vaddr_t)SIG_DFL)
|
||||
@@ -643,6 +649,14 @@ namespace Kernel
|
||||
Processor::scheduler().unblock_thread(this);
|
||||
}
|
||||
|
||||
void Thread::set_suspend_signal_mask(uint64_t sigmask)
|
||||
{
|
||||
SpinLockGuard _(m_signal_lock);
|
||||
ASSERT(!m_signal_suspend_mask.has_value());
|
||||
m_signal_suspend_mask = m_signal_block_mask;
|
||||
m_signal_block_mask = sigmask;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Thread::sleep_or_eintr_ns(uint64_t ns)
|
||||
{
|
||||
if (is_interrupted_by_signal())
|
||||
|
||||
Reference in New Issue
Block a user