1 | /* __sigset_t manipulators. Linux version. |
2 | Copyright (C) 1991-2020 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. */ |
31 | static 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 | |
49 | static inline void |
50 | __sigemptyset (sigset_t *set) |
51 | { |
52 | int cnt = __NSIG_WORDS; |
53 | while (--cnt >= 0) |
54 | set->__val[cnt] = 0; |
55 | } |
56 | |
57 | static inline void |
58 | __sigfillset (sigset_t *set) |
59 | { |
60 | int cnt = __NSIG_WORDS; |
61 | while (--cnt >= 0) |
62 | set->__val[cnt] = ~0UL; |
63 | } |
64 | |
65 | static 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 | |
75 | static 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 | |
83 | static 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 | |
91 | static 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 | |
99 | static 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 | |
107 | static 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 | |