diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 707736e64e0e..e8308e3238c1 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -2300,12 +2300,6 @@ long do_no_restart_syscall(struct restart_block *param) | |||
2300 | } | 2300 | } |
2301 | 2301 | ||
2302 | /* | 2302 | /* |
2303 | * We don't need to get the kernel lock - this is all local to this | ||
2304 | * particular thread.. (and that's good, because this is _heavily_ | ||
2305 | * used by various programs) | ||
2306 | */ | ||
2307 | |||
2308 | /* | ||
2309 | * This is also useful for kernel threads that want to temporarily | 2303 | * This is also useful for kernel threads that want to temporarily |
2310 | * (or permanently) block certain signals. | 2304 | * (or permanently) block certain signals. |
2311 | * | 2305 | * |
@@ -2315,30 +2309,33 @@ long do_no_restart_syscall(struct restart_block *param) | |||
2315 | */ | 2309 | */ |
2316 | int sigprocmask(int how, sigset_t *set, sigset_t *oldset) | 2310 | int sigprocmask(int how, sigset_t *set, sigset_t *oldset) |
2317 | { | 2311 | { |
2318 | int error; | 2312 | struct task_struct *tsk = current; |
2313 | sigset_t newset; | ||
2319 | 2314 | ||
2320 | spin_lock_irq(¤t->sighand->siglock); | 2315 | /* Lockless, only current can change ->blocked, never from irq */ |
2321 | if (oldset) | 2316 | if (oldset) |
2322 | *oldset = current->blocked; | 2317 | *oldset = tsk->blocked; |
2323 | 2318 | ||
2324 | error = 0; | ||
2325 | switch (how) { | 2319 | switch (how) { |
2326 | case SIG_BLOCK: | 2320 | case SIG_BLOCK: |
2327 | sigorsets(¤t->blocked, ¤t->blocked, set); | 2321 | sigorsets(&newset, &tsk->blocked, set); |
2328 | break; | 2322 | break; |
2329 | case SIG_UNBLOCK: | 2323 | case SIG_UNBLOCK: |
2330 | signandsets(¤t->blocked, ¤t->blocked, set); | 2324 | signandsets(&newset, &tsk->blocked, set); |
2331 | break; | 2325 | break; |
2332 | case SIG_SETMASK: | 2326 | case SIG_SETMASK: |
2333 | current->blocked = *set; | 2327 | newset = *set; |
2334 | break; | 2328 | break; |
2335 | default: | 2329 | default: |
2336 | error = -EINVAL; | 2330 | return -EINVAL; |
2337 | } | 2331 | } |
2332 | |||
2333 | spin_lock_irq(&tsk->sighand->siglock); | ||
2334 | tsk->blocked = newset; | ||
2338 | recalc_sigpending(); | 2335 | recalc_sigpending(); |
2339 | spin_unlock_irq(¤t->sighand->siglock); | 2336 | spin_unlock_irq(&tsk->sighand->siglock); |
2340 | 2337 | ||
2341 | return error; | 2338 | return 0; |
2342 | } | 2339 | } |
2343 | 2340 | ||
2344 | /** | 2341 | /** |