Kernel/LibC: Implement sigwait

This commit is contained in:
Bananymous 2025-08-20 20:16:19 +03:00
parent 247743ef9c
commit def236b7cd
4 changed files with 45 additions and 0 deletions

View File

@ -194,6 +194,7 @@ namespace Kernel
BAN::ErrorOr<long> sys_sigpending(sigset_t* set);
BAN::ErrorOr<long> sys_sigprocmask(int how, const sigset_t* set, sigset_t* oset);
BAN::ErrorOr<long> sys_sigsuspend(const sigset_t* set);
BAN::ErrorOr<long> sys_sigwait(const sigset_t* set, int* sig);
BAN::ErrorOr<long> sys_futex(int op, const uint32_t* addr, uint32_t val, const timespec* abstime);
BAN::ErrorOr<long> sys_yield();

View File

@ -2665,6 +2665,42 @@ namespace Kernel
return BAN::Error::from_errno(EINTR);
}
BAN::ErrorOr<long> Process::sys_sigwait(const sigset_t* set, int* sig)
{
LockGuard _(m_process_lock);
auto& thread = Thread::current();
for (;;)
{
TRY(validate_pointer_access(set, sizeof(sigset_t), false));
TRY(validate_pointer_access(sig, sizeof(int), true));
{
SpinLockGuard _1(thread.m_signal_lock);
SpinLockGuard _2(m_signal_lock);
const uint64_t pending = thread.m_signal_pending_mask | this->m_signal_pending_mask;
if (const auto wait_mask = pending & *set)
{
for (size_t i = _SIGMIN; i <= _SIGMAX; i++)
{
const auto mask = 1ull << i;
if (!(wait_mask & mask))
continue;
thread.m_signal_pending_mask &= ~mask;
this->m_signal_pending_mask &= ~mask;
*sig = i;
return 0;
}
ASSERT_NOT_REACHED();
}
}
Processor::scheduler().block_current_thread(nullptr, -1, &m_process_lock);
}
}
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);

View File

@ -91,6 +91,7 @@ __BEGIN_DECLS
O(SYS_SIGPENDING, sigpending) \
O(SYS_SIGPROCMASK, sigprocmask) \
O(SYS_SIGSUSPEND, sigsuspend) \
O(SYS_SIGWAIT, sigwait) \
O(SYS_SETITIMER, setitimer) \
O(SYS_POSIX_OPENPT, posix_openpt) \
O(SYS_PTSNAME, ptsname) \

View File

@ -169,3 +169,10 @@ int sigsuspend(const sigset_t* sigmask)
{
return syscall(SYS_SIGSUSPEND, sigmask);
}
int sigwait(const sigset_t* __restrict set, int* __restrict sig)
{
if (syscall(SYS_SIGWAIT, set, sig) == -1)
return errno;
return 0;
}