From 239e1fcc48ac57a7a15d0ac80714a1ef9cbee71f Mon Sep 17 00:00:00 2001 From: Michalis Pappas Date: Fri, 26 Jan 2024 03:53:09 +0100 Subject: [PATCH] lib/posix-process/signal: Add rt_sigtimedwait() rt_sigtimedwait() suspends the execution of the calling thread until a signal in a caller-provided mask is pending, or a caller provided timeout is reached. For more info see sigwaitinfo(2) Signed-off-by: Michalis Pappas Reviewed-by: Ioan-Teodor Teugea Reviewed-by: Sergiu Moga Reviewed-by: Andrei Tatar Approved-by: Andrei Tatar GitHub-Closes: #1248 --- lib/posix-process/Makefile.uk | 2 + lib/posix-process/signal/rt_sigtimedwait.c | 72 ++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 lib/posix-process/signal/rt_sigtimedwait.c diff --git a/lib/posix-process/Makefile.uk b/lib/posix-process/Makefile.uk index d256cfdbb..d43f420ce 100644 --- a/lib/posix-process/Makefile.uk +++ b/lib/posix-process/Makefile.uk @@ -30,6 +30,7 @@ LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigsuspend.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigaction.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigqueueinfo.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_tgsigqueueinfo.c +LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigtimedwait.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/kill.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/tgkill.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/tkill.c @@ -58,6 +59,7 @@ UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigsuspend-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigaction-4 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigqueueinfo-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_tgsigqueueinfo-4 +UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigtimedwait-4 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += kill-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += tgkill-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += tkill-2 diff --git a/lib/posix-process/signal/rt_sigtimedwait.c b/lib/posix-process/signal/rt_sigtimedwait.c new file mode 100644 index 000000000..bd7fbda47 --- /dev/null +++ b/lib/posix-process/signal/rt_sigtimedwait.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include +#include +#include + +#include +#include +#include + +#include "process.h" +#include "signal.h" + +#if CONFIG_LIBPOSIX_PROCESS_SIGNAL +UK_LLSYSCALL_R_DEFINE(int, rt_sigtimedwait, + const uk_sigset_t *, set, + siginfo_t *, info, + const struct timespec *, timeout, + size_t, sigsetsize) +{ + struct posix_thread *pthread; + struct uk_signal *sig; + + if (unlikely(!set)) + return -EINVAL; + + if (unlikely(sigsetsize != sizeof(sigset_t))) + return -EINVAL; + + pthread = uk_pthread_current(); + UK_ASSERT(pthread); + + /* TODO protect concurrent access by deliver_pending_proc() */ + uk_sigcopyset(&pthread->signal->sigwait_set, set); + + /* If a signal in the set is already pending return immediately */ + if ((sig = pprocess_signal_next_pending_t(pthread))) + goto out; + + if (timeout) + uk_semaphore_down_to(&pthread->signal->pending_semaphore, + uk_time_spec_to_nsec(timeout)); + else + uk_semaphore_down(&pthread->signal->pending_semaphore); + + if ((sig = pprocess_signal_next_pending_t(pthread))) + goto out; + + return -EAGAIN; +out: + if (info) + *info = sig->siginfo; + uk_sigemptyset(&pthread->signal->sigwait_set); + return sig->siginfo.si_signo; +} +#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */ +UK_LLSYSCALL_R_DEFINE(int, rt_sigtimedwait, + const uk_sigset_t *, set, + siginfo_t *, info, + const struct timespec *, timeout, + size_t, sigsetsize) +{ + UK_WARN_STUBBED(); + *info = (siginfo_t){0}; + info->si_signo = SIGINT; + return 0; +} +#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */ -- 2.39.5