1#ifndef _LINUX_SIGNAL_H
2#define _LINUX_SIGNAL_H
3
4#include <linux/list.h>
5#include <linux/spinlock.h>
6#include <asm/signal.h>
7#include <asm/siginfo.h>
8
9#ifdef __KERNEL__
10
11#define MAX_SIGPENDING 1024
12
13
14
15
16
17struct sigqueue {
18 struct list_head list;
19 spinlock_t *lock;
20 int flags;
21 siginfo_t info;
22 struct user_struct *user;
23};
24
25
26#define SIGQUEUE_PREALLOC 1
27
28struct sigpending {
29 struct list_head list;
30 sigset_t signal;
31};
32
33
34
35
36
37#ifndef __HAVE_ARCH_SIG_BITOPS
38#include <linux/bitops.h>
39
40
41
42static inline void sigaddset(sigset_t *set, int _sig)
43{
44 unsigned long sig = _sig - 1;
45 if (_NSIG_WORDS == 1)
46 set->sig[0] |= 1UL << sig;
47 else
48 set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW);
49}
50
51static inline void sigdelset(sigset_t *set, int _sig)
52{
53 unsigned long sig = _sig - 1;
54 if (_NSIG_WORDS == 1)
55 set->sig[0] &= ~(1UL << sig);
56 else
57 set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW));
58}
59
60static inline int sigismember(sigset_t *set, int _sig)
61{
62 unsigned long sig = _sig - 1;
63 if (_NSIG_WORDS == 1)
64 return 1 & (set->sig[0] >> sig);
65 else
66 return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
67}
68
69static inline int sigfindinword(unsigned long word)
70{
71 return ffz(~word);
72}
73
74#endif
75
76#define sigmask(sig) (1UL << ((sig) - 1))
77
78#ifndef __HAVE_ARCH_SIG_SETOPS
79#include <linux/string.h>
80
81#define _SIG_SET_BINOP(name, op) \
82static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
83{ \
84 extern void _NSIG_WORDS_is_unsupported_size(void); \
85 unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \
86 \
87 switch (_NSIG_WORDS) { \
88 case 4: \
89 a3 = a->sig[3]; a2 = a->sig[2]; \
90 b3 = b->sig[3]; b2 = b->sig[2]; \
91 r->sig[3] = op(a3, b3); \
92 r->sig[2] = op(a2, b2); \
93 case 2: \
94 a1 = a->sig[1]; b1 = b->sig[1]; \
95 r->sig[1] = op(a1, b1); \
96 case 1: \
97 a0 = a->sig[0]; b0 = b->sig[0]; \
98 r->sig[0] = op(a0, b0); \
99 break; \
100 default: \
101 _NSIG_WORDS_is_unsupported_size(); \
102 } \
103}
104
105#define _sig_or(x,y) ((x) | (y))
106_SIG_SET_BINOP(sigorsets, _sig_or)
107
108#define _sig_and(x,y) ((x) & (y))
109_SIG_SET_BINOP(sigandsets, _sig_and)
110
111#define _sig_nand(x,y) ((x) & ~(y))
112_SIG_SET_BINOP(signandsets, _sig_nand)
113
114#undef _SIG_SET_BINOP
115#undef _sig_or
116#undef _sig_and
117#undef _sig_nand
118
119#define _SIG_SET_OP(name, op) \
120static inline void name(sigset_t *set) \
121{ \
122 extern void _NSIG_WORDS_is_unsupported_size(void); \
123 \
124 switch (_NSIG_WORDS) { \
125 case 4: set->sig[3] = op(set->sig[3]); \
126 set->sig[2] = op(set->sig[2]); \
127 case 2: set->sig[1] = op(set->sig[1]); \
128 case 1: set->sig[0] = op(set->sig[0]); \
129 break; \
130 default: \
131 _NSIG_WORDS_is_unsupported_size(); \
132 } \
133}
134
135#define _sig_not(x) (~(x))
136_SIG_SET_OP(signotset, _sig_not)
137
138#undef _SIG_SET_OP
139#undef _sig_not
140
141static inline void sigemptyset(sigset_t *set)
142{
143 switch (_NSIG_WORDS) {
144 default:
145 memset(set, 0, sizeof(sigset_t));
146 break;
147 case 2: set->sig[1] = 0;
148 case 1: set->sig[0] = 0;
149 break;
150 }
151}
152
153static inline void sigfillset(sigset_t *set)
154{
155 switch (_NSIG_WORDS) {
156 default:
157 memset(set, -1, sizeof(sigset_t));
158 break;
159 case 2: set->sig[1] = -1;
160 case 1: set->sig[0] = -1;
161 break;
162 }
163}
164
165
166
167static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
168{
169 set->sig[0] |= mask;
170}
171
172static inline void sigdelsetmask(sigset_t *set, unsigned long mask)
173{
174 set->sig[0] &= ~mask;
175}
176
177static inline int sigtestsetmask(sigset_t *set, unsigned long mask)
178{
179 return (set->sig[0] & mask) != 0;
180}
181
182static inline void siginitset(sigset_t *set, unsigned long mask)
183{
184 set->sig[0] = mask;
185 switch (_NSIG_WORDS) {
186 default:
187 memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1));
188 break;
189 case 2: set->sig[1] = 0;
190 case 1: ;
191 }
192}
193
194static inline void siginitsetinv(sigset_t *set, unsigned long mask)
195{
196 set->sig[0] = ~mask;
197 switch (_NSIG_WORDS) {
198 default:
199 memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1));
200 break;
201 case 2: set->sig[1] = -1;
202 case 1: ;
203 }
204}
205
206#endif
207
208static inline void init_sigpending(struct sigpending *sig)
209{
210 sigemptyset(&sig->signal);
211 INIT_LIST_HEAD(&sig->list);
212}
213
214extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
215extern long do_sigpending(void __user *, unsigned long);
216extern int sigprocmask(int, sigset_t *, sigset_t *);
217
218#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
219struct pt_regs;
220extern int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs, void *cookie);
221#endif
222
223#endif
224
225#endif
226