diff options
-rw-r--r-- | include/linux/signal.h | 125 | ||||
-rw-r--r-- | kernel/signal.c | 119 |
2 files changed, 125 insertions, 119 deletions
diff --git a/include/linux/signal.h b/include/linux/signal.h index 14749056dd63..3fa0fab4a04b 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -243,6 +243,131 @@ extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, | |||
243 | 243 | ||
244 | extern struct kmem_cache *sighand_cachep; | 244 | extern struct kmem_cache *sighand_cachep; |
245 | 245 | ||
246 | /* | ||
247 | * In POSIX a signal is sent either to a specific thread (Linux task) | ||
248 | * or to the process as a whole (Linux thread group). How the signal | ||
249 | * is sent determines whether it's to one thread or the whole group, | ||
250 | * which determines which signal mask(s) are involved in blocking it | ||
251 | * from being delivered until later. When the signal is delivered, | ||
252 | * either it's caught or ignored by a user handler or it has a default | ||
253 | * effect that applies to the whole thread group (POSIX process). | ||
254 | * | ||
255 | * The possible effects an unblocked signal set to SIG_DFL can have are: | ||
256 | * ignore - Nothing Happens | ||
257 | * terminate - kill the process, i.e. all threads in the group, | ||
258 | * similar to exit_group. The group leader (only) reports | ||
259 | * WIFSIGNALED status to its parent. | ||
260 | * coredump - write a core dump file describing all threads using | ||
261 | * the same mm and then kill all those threads | ||
262 | * stop - stop all the threads in the group, i.e. TASK_STOPPED state | ||
263 | * | ||
264 | * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored. | ||
265 | * Other signals when not blocked and set to SIG_DFL behaves as follows. | ||
266 | * The job control signals also have other special effects. | ||
267 | * | ||
268 | * +--------------------+------------------+ | ||
269 | * | POSIX signal | default action | | ||
270 | * +--------------------+------------------+ | ||
271 | * | SIGHUP | terminate | | ||
272 | * | SIGINT | terminate | | ||
273 | * | SIGQUIT | coredump | | ||
274 | * | SIGILL | coredump | | ||
275 | * | SIGTRAP | coredump | | ||
276 | * | SIGABRT/SIGIOT | coredump | | ||
277 | * | SIGBUS | coredump | | ||
278 | * | SIGFPE | coredump | | ||
279 | * | SIGKILL | terminate(+) | | ||
280 | * | SIGUSR1 | terminate | | ||
281 | * | SIGSEGV | coredump | | ||
282 | * | SIGUSR2 | terminate | | ||
283 | * | SIGPIPE | terminate | | ||
284 | * | SIGALRM | terminate | | ||
285 | * | SIGTERM | terminate | | ||
286 | * | SIGCHLD | ignore | | ||
287 | * | SIGCONT | ignore(*) | | ||
288 | * | SIGSTOP | stop(*)(+) | | ||
289 | * | SIGTSTP | stop(*) | | ||
290 | * | SIGTTIN | stop(*) | | ||
291 | * | SIGTTOU | stop(*) | | ||
292 | * | SIGURG | ignore | | ||
293 | * | SIGXCPU | coredump | | ||
294 | * | SIGXFSZ | coredump | | ||
295 | * | SIGVTALRM | terminate | | ||
296 | * | SIGPROF | terminate | | ||
297 | * | SIGPOLL/SIGIO | terminate | | ||
298 | * | SIGSYS/SIGUNUSED | coredump | | ||
299 | * | SIGSTKFLT | terminate | | ||
300 | * | SIGWINCH | ignore | | ||
301 | * | SIGPWR | terminate | | ||
302 | * | SIGRTMIN-SIGRTMAX | terminate | | ||
303 | * +--------------------+------------------+ | ||
304 | * | non-POSIX signal | default action | | ||
305 | * +--------------------+------------------+ | ||
306 | * | SIGEMT | coredump | | ||
307 | * +--------------------+------------------+ | ||
308 | * | ||
309 | * (+) For SIGKILL and SIGSTOP the action is "always", not just "default". | ||
310 | * (*) Special job control effects: | ||
311 | * When SIGCONT is sent, it resumes the process (all threads in the group) | ||
312 | * from TASK_STOPPED state and also clears any pending/queued stop signals | ||
313 | * (any of those marked with "stop(*)"). This happens regardless of blocking, | ||
314 | * catching, or ignoring SIGCONT. When any stop signal is sent, it clears | ||
315 | * any pending/queued SIGCONT signals; this happens regardless of blocking, | ||
316 | * catching, or ignored the stop signal, though (except for SIGSTOP) the | ||
317 | * default action of stopping the process may happen later or never. | ||
318 | */ | ||
319 | |||
320 | #ifdef SIGEMT | ||
321 | #define SIGEMT_MASK rt_sigmask(SIGEMT) | ||
322 | #else | ||
323 | #define SIGEMT_MASK 0 | ||
324 | #endif | ||
325 | |||
326 | #if SIGRTMIN > BITS_PER_LONG | ||
327 | #define rt_sigmask(sig) (1ULL << ((sig)-1)) | ||
328 | #else | ||
329 | #define rt_sigmask(sig) sigmask(sig) | ||
330 | #endif | ||
331 | #define siginmask(sig, mask) (rt_sigmask(sig) & (mask)) | ||
332 | |||
333 | #define SIG_KERNEL_ONLY_MASK (\ | ||
334 | rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP)) | ||
335 | |||
336 | #define SIG_KERNEL_STOP_MASK (\ | ||
337 | rt_sigmask(SIGSTOP) | rt_sigmask(SIGTSTP) | \ | ||
338 | rt_sigmask(SIGTTIN) | rt_sigmask(SIGTTOU) ) | ||
339 | |||
340 | #define SIG_KERNEL_COREDUMP_MASK (\ | ||
341 | rt_sigmask(SIGQUIT) | rt_sigmask(SIGILL) | \ | ||
342 | rt_sigmask(SIGTRAP) | rt_sigmask(SIGABRT) | \ | ||
343 | rt_sigmask(SIGFPE) | rt_sigmask(SIGSEGV) | \ | ||
344 | rt_sigmask(SIGBUS) | rt_sigmask(SIGSYS) | \ | ||
345 | rt_sigmask(SIGXCPU) | rt_sigmask(SIGXFSZ) | \ | ||
346 | SIGEMT_MASK ) | ||
347 | |||
348 | #define SIG_KERNEL_IGNORE_MASK (\ | ||
349 | rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \ | ||
350 | rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) ) | ||
351 | |||
352 | #define sig_kernel_only(sig) \ | ||
353 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK)) | ||
354 | #define sig_kernel_coredump(sig) \ | ||
355 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_COREDUMP_MASK)) | ||
356 | #define sig_kernel_ignore(sig) \ | ||
357 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_IGNORE_MASK)) | ||
358 | #define sig_kernel_stop(sig) \ | ||
359 | (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_STOP_MASK)) | ||
360 | |||
361 | #define sig_needs_tasklist(sig) ((sig) == SIGCONT) | ||
362 | |||
363 | #define sig_user_defined(t, signr) \ | ||
364 | (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \ | ||
365 | ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN)) | ||
366 | |||
367 | #define sig_fatal(t, signr) \ | ||
368 | (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \ | ||
369 | (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL) | ||
370 | |||
246 | #endif /* __KERNEL__ */ | 371 | #endif /* __KERNEL__ */ |
247 | 372 | ||
248 | #endif /* _LINUX_SIGNAL_H */ | 373 | #endif /* _LINUX_SIGNAL_H */ |
diff --git a/kernel/signal.c b/kernel/signal.c index 1368e67c8482..4c8f49eadf7d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -38,125 +38,6 @@ | |||
38 | 38 | ||
39 | static struct kmem_cache *sigqueue_cachep; | 39 | static struct kmem_cache *sigqueue_cachep; |
40 | 40 | ||
41 | /* | ||
42 | * In POSIX a signal is sent either to a specific thread (Linux task) | ||
43 | * or to the process as a whole (Linux thread group). How the signal | ||
44 | * is sent determines whether it's to one thread or the whole group, | ||
45 | * which determines which signal mask(s) are involved in blocking it | ||
46 | * from being delivered until later. When the signal is delivered, | ||
47 | * either it's caught or ignored by a user handler or it has a default | ||
48 | * effect that applies to the whole thread group (POSIX process). | ||
49 | * | ||
50 | * The possible effects an unblocked signal set to SIG_DFL can have are: | ||
51 | * ignore - Nothing Happens | ||
52 | * terminate - kill the process, i.e. all threads in the group, | ||
53 | * similar to exit_group. The group leader (only) reports | ||
54 | * WIFSIGNALED status to its parent. | ||
55 | * coredump - write a core dump file describing all threads using | ||
56 | * the same mm and then kill all those threads | ||
57 | * stop - stop all the threads in the group, i.e. TASK_STOPPED state | ||
58 | * | ||
59 | * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored. | ||
60 | * Other signals when not blocked and set to SIG_DFL behaves as follows. | ||
61 | * The job control signals also have other special effects. | ||
62 | * | ||
63 | * +--------------------+------------------+ | ||
64 | * | POSIX signal | default action | | ||
65 | * +--------------------+------------------+ | ||
66 | * | SIGHUP | terminate | | ||
67 | * | SIGINT | terminate | | ||
68 | * | SIGQUIT | coredump | | ||
69 | * | SIGILL | coredump | | ||
70 | * | SIGTRAP | coredump | | ||
71 | * | SIGABRT/SIGIOT | coredump | | ||
72 | * | SIGBUS | coredump | | ||
73 | * | SIGFPE | coredump | | ||
74 | * | SIGKILL | terminate(+) | | ||
75 | * | SIGUSR1 | terminate | | ||
76 | * | SIGSEGV | coredump | | ||
77 | * | SIGUSR2 | terminate | | ||
78 | * | SIGPIPE | terminate | | ||
79 | * | SIGALRM | terminate | | ||
80 | * | SIGTERM | terminate | | ||
81 | * | SIGCHLD | ignore | | ||
82 | * | SIGCONT | ignore(*) | | ||
83 | * | SIGSTOP | stop(*)(+) | | ||
84 | * | SIGTSTP | stop(*) | | ||
85 | * | SIGTTIN | stop(*) | | ||
86 | * | SIGTTOU | stop(*) | | ||
87 | * | SIGURG | ignore | | ||
88 | * | SIGXCPU | coredump | | ||
89 | * | SIGXFSZ | coredump | | ||
90 | * | SIGVTALRM | terminate | | ||
91 | * | SIGPROF | terminate | | ||
92 | * | SIGPOLL/SIGIO | terminate | | ||
93 | * | SIGSYS/SIGUNUSED | coredump | | ||
94 | * | SIGSTKFLT | terminate | | ||
95 | * | SIGWINCH | ignore | | ||
96 | * | SIGPWR | terminate | | ||
97 | * | SIGRTMIN-SIGRTMAX | terminate | | ||
98 | * +--------------------+------------------+ | ||
99 | * | non-POSIX signal | default action | | ||
100 | * +--------------------+------------------+ | ||
101 | * | SIGEMT | coredump | | ||
102 | * +--------------------+------------------+ | ||
103 | * | ||
104 | * (+) For SIGKILL and SIGSTOP the action is "always", not just "default". | ||
105 | * (*) Special job control effects: | ||
106 | * When SIGCONT is sent, it resumes the process (all threads in the group) | ||
107 | * from TASK_STOPPED state and also clears any pending/queued stop signals | ||
108 | * (any of those marked with "stop(*)"). This happens regardless of blocking, | ||
109 | * catching, or ignoring SIGCONT. When any stop signal is sent, it clears | ||
110 | * any pending/queued SIGCONT signals; this happens regardless of blocking, | ||
111 | * catching, or ignored the stop signal, though (except for SIGSTOP) the | ||
112 | * default action of stopping the process may happen later or never. | ||
113 | */ | ||
114 | |||
115 | #ifdef SIGEMT | ||
116 | #define M_SIGEMT M(SIGEMT) | ||
117 | #else | ||
118 | #define M_SIGEMT 0 | ||
119 | #endif | ||
120 | |||
121 | #if SIGRTMIN > BITS_PER_LONG | ||
122 | #define M(sig) (1ULL << ((sig)-1)) | ||
123 | #else | ||
124 | #define M(sig) (1UL << ((sig)-1)) | ||
125 | #endif | ||
126 | #define T(sig, mask) (M(sig) & (mask)) | ||
127 | |||
128 | #define SIG_KERNEL_ONLY_MASK (\ | ||
129 | M(SIGKILL) | M(SIGSTOP) ) | ||
130 | |||
131 | #define SIG_KERNEL_STOP_MASK (\ | ||
132 | M(SIGSTOP) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) ) | ||
133 | |||
134 | #define SIG_KERNEL_COREDUMP_MASK (\ | ||
135 | M(SIGQUIT) | M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | \ | ||
136 | M(SIGFPE) | M(SIGSEGV) | M(SIGBUS) | M(SIGSYS) | \ | ||
137 | M(SIGXCPU) | M(SIGXFSZ) | M_SIGEMT ) | ||
138 | |||
139 | #define SIG_KERNEL_IGNORE_MASK (\ | ||
140 | M(SIGCONT) | M(SIGCHLD) | M(SIGWINCH) | M(SIGURG) ) | ||
141 | |||
142 | #define sig_kernel_only(sig) \ | ||
143 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_ONLY_MASK)) | ||
144 | #define sig_kernel_coredump(sig) \ | ||
145 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_COREDUMP_MASK)) | ||
146 | #define sig_kernel_ignore(sig) \ | ||
147 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_IGNORE_MASK)) | ||
148 | #define sig_kernel_stop(sig) \ | ||
149 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_STOP_MASK)) | ||
150 | |||
151 | #define sig_needs_tasklist(sig) ((sig) == SIGCONT) | ||
152 | |||
153 | #define sig_user_defined(t, signr) \ | ||
154 | (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \ | ||
155 | ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN)) | ||
156 | |||
157 | #define sig_fatal(t, signr) \ | ||
158 | (!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \ | ||
159 | (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL) | ||
160 | 41 | ||
161 | static int sig_ignored(struct task_struct *t, int sig) | 42 | static int sig_ignored(struct task_struct *t, int sig) |
162 | { | 43 | { |