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