[libc-commits] [libc] [llvm] [libc] Move linux signal mask helpers into OSUtil/sigmask.h (PR #232647)
Pavel Labath via libc-commits
libc-commits at lists.llvm.org
Fri Oct 16 01:45:35 PDT 2026
https://github.com/labath created https://github.com/llvm/llvm-project/pull/232647
Move internal signal set and mask helpers (full_set, empty_set, add, remove, block_all, set_mask, etc.) out of signal_utils.h and into a new src/__support/OSUtil/linux/sigmask.h header under the signals namespace. This allows other low-level OS utilities and entrypoints to manipulate signal masks without pulling in signal_utils.h (defined under src/signal).
The rest of signal_utils.h should also move, but I'm leaving that for a separate PR (and a separate file) because the rest of the file has more dependencies (RwLock, vdso, __restore_rt), and interacts with more components.
Along with the move:
- fix full_set() on 32-bit systems: sigset_t{{-1UL}} only set the first word, leaving real-time signals unmasked. Now we loop over __signals.
- rename the helpers to shorter names within the signals namespace (add_signal -> add, delete_signal -> remove, restore_signals -> set_mask, etc.) and update existing callers in signal_utils, abort_utils, sigaddset, sigdelset, sigemptyset, and sigfillset.
- add block and get_mask helpers and migrate call sites in sigsetjmp_epilogue and system.
Assisted-by: Gemini
>From de4a5e0d1ae5d32cadb06de59b1b44e8ccf78e66 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Fri, 16 Oct 2026 08:13:51 +0000
Subject: [PATCH] [libc] Move linux signal mask helpers into OSUtil/sigmask.h
Move internal signal set and mask helpers (full_set, empty_set, add,
remove, block_all, set_mask, etc.) out of signal_utils.h and into a new
src/__support/OSUtil/linux/sigmask.h header under the signals namespace.
This allows other low-level OS utilities and entrypoints to manipulate
signal masks without pulling in signal_utils.h (defined under
src/signal).
The rest of signal_utils.h should also move, but I'm leaving that for a
separate PR (and a separate file) because the rest of the file has more
dependencies (RwLock, vdso, __restore_rt), and interacts with more
components.
Along with the move:
- fix full_set() on 32-bit systems: sigset_t{{-1UL}} only set the first
word, leaving real-time signals unmasked. Now we loop over __signals.
- rename the helpers to shorter names within the signals namespace
(add_signal -> add, delete_signal -> remove, restore_signals ->
set_mask, etc.) and update existing callers in signal_utils,
abort_utils, sigaddset, sigdelset, sigemptyset, and sigfillset.
- add block and get_mask helpers and migrate call sites in
sigsetjmp_epilogue and system.
Assisted-by: Gemini
---
.../src/__support/OSUtil/linux/CMakeLists.txt | 15 +++
libc/src/__support/OSUtil/linux/sigmask.h | 122 ++++++++++++++++++
libc/src/setjmp/linux/CMakeLists.txt | 2 +-
libc/src/setjmp/linux/sigsetjmp_epilogue.cpp | 13 +-
libc/src/signal/linux/CMakeLists.txt | 10 +-
libc/src/signal/linux/sigaddset.cpp | 4 +-
libc/src/signal/linux/sigdelset.cpp | 4 +-
libc/src/signal/linux/sigemptyset.cpp | 4 +-
libc/src/signal/linux/sigfillset.cpp | 4 +-
libc/src/signal/linux/signal_utils.h | 52 +-------
libc/src/stdlib/linux/CMakeLists.txt | 3 +-
libc/src/stdlib/linux/abort_utils.h | 4 +-
libc/src/stdlib/linux/system.cpp | 14 +-
libc/test/src/signal/sigfillset_test.cpp | 9 +-
.../llvm-project-overlay/libc/BUILD.bazel | 24 +++-
15 files changed, 198 insertions(+), 86 deletions(-)
create mode 100644 libc/src/__support/OSUtil/linux/sigmask.h
diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index e01f079c6780e5..22004c234650c7 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -66,6 +66,21 @@ add_header_library(
libc.src.__support.CPP.string_view
)
+add_header_library(
+ sigmask
+ HDRS
+ sigmask.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.signal_macros
+ libc.hdr.types.sigset_t
+ libc.hdr.types.size_t
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigprocmask
+)
+
add_header_library(
sysinfo
HDRS
diff --git a/libc/src/__support/OSUtil/linux/sigmask.h b/libc/src/__support/OSUtil/linux/sigmask.h
new file mode 100644
index 00000000000000..25ade4a1f3aea4
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/sigmask.h
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Internal Linux signal mask helpers.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SIGMASK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SIGMASK_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/signal_macros.h"
+#include "hdr/types/sigset_t.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigprocmask.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace signals {
+
+static constexpr size_t BITS_PER_SIGWORD = sizeof(unsigned long) * 8;
+
+/// Return a signal set with all signals set.
+LIBC_INLINE constexpr sigset_t full_set() {
+ sigset_t set{};
+ for (unsigned long &sigword : set.__signals)
+ sigword = -1UL;
+ return set;
+}
+
+/// Return an empty signal set with no signals set.
+LIBC_INLINE constexpr sigset_t empty_set() { return sigset_t{}; }
+
+/// Set or clear the bit corresponding to |signal| in |set| according to
+/// |value|. Return true on success and false if |signal| is out of range.
+LIBC_INLINE constexpr bool set_bit(sigset_t &set, int signal, bool value) {
+ if (signal >= NSIG || signal <= 0)
+ return false;
+ size_t n = static_cast<size_t>(signal) - 1;
+ size_t word = n / BITS_PER_SIGWORD;
+ size_t bit = n % BITS_PER_SIGWORD;
+ if (value)
+ set.__signals[word] |= (1UL << bit);
+ else
+ set.__signals[word] &= ~(1UL << bit);
+ return true;
+}
+
+/// Set the bit corresponding to |signal| in |set|. Return true on success
+/// and false on failure. |signal| must be less than NSIG and be positive.
+LIBC_INLINE constexpr bool add(sigset_t &set, int signal) {
+ return set_bit(set, signal, true);
+}
+
+/// Clear the bit corresponding to |signal| in |set|. Return true on success
+/// and false on failure. |signal| must be less than NSIG and be positive.
+LIBC_INLINE constexpr bool remove(sigset_t &set, int signal) {
+ return set_bit(set, signal, false);
+}
+
+/// Block the signals in |set|. If |old_set| is non-null, store the previous
+/// signal mask in |*old_set|.
+LIBC_INLINE ErrorOr<int> block(const sigset_t &set,
+ sigset_t *old_set = nullptr) {
+ return linux_syscalls::rt_sigprocmask(SIG_BLOCK, &set, old_set);
+}
+
+/// Block a single |signal|. If |old_set| is non-null, store the previous
+/// signal mask in |*old_set|.
+LIBC_INLINE ErrorOr<int> block(int signal, sigset_t *old_set = nullptr) {
+ sigset_t set = empty_set();
+ if (!add(set, signal))
+ return Error(EINVAL);
+ return block(set, old_set);
+}
+
+/// Block all signals. If |old_set| is non-null, store the previous signal mask
+/// in |*old_set|.
+LIBC_INLINE ErrorOr<int> block_all(sigset_t *old_set = nullptr) {
+ return block(full_set(), old_set);
+}
+
+/// Set the signal mask to |set|. If |old_set| is non-null, store the previous
+/// signal mask in |*old_set|.
+LIBC_INLINE ErrorOr<int> set_mask(const sigset_t &set,
+ sigset_t *old_set = nullptr) {
+ return linux_syscalls::rt_sigprocmask(SIG_SETMASK, &set, old_set);
+}
+
+/// Store the current signal mask in |set|.
+LIBC_INLINE ErrorOr<int> get_mask(sigset_t &set) {
+ return linux_syscalls::rt_sigprocmask(SIG_SETMASK, nullptr, &set);
+}
+
+/// Unblock the signals in |set|. If |old_set| is non-null, store the previous
+/// signal mask in |*old_set|.
+LIBC_INLINE ErrorOr<int> unblock(const sigset_t &set,
+ sigset_t *old_set = nullptr) {
+ return linux_syscalls::rt_sigprocmask(SIG_UNBLOCK, &set, old_set);
+}
+
+/// Unblock a single |signal|. If |old_set| is non-null, store the previous
+/// signal mask in |*old_set|.
+LIBC_INLINE ErrorOr<int> unblock(int signal, sigset_t *old_set = nullptr) {
+ sigset_t set = empty_set();
+ if (!add(set, signal))
+ return Error(EINVAL);
+ return unblock(set, old_set);
+}
+
+} // namespace signals
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SIGMASK_H
diff --git a/libc/src/setjmp/linux/CMakeLists.txt b/libc/src/setjmp/linux/CMakeLists.txt
index bde4e5b87392bf..215145729f270f 100644
--- a/libc/src/setjmp/linux/CMakeLists.txt
+++ b/libc/src/setjmp/linux/CMakeLists.txt
@@ -6,7 +6,7 @@ add_object_library(
sigsetjmp_epilogue.cpp
DEPENDS
libc.src.__support.common
- libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigprocmask
+ libc.src.__support.OSUtil.linux.sigmask
libc.hdr.types.sigjmp_buf
libc.hdr.types.sigset_t
)
diff --git a/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp b/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
index 7922f51225f3c0..176deaaa654e66 100644
--- a/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
+++ b/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
@@ -7,18 +7,15 @@
//===----------------------------------------------------------------------===//
#include "src/setjmp/sigsetjmp_epilogue.h"
-#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigprocmask.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE_DECL {
[[gnu::returns_twice]] int sigsetjmp_epilogue(sigjmp_buf buffer, int retval) {
- // If set is NULL, then the signal mask is unchanged (i.e., how is
- // ignored), but the current value of the signal mask is nevertheless
- // returned in oldset (if it is not NULL).
- linux_syscalls::rt_sigprocmask(
- SIG_SETMASK,
- /* set= */ retval ? &buffer->sigmask : nullptr,
- /* old_set= */ retval ? nullptr : &buffer->sigmask);
+ if (retval)
+ signals::set_mask(buffer->sigmask);
+ else
+ signals::get_mask(buffer->sigmask);
return retval;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index 8360ce21364766..c035a4915e132f 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -10,7 +10,7 @@ add_header_library(
libc.include.sys_syscall
libc.src.__support.OSUtil.linux.vdso
libc.src.__support.OSUtil.osutil
- libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigprocmask
+ libc.src.__support.OSUtil.linux.sigmask
libc.src.__support.error_or
libc.src.__support.threads.raw_rwlock
)
@@ -131,8 +131,8 @@ add_entrypoint_object(
HDRS
../sigemptyset.h
DEPENDS
- .signal_utils
libc.hdr.types.sigset_t
+ libc.src.__support.OSUtil.linux.sigmask
libc.src.errno.errno
)
@@ -143,8 +143,8 @@ add_entrypoint_object(
HDRS
../sigaddset.h
DEPENDS
- .signal_utils
libc.hdr.types.sigset_t
+ libc.src.__support.OSUtil.linux.sigmask
libc.src.errno.errno
)
@@ -166,8 +166,8 @@ add_entrypoint_object(
HDRS
../sigfillset.h
DEPENDS
- .signal_utils
libc.hdr.types.sigset_t
+ libc.src.__support.OSUtil.linux.sigmask
libc.src.errno.errno
)
@@ -178,7 +178,7 @@ add_entrypoint_object(
HDRS
../sigdelset.h
DEPENDS
- .signal_utils
libc.hdr.types.sigset_t
+ libc.src.__support.OSUtil.linux.sigmask
libc.src.errno.errno
)
diff --git a/libc/src/signal/linux/sigaddset.cpp b/libc/src/signal/linux/sigaddset.cpp
index 2091e8b51453fb..2372d4a8654d44 100644
--- a/libc/src/signal/linux/sigaddset.cpp
+++ b/libc/src/signal/linux/sigaddset.cpp
@@ -9,15 +9,15 @@
#include "src/signal/sigaddset.h"
#include "hdr/types/sigset_t.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/signal/linux/signal_utils.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(int, sigaddset, (sigset_t * set, int signum)) {
- if (set != nullptr && add_signal(*set, signum))
+ if (set != nullptr && signals::add(*set, signum))
return 0;
libc_errno = EINVAL;
return -1;
diff --git a/libc/src/signal/linux/sigdelset.cpp b/libc/src/signal/linux/sigdelset.cpp
index 6fce0d7a6e1474..36b4df3024d363 100644
--- a/libc/src/signal/linux/sigdelset.cpp
+++ b/libc/src/signal/linux/sigdelset.cpp
@@ -9,15 +9,15 @@
#include "src/signal/sigdelset.h"
#include "hdr/types/sigset_t.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/signal/linux/signal_utils.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(int, sigdelset, (sigset_t * set, int signum)) {
- if (set != nullptr && delete_signal(*set, signum))
+ if (set != nullptr && signals::remove(*set, signum))
return 0;
libc_errno = EINVAL;
return -1;
diff --git a/libc/src/signal/linux/sigemptyset.cpp b/libc/src/signal/linux/sigemptyset.cpp
index 788983f429baa0..d80a3186bc234e 100644
--- a/libc/src/signal/linux/sigemptyset.cpp
+++ b/libc/src/signal/linux/sigemptyset.cpp
@@ -7,10 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/signal/sigemptyset.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/signal/linux/signal_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(int, sigemptyset, (sigset_t * set)) {
libc_errno = EINVAL;
return -1;
}
- *set = empty_set();
+ *set = signals::empty_set();
return 0;
}
diff --git a/libc/src/signal/linux/sigfillset.cpp b/libc/src/signal/linux/sigfillset.cpp
index f0b499093b3198..cc8c9b7dd09e88 100644
--- a/libc/src/signal/linux/sigfillset.cpp
+++ b/libc/src/signal/linux/sigfillset.cpp
@@ -9,10 +9,10 @@
#include "src/signal/sigfillset.h"
#include "hdr/types/sigset_t.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include "src/signal/linux/signal_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -21,7 +21,7 @@ LLVM_LIBC_FUNCTION(int, sigfillset, (sigset_t * set)) {
libc_errno = EINVAL;
return -1;
}
- *set = full_set();
+ *set = signals::full_set();
return 0;
}
diff --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index 7a78b00d865de6..07b89e8e921289 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -14,7 +14,7 @@
#include "hdr/types/sigset_t.h"
#include "hdr/types/size_t.h"
#include "hdr/types/struct_sigaction.h"
-#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigprocmask.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/OSUtil/linux/vdso.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
@@ -72,52 +72,6 @@ struct KernelSigaction {
sigset_t sa_mask;
};
-static constexpr size_t BITS_PER_SIGWORD = sizeof(unsigned long) * 8;
-
-LIBC_INLINE constexpr sigset_t full_set() { return sigset_t{{-1UL}}; }
-
-LIBC_INLINE constexpr sigset_t empty_set() { return sigset_t{{0}}; }
-
-// Set the bit corresponding to |signal| in |set|. Return true on success
-// and false on failure. |signal| must be less than NSIG and be positive.
-LIBC_INLINE constexpr bool add_signal(sigset_t &set, int signal) {
- if (signal >= NSIG || signal <= 0)
- return false;
- size_t n = size_t(signal) - 1;
- size_t word = n / BITS_PER_SIGWORD;
- size_t bit = n % BITS_PER_SIGWORD;
- set.__signals[word] |= (1UL << bit);
- return true;
-}
-
-// Reset the bit corresponding to |signal| in |set|. Return true on success
-// and false on failure. |signal| must be less than NSIG and be positive.
-LIBC_INLINE constexpr bool delete_signal(sigset_t &set, int signal) {
- if (signal >= NSIG || signal <= 0)
- return false;
- size_t n = size_t(signal) - 1;
- size_t word = n / BITS_PER_SIGWORD;
- size_t bit = n % BITS_PER_SIGWORD;
- set.__signals[word] &= ~(1UL << bit);
- return true;
-}
-
-LIBC_INLINE ErrorOr<int> block_all_signals(sigset_t &set) {
- sigset_t full = full_set();
- return linux_syscalls::rt_sigprocmask(SIG_BLOCK, &full, &set);
-}
-
-LIBC_INLINE ErrorOr<int> restore_signals(const sigset_t &set) {
- return linux_syscalls::rt_sigprocmask(SIG_SETMASK, &set, nullptr);
-}
-
-LIBC_INLINE ErrorOr<int> unblock_signal(int signal) {
- sigset_t set = empty_set();
- if (!add_signal(set, signal))
- return Error(EINVAL);
- return linux_syscalls::rt_sigprocmask(SIG_UNBLOCK, &set, nullptr);
-}
-
// This guard is used to:
// 1. temporarily block the all signal, avoid post fork invalid state to be
// exposed to async signal handlers.
@@ -140,13 +94,13 @@ class SigAbortGuard {
// This uses a valid sigset_t size and internal storage. A failure here
// would indicate a kernel ABI mismatch, which is not actionable here.
- (void)block_all_signals(old_mask);
+ (void)signals::block_all(&old_mask);
}
LIBC_INLINE ~SigAbortGuard() {
// This restores a previously saved mask from internal storage. A failure
// here would likewise be a non-recoverable kernel ABI issue.
- (void)restore_signals(old_mask);
+ (void)signals::set_mask(old_mask);
(void)abort_lock.unlock();
}
};
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
index c40fc6a5b84ce7..f0dff355f5789d 100644
--- a/libc/src/stdlib/linux/CMakeLists.txt
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -3,6 +3,7 @@ add_header_library(
HDRS
abort_utils.h
DEPENDS
+ libc.src.__support.OSUtil.linux.sigmask
libc.src.__support.OSUtil.linux.syscall_wrappers.raise
libc.src.__support.OSUtil.osutil
libc.src.signal.linux.__restore
@@ -122,10 +123,10 @@ add_entrypoint_object(
libc.src.__support.libc_errno
libc.src.__support.macros.config
libc.src.__support.OSUtil.osutil
+ libc.src.__support.OSUtil.linux.sigmask
libc.src.__support.OSUtil.linux.syscall_wrappers.execle
libc.src.__support.OSUtil.linux.syscall_wrappers.clone3
libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigaction
- libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigprocmask
libc.src.__support.OSUtil.linux.syscall_wrappers.wait4
libc.src.signal.linux.signal_utils
libc.src.unistd.environ
diff --git a/libc/src/stdlib/linux/abort_utils.h b/libc/src/stdlib/linux/abort_utils.h
index 9ba752ed252bb7..b7a42d7dda824e 100644
--- a/libc/src/stdlib/linux/abort_utils.h
+++ b/libc/src/stdlib/linux/abort_utils.h
@@ -9,9 +9,9 @@
#ifndef LLVM_LIBC_SRC_STDLIB_LINUX_ABORT_UTILS_H
#define LLVM_LIBC_SRC_STDLIB_LINUX_ABORT_UTILS_H
-#include "hdr/types/sigset_t.h"
#include "hdr/types/struct_sigaction.h"
#include "src/__support/OSUtil/exit.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/raise.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
@@ -43,7 +43,7 @@ namespace abort_utils {
// Now unblock the signal. The pending abort signal is now unblocked and
// should be delivered to its default handler.
// If this fails, there is still no meaningful recovery path while aborting.
- (void)unblock_signal(SIGABRT);
+ (void)signals::unblock(SIGABRT);
internal::exit(127);
}
diff --git a/libc/src/stdlib/linux/system.cpp b/libc/src/stdlib/linux/system.cpp
index f40e1f8756b155..f80987633bdcb0 100644
--- a/libc/src/stdlib/linux/system.cpp
+++ b/libc/src/stdlib/linux/system.cpp
@@ -17,10 +17,10 @@
#include "hdr/types/pid_t.h"
#include "hdr/types/sigset_t.h"
#include "src/__support/OSUtil/exit.h"
+#include "src/__support/OSUtil/linux/sigmask.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/clone3.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/execle.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigaction.h"
-#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigprocmask.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/wait4.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
@@ -57,12 +57,8 @@ LLVM_LIBC_FUNCTION(int, system, (const char *command)) {
return -1;
}
- sigset_t block_mask{};
- add_signal(block_mask, SIGCHLD);
sigset_t orig_mask{};
- if (auto res =
- linux_syscalls::rt_sigprocmask(SIG_BLOCK, &block_mask, &orig_mask);
- !res.has_value()) {
+ if (auto res = signals::block(SIGCHLD, &orig_mask); !res.has_value()) {
linux_syscalls::rt_sigaction(SIGINT, &orig_int, nullptr);
linux_syscalls::rt_sigaction(SIGQUIT, &orig_quit, nullptr);
libc_errno = res.error();
@@ -75,7 +71,7 @@ LLVM_LIBC_FUNCTION(int, system, (const char *command)) {
if (!fork_res.has_value()) {
linux_syscalls::rt_sigaction(SIGINT, &orig_int, nullptr);
linux_syscalls::rt_sigaction(SIGQUIT, &orig_quit, nullptr);
- linux_syscalls::rt_sigprocmask(SIG_SETMASK, &orig_mask, nullptr);
+ signals::set_mask(orig_mask);
libc_errno = fork_res.error();
return -1;
}
@@ -84,7 +80,7 @@ LLVM_LIBC_FUNCTION(int, system, (const char *command)) {
if (pid == 0) {
linux_syscalls::rt_sigaction(SIGINT, &orig_int, nullptr);
linux_syscalls::rt_sigaction(SIGQUIT, &orig_quit, nullptr);
- linux_syscalls::rt_sigprocmask(SIG_SETMASK, &orig_mask, nullptr);
+ signals::set_mask(orig_mask);
// Error checking isn't helpful since this is the forked process, so we
// can't set errno. All we can meaningfully do is exit with status 127.
@@ -110,7 +106,7 @@ LLVM_LIBC_FUNCTION(int, system, (const char *command)) {
linux_syscalls::rt_sigaction(SIGINT, &orig_int, nullptr);
linux_syscalls::rt_sigaction(SIGQUIT, &orig_quit, nullptr);
- linux_syscalls::rt_sigprocmask(SIG_SETMASK, &orig_mask, nullptr);
+ signals::set_mask(orig_mask);
return wait_ret;
}
diff --git a/libc/test/src/signal/sigfillset_test.cpp b/libc/test/src/signal/sigfillset_test.cpp
index 1f69734404e18a..b1074987f2bd2f 100644
--- a/libc/test/src/signal/sigfillset_test.cpp
+++ b/libc/test/src/signal/sigfillset_test.cpp
@@ -25,5 +25,12 @@ TEST(LlvmLibcSigfillset, BlocksAll) {
EXPECT_THAT(LIBC_NAMESPACE::sigfillset(&set), Succeeds());
EXPECT_THAT(LIBC_NAMESPACE::sigprocmask(SIG_SETMASK, &set, nullptr),
Succeeds());
- EXPECT_EXITS([] { LIBC_NAMESPACE::raise(SIGUSR1); }, 0);
+ EXPECT_EXITS(
+ [] {
+ LIBC_NAMESPACE::raise(SIGUSR1);
+#ifdef SIGRTMAX
+ LIBC_NAMESPACE::raise(SIGRTMAX);
+#endif
+ },
+ 0);
}
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 457de6f7048762..43bb5b522823c0 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -4380,6 +4380,26 @@ libc_support_library(
}),
)
+libc_support_library(
+ name = "__support_osutil_linux_sigmask",
+ hdrs = ["src/__support/OSUtil/linux/sigmask.h"],
+ full_build_only = True,
+ target_compatible_with = select({
+ "@platforms//os:linux": [],
+ "//conditions:default": ["@platforms//:incompatible"],
+ }),
+ deps = [
+ ":__support_common",
+ ":__support_error_or",
+ ":__support_macros_config",
+ ":__support_osutil_linux_syscall_wrappers_rt_sigprocmask",
+ ":hdr_errno_macros",
+ ":hdr_signal_macros",
+ ":types_sigset_t",
+ ":types_size_t",
+ ],
+)
+
libc_support_library(
name = "__support_stringutil",
srcs = glob(["src/__support/StringUtil/tables/**/*.h"]) + [
@@ -15801,8 +15821,8 @@ libc_support_library(
":__support_common",
":__support_macros_config",
":__support_osutil_exit",
+ ":__support_osutil_linux_sigmask",
":__support_osutil_linux_syscall_wrappers_raise",
- ":types_sigset_t",
":types_struct_sigaction",
],
)
@@ -17168,7 +17188,7 @@ libc_support_library(
":__support_common",
":__support_error_or",
":__support_macros_config",
- ":__support_osutil_linux_syscall_wrappers_rt_sigprocmask",
+ ":__support_osutil_linux_sigmask",
":__support_osutil_syscall",
":__support_osutil_vdso",
":__support_threads_raw_rwlock",
More information about the libc-commits
mailing list