From 9e466accaadfa029aa0ccb779dfe983bf239b80d Mon Sep 17 00:00:00 2001 From: Michalis Pappas Date: Tue, 16 Jan 2024 12:49:36 +0100 Subject: [PATCH] lib/posix-process/signal: Add sigsuspend() sigsuspend() temporarily replaces the signal mask of the current thread and suspends its execution until a signal is delivered. For more info see sigsuspend(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_sigsuspend.c | 56 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 lib/posix-process/signal/rt_sigsuspend.c diff --git a/lib/posix-process/Makefile.uk b/lib/posix-process/Makefile.uk index a174a4a30..d256cfdbb 100644 --- a/lib/posix-process/Makefile.uk +++ b/lib/posix-process/Makefile.uk @@ -26,6 +26,7 @@ LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/pause.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/sigaltstack.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigpending.c LIBPOSIX_PROCESS_SRCS-y += $(LIBPOSIX_PROCESS_BASE)/signal/rt_sigprocmask.c +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 @@ -53,6 +54,7 @@ UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += pause-0 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += sigaltstack-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigpending-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_PROCESS) += rt_sigprocmask-4 +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 diff --git a/lib/posix-process/signal/rt_sigsuspend.c b/lib/posix-process/signal/rt_sigsuspend.c new file mode 100644 index 000000000..3faf3d1b4 --- /dev/null +++ b/lib/posix-process/signal/rt_sigsuspend.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, 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 "signal.h" +#include "sigset.h" + +#if CONFIG_LIBPOSIX_PROCESS_SIGNAL +UK_LLSYSCALL_R_DEFINE(int, rt_sigsuspend, + const uk_sigset_t *, mask, + size_t, sigsetsize) +{ + struct posix_thread *pthread; + uk_sigset_t suspend_mask; + uk_sigset_t saved_mask; + + pthread = uk_pthread_current(); + UK_ASSERT(pthread); + + if (unlikely(sigsetsize != sizeof(uk_sigset_t))) + return -EINVAL; + + /* It is not possible to block SIGKILL & SIGSTOP */ + uk_sigcopyset(&suspend_mask, mask); + uk_sigdelset(&suspend_mask, SIGKILL); + uk_sigdelset(&suspend_mask, SIGSTOP); + + /* Temporarily replace mask */ + saved_mask = pthread->signal->mask; + pthread->signal->mask = suspend_mask; + + /* Wait for signal */ + pthread->state = POSIX_THREAD_BLOCKED_SIGNAL; + uk_semaphore_down(&pthread->signal->deliver_semaphore); + + /* Restore mask */ + pthread->signal->mask = saved_mask; + + return -EINTR; +} +#else /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */ +UK_LLSYSCALL_R_DEFINE(int, rt_sigsuspend, + const uk_sigset_t *, mask, + size_t, sigsetsize) +{ + UK_WARN_STUBBED(); + return -EINTR; +} +#endif /* !CONFIG_LIBPOSIX_PROCESS_SIGNAL */ -- 2.39.5