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(sigset_t *);
254extern void __set_current_blocked(const sigset_t *);
255extern int show_unhandled_signals;
256extern int sigsuspend(sigset_t *);
257
258extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
259extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping);
260extern void exit_signals(struct task_struct *tsk);
261
262extern struct kmem_cache *sighand_cachep;
263
264int unhandled_signal(struct task_struct *tsk, int sig);
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
338
339
340#ifdef SIGEMT
341#define SIGEMT_MASK rt_sigmask(SIGEMT)
342#else
343#define SIGEMT_MASK 0
344#endif
345
346#if SIGRTMIN > BITS_PER_LONG
347#define rt_sigmask(sig) (1ULL << ((sig)-1))
348#else
349#define rt_sigmask(sig) sigmask(sig)
350#endif
351#define siginmask(sig, mask) (rt_sigmask(sig) & (mask))
352
353#define SIG_KERNEL_ONLY_MASK (\
354 rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP))
355
356#define SIG_KERNEL_STOP_MASK (\
357 rt_sigmask(SIGSTOP) | rt_sigmask(SIGTSTP) | \
358 rt_sigmask(SIGTTIN) | rt_sigmask(SIGTTOU) )
359
360#define SIG_KERNEL_COREDUMP_MASK (\
361 rt_sigmask(SIGQUIT) | rt_sigmask(SIGILL) | \
362 rt_sigmask(SIGTRAP) | rt_sigmask(SIGABRT) | \
363 rt_sigmask(SIGFPE) | rt_sigmask(SIGSEGV) | \
364 rt_sigmask(SIGBUS) | rt_sigmask(SIGSYS) | \
365 rt_sigmask(SIGXCPU) | rt_sigmask(SIGXFSZ) | \
366 SIGEMT_MASK )
367
368#define SIG_KERNEL_IGNORE_MASK (\
369 rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \
370 rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) )
371
372#define sig_kernel_only(sig) \
373 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK))
374#define sig_kernel_coredump(sig) \
375 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_COREDUMP_MASK))
376#define sig_kernel_ignore(sig) \
377 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_IGNORE_MASK))
378#define sig_kernel_stop(sig) \
379 (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_STOP_MASK))
380
381#define sig_user_defined(t, signr) \
382 (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \
383 ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
384
385#define sig_fatal(t, signr) \
386 (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
387 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
388
389void signals_init(void);
390
391#endif
392
393#endif
394