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