mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:47:36 +00:00
Kernel: Implement sigsuspend
using a SignalBlocker
`sigsuspend` was previously implemented using a poll on an empty set of file descriptors. However, this broke quite a few assumptions in `SelectBlocker`, as it verifies at least one file descriptor to be ready after waking up and as it relies on being notified by the file descriptor. A bare-bones `sigsuspend` may also be implemented by relying on any of the `sigwait` functions, but as `sigsuspend` features several (currently unimplemented) restrictions on how returns work, it is a syscall on its own.
This commit is contained in:
parent
edbffb3c7a
commit
cf0ad3715e
4 changed files with 28 additions and 1 deletions
|
@ -170,6 +170,7 @@ enum class NeedsBigProcessLock {
|
||||||
S(sigpending, NeedsBigProcessLock::Yes) \
|
S(sigpending, NeedsBigProcessLock::Yes) \
|
||||||
S(sigprocmask, NeedsBigProcessLock::Yes) \
|
S(sigprocmask, NeedsBigProcessLock::Yes) \
|
||||||
S(sigreturn, NeedsBigProcessLock::Yes) \
|
S(sigreturn, NeedsBigProcessLock::Yes) \
|
||||||
|
S(sigsuspend, NeedsBigProcessLock::Yes) \
|
||||||
S(sigtimedwait, NeedsBigProcessLock::Yes) \
|
S(sigtimedwait, NeedsBigProcessLock::Yes) \
|
||||||
S(socket, NeedsBigProcessLock::Yes) \
|
S(socket, NeedsBigProcessLock::Yes) \
|
||||||
S(socketpair, NeedsBigProcessLock::Yes) \
|
S(socketpair, NeedsBigProcessLock::Yes) \
|
||||||
|
|
|
@ -334,6 +334,7 @@ public:
|
||||||
ErrorOr<FlatPtr> sys$sigaltstack(Userspace<stack_t const*> ss, Userspace<stack_t*> old_ss);
|
ErrorOr<FlatPtr> sys$sigaltstack(Userspace<stack_t const*> ss, Userspace<stack_t*> old_ss);
|
||||||
ErrorOr<FlatPtr> sys$sigprocmask(int how, Userspace<sigset_t const*> set, Userspace<sigset_t*> old_set);
|
ErrorOr<FlatPtr> sys$sigprocmask(int how, Userspace<sigset_t const*> set, Userspace<sigset_t*> old_set);
|
||||||
ErrorOr<FlatPtr> sys$sigpending(Userspace<sigset_t*>);
|
ErrorOr<FlatPtr> sys$sigpending(Userspace<sigset_t*>);
|
||||||
|
ErrorOr<FlatPtr> sys$sigsuspend(Userspace<sigset_t const*>);
|
||||||
ErrorOr<FlatPtr> sys$sigtimedwait(Userspace<sigset_t const*>, Userspace<siginfo_t*>, Userspace<timespec const*>);
|
ErrorOr<FlatPtr> sys$sigtimedwait(Userspace<sigset_t const*>, Userspace<siginfo_t*>, Userspace<timespec const*>);
|
||||||
ErrorOr<FlatPtr> sys$getgroups(size_t, Userspace<gid_t*>);
|
ErrorOr<FlatPtr> sys$getgroups(size_t, Userspace<gid_t*>);
|
||||||
ErrorOr<FlatPtr> sys$setgroups(size_t, Userspace<gid_t const*>);
|
ErrorOr<FlatPtr> sys$setgroups(size_t, Userspace<gid_t const*>);
|
||||||
|
|
|
@ -326,4 +326,28 @@ ErrorOr<FlatPtr> Process::sys$sigtimedwait(Userspace<sigset_t const*> set, Users
|
||||||
return info_value.si_signo;
|
return info_value.si_signo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html
|
||||||
|
ErrorOr<FlatPtr> Process::sys$sigsuspend(Userspace<sigset_t const*> mask)
|
||||||
|
{
|
||||||
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
|
|
||||||
|
auto sigmask = TRY(copy_typed_from_user(mask));
|
||||||
|
|
||||||
|
auto* current_thread = Thread::current();
|
||||||
|
|
||||||
|
u32 previous_signal_mask = current_thread->update_signal_mask(sigmask);
|
||||||
|
ScopeGuard rollback_signal_mask([&]() {
|
||||||
|
current_thread->update_signal_mask(previous_signal_mask);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: Ensure that/check if we never return if the action is to terminate the process.
|
||||||
|
// TODO: Ensure that/check if we only return after an eventual signal-catching function returns.
|
||||||
|
Thread::BlockTimeout timeout = {};
|
||||||
|
siginfo_t siginfo = {};
|
||||||
|
if (current_thread->block<Thread::SignalBlocker>(timeout, ~sigmask, siginfo).was_interrupted())
|
||||||
|
return EINTR;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,7 +175,8 @@ void siglongjmp(jmp_buf env, int val)
|
||||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html
|
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html
|
||||||
int sigsuspend(sigset_t const* set)
|
int sigsuspend(sigset_t const* set)
|
||||||
{
|
{
|
||||||
return pselect(0, nullptr, nullptr, nullptr, nullptr, set);
|
int rc = syscall(SC_sigsuspend, set);
|
||||||
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://pubs.opengroup.org/onlinepubs/009604499/functions/sigwait.html
|
// https://pubs.opengroup.org/onlinepubs/009604499/functions/sigwait.html
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue