[libc] Update NSIG value and usage on Linux. - #217481
Merged
Merged
Conversation
|
@llvm/pr-subscribers-libc Author: Alexey Samsonov (vonosmas) Changes
Full diff: https://github.com/llvm/llvm-project/pull/217481.diff 4 Files Affected:
diff --git a/libc/include/llvm-libc-macros/linux/signal-macros.h b/libc/include/llvm-libc-macros/linux/signal-macros.h
index e9fff447f9086..1f98e1c76bd66 100644
--- a/libc/include/llvm-libc-macros/linux/signal-macros.h
+++ b/libc/include/llvm-libc-macros/linux/signal-macros.h
@@ -45,22 +45,23 @@
#define SIGPWR 30
#define SIGSYS 31
-// Max signal number
-#define NSIG 64
+// All signal numbers need to be less than this constant.
+#define NSIG 65
+#define _NSIG NSIG
// SIGRTMIN is current set to the minimum usable from user mode programs. If
// the libc itself uses some of these signal numbers for private operations,
// then it has to be adjusted in future to reflect that.
#define SIGRTMIN 32
-
-#define SIGRTMAX NSIG
+// SIGRTMAX is the largest allowed value for the runtime signal.
+#define SIGRTMAX (NSIG - 1)
// The kernel sigset is stored as an array of long values. Each bit of this
// array corresponds to a signal, adjusted by 1. That is, bit 0 corresponds
// to signal number 1, bit 1 corresponds to signal number 2 and so on. The
// below macro denotes the size of that array (in number of long words and
// not bytes).
-#define __NSIGSET_WORDS (NSIG / (sizeof(unsigned long) * 8))
+#define __NSIGSET_WORDS ((NSIG - 1) / (sizeof(unsigned long) * 8))
#define SIG_BLOCK 0 // For blocking signals
#define SIG_UNBLOCK 1 // For unblocking signals
diff --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index c1f067951bd70..7a78b00d865de 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -79,10 +79,9 @@ 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. The function will fail if |signal| is greater than
-// NSIG or negative.
+// 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)
+ if (signal >= NSIG || signal <= 0)
return false;
size_t n = size_t(signal) - 1;
size_t word = n / BITS_PER_SIGWORD;
@@ -92,10 +91,9 @@ LIBC_INLINE constexpr bool add_signal(sigset_t &set, int signal) {
}
// Reset the bit corresponding to |signal| in |set|. Return true on success
-// and false on failure. The function will fail if |signal| is greater than
-// NSIG or negative.
+// 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)
+ if (signal >= NSIG || signal <= 0)
return false;
size_t n = size_t(signal) - 1;
size_t word = n / BITS_PER_SIGWORD;
diff --git a/libc/test/src/signal/sigaddset_test.cpp b/libc/test/src/signal/sigaddset_test.cpp
index 6456aa8f570d0..6189479c98208 100644
--- a/libc/test/src/signal/sigaddset_test.cpp
+++ b/libc/test/src/signal/sigaddset_test.cpp
@@ -22,8 +22,6 @@ TEST(LlvmLibcSignalTest, SigaddsetInvalid) {
sigset_t sigset;
EXPECT_THAT(LIBC_NAMESPACE::sigaddset(&sigset, -1), Fails(EINVAL));
- // This doesn't use NSIG because LIBC_NAMESPACE::sigaddset error checking is
- // against sizeof(sigset_t) not NSIG.
constexpr int bitsInSigsetT = 8 * sizeof(sigset_t);
EXPECT_THAT(LIBC_NAMESPACE::sigaddset(&sigset, bitsInSigsetT + 1),
diff --git a/libc/test/src/ucontext/ucontext_test.cpp b/libc/test/src/ucontext/ucontext_test.cpp
index 1983c2f1ec5b2..f7ef972cca206 100644
--- a/libc/test/src/ucontext/ucontext_test.cpp
+++ b/libc/test/src/ucontext/ucontext_test.cpp
@@ -21,8 +21,7 @@ namespace LIBC_NAMESPACE {
static bool is_signal_set(const sigset_t *set, int signum) {
// TODO: Replace this with sigismember once it is implemented.
- // NSIG is 64, sigset_t is an array of unsigned long.
- // Signum is 1-indexed.
+ // sigset_t is an array of unsigned long, signum is 1-indexed.
int word = (signum - 1) / (sizeof(unsigned long) * 8);
int bit = (signum - 1) % (sizeof(unsigned long) * 8);
return (set->__signals[word] & (1UL << bit)) != 0;
|
michaelrj-google
approved these changes
Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
_NSIGalias to the same value for compatibility.