1#ifndef _LINUX_SIGNAL_H
2#define _LINUX_SIGNAL_H
3
4#include <asm/signal.h>
5#include <asm/siginfo.h>
6
7#ifdef __KERNEL__
8#include <linux/list.h>
9
10
11
12
13
14struct sigqueue {
15 struct list_head list;
16 int flags;
17 siginfo_t info;
18 struct user_struct *user;
19};
20
21
22#define SIGQUEUE_PREALLOC 1
23
24struct sigpending {
25 struct list_head list;
26 sigset_t signal;
27};
28
29
30
31
32
33#ifndef __HAVE_ARCH_SIG_BITOPS
34#include <linux/bitops.h>
35
36
37
38static inline void sigaddset(sigset_t *set, int _sig)
39{
40 unsigned long sig = _sig - 1;
41 if (_NSIG_WORDS == 1)
42 set->sig[0] |= 1UL << sig;
43 else
44 set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW);
45}
46
47static inline void sigdelset(sigset_t *set, int _sig)
48{
49 unsigned long sig = _sig - 1;
50 if (_NSIG_WORDS == 1)
51 set->sig[0] &= ~(1UL << sig);
52 else
53 set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW));
54}
55
56static inline int sigismember(sigset_t *set, int _sig)
57{
58 unsigned long sig = _sig - 1;
59 if (_NSIG_WORDS == 1)
60 return 1 & (set->sig[0] >> sig);
61 else
62 return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
63}
64
65static inline int sigfindinword(unsigned long word)
66{
67 return ffz(~word);
68}
69
70#endif
71
72static inline int sigisemptyset(sigset_t *set)
73{
74 extern void _NSIG_WORDS_is_unsupported_size(void);
75 switch (_NSIG_WORDS) {
76 case 4:
77 return (set->sig[3] | set->sig[2] |
78 set->sig[1] | set->sig[0]) == 0;
79 case 2:
80 return (set->sig[1] | set->sig[0]) == 0;
81 case 1:
82 return set->sig[0] == 0;
83 default:
84 _NSIG_WORDS_is_unsupported_size();
85 return 0;
86 }
87}
88
89#define sigmask(sig) (1UL << ((sig) - 1))
90
91#ifndef __HAVE_ARCH_SIG_SETOPS
92#include <linux/string.h>
93
94#define _SIG_SET_BINOP(name, op) \
95static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
96{ \
97 extern void _NSIG_WORDS_is_unsupported_size(void); \
98 unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \
99 \
100 switch (_NSIG_WORDS) { \
101 case 4: \
102 a3 = a->sig[3]; a2 = a->sig[2]; \
103 b3 = b->sig[3]; b2 = b->sig[2]; \
104 r->sig[3] = op(a3, b3); \
105 r->sig[2] = op(a2, b2); \
106 case 2: \
107 a1 = a->sig[1]; b1 = b->sig[1]; \
108 r->sig[1] = op(a1, b1); \
109 case 1: \
110 a0 = a->sig[0]; b0 = b->sig[0]; \
111 r->sig[0] = op(a0, b0); \
112 break; \
113 default: \
114 _NSIG_WORDS_is_unsupported_size(); \
115 } \
116}
117
118#define _sig_or(x,y) ((x) | (y))
119_SIG_SET_BINOP(sigorsets, _sig_or)
120
121#define _sig_and(x,y) ((x) & (y))
122_SIG_SET_BINOP(sigandsets, _sig_and)
123
124#define _sig_nand(x,y) ((x) & ~(y))
125_SIG_SET_BINOP(signandsets, _sig_nand)
126
127#undef _SIG_SET_BINOP
128#undef _sig_or
129#undef _sig_and
130#undef _sig_nand
131
132#define _SIG_SET_OP(name, op) \
133static inline void name(sigset_t *set) \
134{ \
135 extern void _NSIG_WORDS_is_unsupported_size(void); \
136 \
137 switch (_NSIG_WORDS) { \
138 case 4: set->sig[3] = op(set->sig[3]); \
139 set->sig[2] = op(set->sig[2]); \
140 case 2: set->sig[1] = op(set->sig[1]); \
141 case 1: set->sig[0] = op(set->sig[0]); \
142 break; \
143 default: \
144 _NSIG_WORDS_is_unsupported_size(); \
145 } \
146}
147
148#define _sig_not(x) (~(x))
149_SIG_SET_OP(signotset, _sig_not)
150
151#undef _SIG_SET_OP
152#undef _sig_not
153
154static inline void sigemptyset(sigset_t *set)
155{
156 switch (_NSIG_WORDS) {
157 default:
158 memset(set, 0, sizeof(sigset_t));
159 break;
160 case 2: set->sig[1] = 0;
161 case 1: set->sig[0] = 0;
162 break;
163 }
164}
165
166static inline void sigfillset(sigset_t *set)
167{
168 switch (_NSIG_WORDS) {
169 default:
170 memset(set, -1, sizeof(sigset_t));
171 break;
172 case 2: set->sig[1] = -1;
173 case 1: set->sig[0] = -1;
174 break;
175 }
176}
177
178
179
180static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
181{
182 set->sig[0] |= mask;
183}
184
185static inline void sigdelsetmask(sigset_t *set, unsigned long mask)
186{
187 set->sig[0] &= ~mask;
188}
189
190static inline int sigtestsetmask(sigset_t *set, unsigned long mask)
191{
192 return (set->sig[0] & mask) != 0;
193}
194
195static inline void siginitset(sigset_t *set, unsigned long mask)
196{
197 set->sig[0] = mask;
198 switch (_NSIG_WORDS) {
199 default:
200 memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1));
201 break;
202 case 2: set->sig[1] = 0;
203 case 1: ;
204 }
205}
206
207static inline void siginitsetinv(sigset_t *set, unsigned long mask)
208{
209 set->sig[0] = ~mask;
210 switch (_NSIG_WORDS) {
211 default:
212 memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1));
213 break;
214 case 2: set->sig[1] = -1;
215 case 1: ;
216 }
217}
218
219#endif
220
221static inline void init_sigpending(struct sigpending *sig)
222{
223 sigemptyset(&sig->signal);
224 INIT_LIST_HEAD(&sig->list);
225}
226
227extern void flush_sigqueue(struct sigpending *queue);
228
229
230static inline int valid_signal(unsigned long sig)
231{
232 return sig <= _NSIG ? 1 : 0;
233}
234
235extern int next_signal(struct sigpending *pending, sigset_t *mask);
236extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
237extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
238extern long do_sigpending(void __user *, unsigned long);
239extern int sigprocmask(int, sigset_t *, sigset_t *);
240extern int show_unhandled_signals;
241
242struct pt_regs;
243extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
244extern void exit_signals(struct task_struct *tsk);
245
246extern struct kmem_cache *sighand_cachep;
247
248int unhandled_signal(struct task_struct *tsk, int sig);
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324#ifdef SIGEMT
325#define SIGEMT_MASK rt_sigmask(SIGEMT)
326#else
327#define SIGEMT_MASK 0
328#endif
329
330#if SIGRTMIN > BITS_PER_LONG
331#define rt_sigmask(sig) (1ULL << ((sig)-1))
332#else
333#define rt_sigmask(sig) sigmask(sig)
334#endif
335#define siginmask(sig, mask) (rt_sigmask(sig) & (mask))
336
337#define SIG_KERNEL_ONLY_MASK (\
338 rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP))
339
340#define SIG_KERNEL_STOP_MASK (\
341 rt_sigmask(SIGSTOP) | rt_sigmask(SIGTSTP) | \
342 rt_sigmask(SIGTTIN) | rt_sigmask(SIGTTOU) )
343
344#define SIG_KERNEL_COREDUMP_MASK (\
345 rt_sigmask(SIGQUIT) | rt_sigmask(SIGILL) | \
346 rt_sigmask(SIGTRAP) | rt_sigmask(SIGABRT) | \
347 rt_sigmask(SIGFPE) | rt_sigmask(SIGSEGV) | \
348 rt_sigmask(SIGBUS) | rt_sigmask(SIGSYS) | \
349 rt_sigmask(SIGXCPU) | rt_sigmask(SIGXFSZ) | \
350 SIGEMT_MASK )
351
352#define SIG_KERNEL_IGNORE_MASK (\
353 rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \
354 rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) )
355
356#define sig_kernel_only(sig) \
357 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK))
358#define sig_kernel_coredump(sig) \
359 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_COREDUMP_MASK))
360#define sig_kernel_ignore(sig) \
361 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_IGNORE_MASK))
362#define sig_kernel_stop(sig) \
363 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_STOP_MASK))
364
365#define sig_user_defined(t, signr) \
366 (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \
367 ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
368
369#define sig_fatal(t, signr) \
370 (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
371 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
372
373void signals_init(void);
374
375#endif
376
377#endif
378