1
2#ifndef _LINUX_SIGNAL_H
3#define _LINUX_SIGNAL_H
4
5#include <linux/bug.h>
6#include <linux/signal_types.h>
7#include <linux/string.h>
8
9struct task_struct;
10
11
12extern int print_fatal_signals;
13
14static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
15{
16 if (from->si_code < 0)
17 memcpy(to, from, sizeof(*to));
18 else
19
20 memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
21}
22
23int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from);
24
25enum siginfo_layout {
26 SIL_KILL,
27 SIL_TIMER,
28 SIL_POLL,
29 SIL_FAULT,
30 SIL_CHLD,
31 SIL_RT,
32#ifdef __ARCH_SIGSYS
33 SIL_SYS,
34#endif
35};
36
37enum siginfo_layout siginfo_layout(int sig, int si_code);
38
39
40
41
42
43#ifndef __HAVE_ARCH_SIG_BITOPS
44#include <linux/bitops.h>
45
46
47
48static inline void sigaddset(sigset_t *set, int _sig)
49{
50 unsigned long sig = _sig - 1;
51 if (_NSIG_WORDS == 1)
52 set->sig[0] |= 1UL << sig;
53 else
54 set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW);
55}
56
57static inline void sigdelset(sigset_t *set, int _sig)
58{
59 unsigned long sig = _sig - 1;
60 if (_NSIG_WORDS == 1)
61 set->sig[0] &= ~(1UL << sig);
62 else
63 set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW));
64}
65
66static inline int sigismember(sigset_t *set, int _sig)
67{
68 unsigned long sig = _sig - 1;
69 if (_NSIG_WORDS == 1)
70 return 1 & (set->sig[0] >> sig);
71 else
72 return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
73}
74
75#endif
76
77static inline int sigisemptyset(sigset_t *set)
78{
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 BUILD_BUG();
89 return 0;
90 }
91}
92
93static inline int sigequalsets(const sigset_t *set1, const sigset_t *set2)
94{
95 switch (_NSIG_WORDS) {
96 case 4:
97 return (set1->sig[3] == set2->sig[3]) &&
98 (set1->sig[2] == set2->sig[2]) &&
99 (set1->sig[1] == set2->sig[1]) &&
100 (set1->sig[0] == set2->sig[0]);
101 case 2:
102 return (set1->sig[1] == set2->sig[1]) &&
103 (set1->sig[0] == set2->sig[0]);
104 case 1:
105 return set1->sig[0] == set2->sig[0];
106 }
107 return 0;
108}
109
110#define sigmask(sig) (1UL << ((sig) - 1))
111
112#ifndef __HAVE_ARCH_SIG_SETOPS
113#include <linux/string.h>
114
115#define _SIG_SET_BINOP(name, op) \
116static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
117{ \
118 unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \
119 \
120 switch (_NSIG_WORDS) { \
121 case 4: \
122 a3 = a->sig[3]; a2 = a->sig[2]; \
123 b3 = b->sig[3]; b2 = b->sig[2]; \
124 r->sig[3] = op(a3, b3); \
125 r->sig[2] = op(a2, b2); \
126 case 2: \
127 a1 = a->sig[1]; b1 = b->sig[1]; \
128 r->sig[1] = op(a1, b1); \
129 case 1: \
130 a0 = a->sig[0]; b0 = b->sig[0]; \
131 r->sig[0] = op(a0, b0); \
132 break; \
133 default: \
134 BUILD_BUG(); \
135 } \
136}
137
138#define _sig_or(x,y) ((x) | (y))
139_SIG_SET_BINOP(sigorsets, _sig_or)
140
141#define _sig_and(x,y) ((x) & (y))
142_SIG_SET_BINOP(sigandsets, _sig_and)
143
144#define _sig_andn(x,y) ((x) & ~(y))
145_SIG_SET_BINOP(sigandnsets, _sig_andn)
146
147#undef _SIG_SET_BINOP
148#undef _sig_or
149#undef _sig_and
150#undef _sig_andn
151
152#define _SIG_SET_OP(name, op) \
153static inline void name(sigset_t *set) \
154{ \
155 switch (_NSIG_WORDS) { \
156 case 4: set->sig[3] = op(set->sig[3]); \
157 set->sig[2] = op(set->sig[2]); \
158 case 2: set->sig[1] = op(set->sig[1]); \
159 case 1: set->sig[0] = op(set->sig[0]); \
160 break; \
161 default: \
162 BUILD_BUG(); \
163 } \
164}
165
166#define _sig_not(x) (~(x))
167_SIG_SET_OP(signotset, _sig_not)
168
169#undef _SIG_SET_OP
170#undef _sig_not
171
172static inline void sigemptyset(sigset_t *set)
173{
174 switch (_NSIG_WORDS) {
175 default:
176 memset(set, 0, sizeof(sigset_t));
177 break;
178 case 2: set->sig[1] = 0;
179 case 1: set->sig[0] = 0;
180 break;
181 }
182}
183
184static inline void sigfillset(sigset_t *set)
185{
186 switch (_NSIG_WORDS) {
187 default:
188 memset(set, -1, sizeof(sigset_t));
189 break;
190 case 2: set->sig[1] = -1;
191 case 1: set->sig[0] = -1;
192 break;
193 }
194}
195
196
197
198static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
199{
200 set->sig[0] |= mask;
201}
202
203static inline void sigdelsetmask(sigset_t *set, unsigned long mask)
204{
205 set->sig[0] &= ~mask;
206}
207
208static inline int sigtestsetmask(sigset_t *set, unsigned long mask)
209{
210 return (set->sig[0] & mask) != 0;
211}
212
213static inline void siginitset(sigset_t *set, unsigned long mask)
214{
215 set->sig[0] = mask;
216 switch (_NSIG_WORDS) {
217 default:
218 memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1));
219 break;
220 case 2: set->sig[1] = 0;
221 case 1: ;
222 }
223}
224
225static inline void siginitsetinv(sigset_t *set, unsigned long mask)
226{
227 set->sig[0] = ~mask;
228 switch (_NSIG_WORDS) {
229 default:
230 memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1));
231 break;
232 case 2: set->sig[1] = -1;
233 case 1: ;
234 }
235}
236
237#endif
238
239static inline void init_sigpending(struct sigpending *sig)
240{
241 sigemptyset(&sig->signal);
242 INIT_LIST_HEAD(&sig->list);
243}
244
245extern void flush_sigqueue(struct sigpending *queue);
246
247
248static inline int valid_signal(unsigned long sig)
249{
250 return sig <= _NSIG ? 1 : 0;
251}
252
253struct timespec;
254struct pt_regs;
255
256extern int next_signal(struct sigpending *pending, sigset_t *mask);
257extern int do_send_sig_info(int sig, struct siginfo *info,
258 struct task_struct *p, bool group);
259extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
260extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
261extern int sigprocmask(int, sigset_t *, sigset_t *);
262extern void set_current_blocked(sigset_t *);
263extern void __set_current_blocked(const sigset_t *);
264extern int show_unhandled_signals;
265
266extern int get_signal(struct ksignal *ksig);
267extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
268extern void exit_signals(struct task_struct *tsk);
269extern void kernel_sigaction(int, __sighandler_t);
270
271static inline void allow_signal(int sig)
272{
273
274
275
276
277
278 kernel_sigaction(sig, (__force __sighandler_t)2);
279}
280
281static inline void disallow_signal(int sig)
282{
283 kernel_sigaction(sig, SIG_IGN);
284}
285
286extern struct kmem_cache *sighand_cachep;
287
288int unhandled_signal(struct task_struct *tsk, int sig);
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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364#ifdef SIGEMT
365#define SIGEMT_MASK rt_sigmask(SIGEMT)
366#else
367#define SIGEMT_MASK 0
368#endif
369
370#if SIGRTMIN > BITS_PER_LONG
371#define rt_sigmask(sig) (1ULL << ((sig)-1))
372#else
373#define rt_sigmask(sig) sigmask(sig)
374#endif
375
376#define siginmask(sig, mask) \
377 ((sig) < SIGRTMIN && (rt_sigmask(sig) & (mask)))
378
379#define SIG_KERNEL_ONLY_MASK (\
380 rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP))
381
382#define SIG_KERNEL_STOP_MASK (\
383 rt_sigmask(SIGSTOP) | rt_sigmask(SIGTSTP) | \
384 rt_sigmask(SIGTTIN) | rt_sigmask(SIGTTOU) )
385
386#define SIG_KERNEL_COREDUMP_MASK (\
387 rt_sigmask(SIGQUIT) | rt_sigmask(SIGILL) | \
388 rt_sigmask(SIGTRAP) | rt_sigmask(SIGABRT) | \
389 rt_sigmask(SIGFPE) | rt_sigmask(SIGSEGV) | \
390 rt_sigmask(SIGBUS) | rt_sigmask(SIGSYS) | \
391 rt_sigmask(SIGXCPU) | rt_sigmask(SIGXFSZ) | \
392 SIGEMT_MASK )
393
394#define SIG_KERNEL_IGNORE_MASK (\
395 rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \
396 rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) )
397
398#define SIG_SPECIFIC_SICODES_MASK (\
399 rt_sigmask(SIGILL) | rt_sigmask(SIGFPE) | \
400 rt_sigmask(SIGSEGV) | rt_sigmask(SIGBUS) | \
401 rt_sigmask(SIGTRAP) | rt_sigmask(SIGCHLD) | \
402 rt_sigmask(SIGPOLL) | rt_sigmask(SIGSYS) | \
403 SIGEMT_MASK )
404
405#define sig_kernel_only(sig) siginmask(sig, SIG_KERNEL_ONLY_MASK)
406#define sig_kernel_coredump(sig) siginmask(sig, SIG_KERNEL_COREDUMP_MASK)
407#define sig_kernel_ignore(sig) siginmask(sig, SIG_KERNEL_IGNORE_MASK)
408#define sig_kernel_stop(sig) siginmask(sig, SIG_KERNEL_STOP_MASK)
409#define sig_specific_sicodes(sig) siginmask(sig, SIG_SPECIFIC_SICODES_MASK)
410
411#define sig_fatal(t, signr) \
412 (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
413 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
414
415void signals_init(void);
416
417int restore_altstack(const stack_t __user *);
418int __save_altstack(stack_t __user *, unsigned long);
419
420#define save_altstack_ex(uss, sp) do { \
421 stack_t __user *__uss = uss; \
422 struct task_struct *t = current; \
423 put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \
424 put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \
425 put_user_ex(t->sas_ss_size, &__uss->ss_size); \
426 if (t->sas_ss_flags & SS_AUTODISARM) \
427 sas_ss_reset(t); \
428} while (0);
429
430#ifdef CONFIG_PROC_FS
431struct seq_file;
432extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);
433#endif
434
435#endif
436