diff options
Diffstat (limited to 'kernel/signal.c')
| -rw-r--r-- | kernel/signal.c | 147 |
1 files changed, 11 insertions, 136 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 3670225ecbc0..2ac3a668d9dd 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/smp_lock.h> | ||
| 16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 17 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
| 18 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| @@ -39,125 +38,6 @@ | |||
| 39 | 38 | ||
| 40 | static struct kmem_cache *sigqueue_cachep; | 39 | static struct kmem_cache *sigqueue_cachep; |
| 41 | 40 | ||
| 42 | /* | ||
| 43 | * In POSIX a signal is sent either to a specific thread (Linux task) | ||
| 44 | * or to the process as a whole (Linux thread group). How the signal | ||
| 45 | * is sent determines whether it's to one thread or the whole group, | ||
| 46 | * which determines which signal mask(s) are involved in blocking it | ||
| 47 | * from being delivered until later. When the signal is delivered, | ||
| 48 | * either it's caught or ignored by a user handler or it has a default | ||
| 49 | * effect that applies to the whole thread group (POSIX process). | ||
| 50 | * | ||
| 51 | * The possible effects an unblocked signal set to SIG_DFL can have are: | ||
| 52 | * ignore - Nothing Happens | ||
| 53 | * terminate - kill the process, i.e. all threads in the group, | ||
| 54 | * similar to exit_group. The group leader (only) reports | ||
| 55 | * WIFSIGNALED status to its parent. | ||
| 56 | * coredump - write a core dump file describing all threads using | ||
| 57 | * the same mm and then kill all those threads | ||
| 58 | * stop - stop all the threads in the group, i.e. TASK_STOPPED state | ||
| 59 | * | ||
| 60 | * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored. | ||
| 61 | * Other signals when not blocked and set to SIG_DFL behaves as follows. | ||
| 62 | * The job control signals also have other special effects. | ||
| 63 | * | ||
| 64 | * +--------------------+------------------+ | ||
| 65 | * | POSIX signal | default action | | ||
| 66 | * +--------------------+------------------+ | ||
| 67 | * | SIGHUP | terminate | | ||
| 68 | * | SIGINT | terminate | | ||
| 69 | * | SIGQUIT | coredump | | ||
| 70 | * | SIGILL | coredump | | ||
| 71 | * | SIGTRAP | coredump | | ||
| 72 | * | SIGABRT/SIGIOT | coredump | | ||
| 73 | * | SIGBUS | coredump | | ||
| 74 | * | SIGFPE | coredump | | ||
| 75 | * | SIGKILL | terminate(+) | | ||
| 76 | * | SIGUSR1 | terminate | | ||
| 77 | * | SIGSEGV | coredump | | ||
| 78 | * | SIGUSR2 | terminate | | ||
| 79 | * | SIGPIPE | terminate | | ||
| 80 | * | SIGALRM | terminate | | ||
| 81 | * | SIGTERM | terminate | | ||
| 82 | * | SIGCHLD | ignore | | ||
| 83 | * | SIGCONT | ignore(*) | | ||
| 84 | * | SIGSTOP | stop(*)(+) | | ||
| 85 | * | SIGTSTP | stop(*) | | ||
| 86 | * | SIGTTIN | stop(*) | | ||
| 87 | * | SIGTTOU | stop(*) | | ||
| 88 | * | SIGURG | ignore | | ||
| 89 | * | SIGXCPU | coredump | | ||
| 90 | * | SIGXFSZ | coredump | | ||
| 91 | * | SIGVTALRM | terminate | | ||
| 92 | * | SIGPROF | terminate | | ||
| 93 | * | SIGPOLL/SIGIO | terminate | | ||
| 94 | * | SIGSYS/SIGUNUSED | coredump | | ||
| 95 | * | SIGSTKFLT | terminate | | ||
| 96 | * | SIGWINCH | ignore | | ||
| 97 | * | SIGPWR | terminate | | ||
| 98 | * | SIGRTMIN-SIGRTMAX | terminate | | ||
| 99 | * +--------------------+------------------+ | ||
| 100 | * | non-POSIX signal | default action | | ||
| 101 | * +--------------------+------------------+ | ||
| 102 | * | SIGEMT | coredump | | ||
| 103 | * +--------------------+------------------+ | ||
| 104 | * | ||
| 105 | * (+) For SIGKILL and SIGSTOP the action is "always", not just "default". | ||
| 106 | * (*) Special job control effects: | ||
| 107 | * When SIGCONT is sent, it resumes the process (all threads in the group) | ||
| 108 | * from TASK_STOPPED state and also clears any pending/queued stop signals | ||
| 109 | * (any of those marked with "stop(*)"). This happens regardless of blocking, | ||
| 110 | * catching, or ignoring SIGCONT. When any stop signal is sent, it clears | ||
| 111 | * any pending/queued SIGCONT signals; this happens regardless of blocking, | ||
| 112 | * catching, or ignored the stop signal, though (except for SIGSTOP) the | ||
| 113 | * default action of stopping the process may happen later or never. | ||
| 114 | */ | ||
| 115 | |||
| 116 | #ifdef SIGEMT | ||
| 117 | #define M_SIGEMT M(SIGEMT) | ||
| 118 | #else | ||
| 119 | #define M_SIGEMT 0 | ||
| 120 | #endif | ||
| 121 | |||
| 122 | #if SIGRTMIN > BITS_PER_LONG | ||
| 123 | #define M(sig) (1ULL << ((sig)-1)) | ||
| 124 | #else | ||
| 125 | #define M(sig) (1UL << ((sig)-1)) | ||
| 126 | #endif | ||
| 127 | #define T(sig, mask) (M(sig) & (mask)) | ||
| 128 | |||
| 129 | #define SIG_KERNEL_ONLY_MASK (\ | ||
| 130 | M(SIGKILL) | M(SIGSTOP) ) | ||
| 131 | |||
| 132 | #define SIG_KERNEL_STOP_MASK (\ | ||
| 133 | M(SIGSTOP) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) ) | ||
| 134 | |||
| 135 | #define SIG_KERNEL_COREDUMP_MASK (\ | ||
| 136 | M(SIGQUIT) | M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | \ | ||
| 137 | M(SIGFPE) | M(SIGSEGV) | M(SIGBUS) | M(SIGSYS) | \ | ||
| 138 | M(SIGXCPU) | M(SIGXFSZ) | M_SIGEMT ) | ||
| 139 | |||
| 140 | #define SIG_KERNEL_IGNORE_MASK (\ | ||
| 141 | M(SIGCONT) | M(SIGCHLD) | M(SIGWINCH) | M(SIGURG) ) | ||
| 142 | |||
| 143 | #define sig_kernel_only(sig) \ | ||
| 144 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_ONLY_MASK)) | ||
| 145 | #define sig_kernel_coredump(sig) \ | ||
| 146 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_COREDUMP_MASK)) | ||
| 147 | #define sig_kernel_ignore(sig) \ | ||
| 148 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_IGNORE_MASK)) | ||
| 149 | #define sig_kernel_stop(sig) \ | ||
| 150 | (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_STOP_MASK)) | ||
| 151 | |||
| 152 | #define sig_needs_tasklist(sig) ((sig) == SIGCONT) | ||
| 153 | |||
| 154 | #define sig_user_defined(t, signr) \ | ||
| 155 | (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \ | ||
| 156 | ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN)) | ||
| 157 | |||
| 158 | #define sig_fatal(t, signr) \ | ||
| 159 | (!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \ | ||
| 160 | (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL) | ||
| 161 | 41 | ||
| 162 | static int sig_ignored(struct task_struct *t, int sig) | 42 | static int sig_ignored(struct task_struct *t, int sig) |
| 163 | { | 43 | { |
| @@ -329,6 +209,16 @@ void flush_signals(struct task_struct *t) | |||
| 329 | spin_unlock_irqrestore(&t->sighand->siglock, flags); | 209 | spin_unlock_irqrestore(&t->sighand->siglock, flags); |
| 330 | } | 210 | } |
| 331 | 211 | ||
| 212 | void ignore_signals(struct task_struct *t) | ||
| 213 | { | ||
| 214 | int i; | ||
| 215 | |||
| 216 | for (i = 0; i < _NSIG; ++i) | ||
| 217 | t->sighand->action[i].sa.sa_handler = SIG_IGN; | ||
| 218 | |||
| 219 | flush_signals(t); | ||
| 220 | } | ||
| 221 | |||
| 332 | /* | 222 | /* |
| 333 | * Flush all handlers for a task. | 223 | * Flush all handlers for a task. |
| 334 | */ | 224 | */ |
| @@ -1033,17 +923,6 @@ void zap_other_threads(struct task_struct *p) | |||
| 1033 | if (t->exit_state) | 923 | if (t->exit_state) |
| 1034 | continue; | 924 | continue; |
| 1035 | 925 | ||
| 1036 | /* | ||
| 1037 | * We don't want to notify the parent, since we are | ||
| 1038 | * killed as part of a thread group due to another | ||
| 1039 | * thread doing an execve() or similar. So set the | ||
| 1040 | * exit signal to -1 to allow immediate reaping of | ||
| 1041 | * the process. But don't detach the thread group | ||
| 1042 | * leader. | ||
| 1043 | */ | ||
| 1044 | if (t != p->group_leader) | ||
| 1045 | t->exit_signal = -1; | ||
| 1046 | |||
| 1047 | /* SIGKILL will be handled before any pending SIGSTOP */ | 926 | /* SIGKILL will be handled before any pending SIGSTOP */ |
| 1048 | sigaddset(&t->pending.signal, SIGKILL); | 927 | sigaddset(&t->pending.signal, SIGKILL); |
| 1049 | signal_wake_up(t, 1); | 928 | signal_wake_up(t, 1); |
| @@ -2636,9 +2515,5 @@ __attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma) | |||
| 2636 | 2515 | ||
| 2637 | void __init signals_init(void) | 2516 | void __init signals_init(void) |
| 2638 | { | 2517 | { |
| 2639 | sigqueue_cachep = | 2518 | sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); |
| 2640 | kmem_cache_create("sigqueue", | ||
| 2641 | sizeof(struct sigqueue), | ||
| 2642 | __alignof__(struct sigqueue), | ||
| 2643 | SLAB_PANIC, NULL, NULL); | ||
| 2644 | } | 2519 | } |
