1/* __sigset_t manipulators. Linux version.
2 Copyright (C) 1991-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#ifndef _SIGSETOPS_H
20#define _SIGSETOPS_H 1
21
22#include <signal.h>
23#include <limits.h>
24#include <libc-pointer-arith.h>
25
26/* Return a mask that includes the bit for SIG only. */
27#define __sigmask(sig) \
28 (1UL << (((sig) - 1) % ULONG_WIDTH))
29
30/* Return the word index for SIG. */
31static inline unsigned long int
32__sigword (int sig)
33{
34 return (sig - 1) / ULONG_WIDTH;
35}
36
37/* Linux sig* functions only handle up to __NSIG_WORDS words instead of
38 full _SIGSET_NWORDS sigset size. The signal numbers are 1-based, and
39 bit 0 of a signal mask is for signal 1. */
40#define __NSIG_WORDS (ALIGN_UP ((_NSIG - 1), ULONG_WIDTH) / ULONG_WIDTH)
41_Static_assert (__NSIG_WORDS <= _SIGSET_NWORDS,
42 "__NSIG_WORDS > _SIGSET_WORDS");
43
44/* This macro is used on syscall that takes a sigset_t to specify the expected
45 size in bytes. As for glibc, kernel sigset is implemented as an array of
46 unsigned long. */
47#define __NSIG_BYTES (__NSIG_WORDS * (ULONG_WIDTH / UCHAR_WIDTH))
48
49static inline void
50__sigemptyset (sigset_t *set)
51{
52 int cnt = __NSIG_WORDS;
53 while (--cnt >= 0)
54 set->__val[cnt] = 0;
55}
56
57static inline void
58__sigfillset (sigset_t *set)
59{
60 int cnt = __NSIG_WORDS;
61 while (--cnt >= 0)
62 set->__val[cnt] = ~0UL;
63}
64
65static inline int
66__sigisemptyset (const sigset_t *set)
67{
68 int cnt = __NSIG_WORDS;
69 int ret = set->__val[--cnt];
70 while (ret == 0 && --cnt >= 0)
71 ret = set->__val[cnt];
72 return ret == 0;
73}
74
75static inline void
76__sigandset (sigset_t *dest, const sigset_t *left, const sigset_t *right)
77{
78 int cnt = __NSIG_WORDS;
79 while (--cnt >= 0)
80 dest->__val[cnt] = left->__val[cnt] & right->__val[cnt];
81}
82
83static inline void
84__sigorset (sigset_t *dest, const sigset_t *left, const sigset_t *right)
85{
86 int cnt = __NSIG_WORDS;
87 while (--cnt >= 0)
88 dest->__val[cnt] = left->__val[cnt] | right->__val[cnt];
89}
90
91static inline int
92__sigismember (const sigset_t *set, int sig)
93{
94 unsigned long int mask = __sigmask (sig);
95 unsigned long int word = __sigword (sig);
96 return set->__val[word] & mask ? 1 : 0;
97}
98
99static inline void
100__sigaddset (sigset_t *set, int sig)
101{
102 unsigned long int mask = __sigmask (sig);
103 unsigned long int word = __sigword (sig);
104 set->__val[word] |= mask;
105}
106
107static inline void
108__sigdelset (sigset_t *set, int sig)
109{
110 unsigned long int mask = __sigmask (sig);
111 unsigned long int word = __sigword (sig);
112 set->__val[word] &= ~mask;
113}
114
115#endif /* bits/sigsetops.h */
116

source code of glibc/sysdeps/unix/sysv/linux/sigsetops.h