diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 80 |
1 files changed, 27 insertions, 53 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 6c0958e52ea7..82c3545596c5 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -338,13 +338,9 @@ unblock_all_signals(void) | |||
338 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | 338 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
339 | } | 339 | } |
340 | 340 | ||
341 | static int collect_signal(int sig, struct sigpending *list, siginfo_t *info) | 341 | static void collect_signal(int sig, struct sigpending *list, siginfo_t *info) |
342 | { | 342 | { |
343 | struct sigqueue *q, *first = NULL; | 343 | struct sigqueue *q, *first = NULL; |
344 | int still_pending = 0; | ||
345 | |||
346 | if (unlikely(!sigismember(&list->signal, sig))) | ||
347 | return 0; | ||
348 | 344 | ||
349 | /* | 345 | /* |
350 | * Collect the siginfo appropriate to this signal. Check if | 346 | * Collect the siginfo appropriate to this signal. Check if |
@@ -352,33 +348,30 @@ static int collect_signal(int sig, struct sigpending *list, siginfo_t *info) | |||
352 | */ | 348 | */ |
353 | list_for_each_entry(q, &list->list, list) { | 349 | list_for_each_entry(q, &list->list, list) { |
354 | if (q->info.si_signo == sig) { | 350 | if (q->info.si_signo == sig) { |
355 | if (first) { | 351 | if (first) |
356 | still_pending = 1; | 352 | goto still_pending; |
357 | break; | ||
358 | } | ||
359 | first = q; | 353 | first = q; |
360 | } | 354 | } |
361 | } | 355 | } |
356 | |||
357 | sigdelset(&list->signal, sig); | ||
358 | |||
362 | if (first) { | 359 | if (first) { |
360 | still_pending: | ||
363 | list_del_init(&first->list); | 361 | list_del_init(&first->list); |
364 | copy_siginfo(info, &first->info); | 362 | copy_siginfo(info, &first->info); |
365 | __sigqueue_free(first); | 363 | __sigqueue_free(first); |
366 | if (!still_pending) | ||
367 | sigdelset(&list->signal, sig); | ||
368 | } else { | 364 | } else { |
369 | |||
370 | /* Ok, it wasn't in the queue. This must be | 365 | /* Ok, it wasn't in the queue. This must be |
371 | a fast-pathed signal or we must have been | 366 | a fast-pathed signal or we must have been |
372 | out of queue space. So zero out the info. | 367 | out of queue space. So zero out the info. |
373 | */ | 368 | */ |
374 | sigdelset(&list->signal, sig); | ||
375 | info->si_signo = sig; | 369 | info->si_signo = sig; |
376 | info->si_errno = 0; | 370 | info->si_errno = 0; |
377 | info->si_code = 0; | 371 | info->si_code = 0; |
378 | info->si_pid = 0; | 372 | info->si_pid = 0; |
379 | info->si_uid = 0; | 373 | info->si_uid = 0; |
380 | } | 374 | } |
381 | return 1; | ||
382 | } | 375 | } |
383 | 376 | ||
384 | static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, | 377 | static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, |
@@ -396,8 +389,7 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, | |||
396 | } | 389 | } |
397 | } | 390 | } |
398 | 391 | ||
399 | if (!collect_signal(sig, pending, info)) | 392 | collect_signal(sig, pending, info); |
400 | sig = 0; | ||
401 | } | 393 | } |
402 | 394 | ||
403 | return sig; | 395 | return sig; |
@@ -462,8 +454,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
462 | * is to alert stop-signal processing code when another | 454 | * is to alert stop-signal processing code when another |
463 | * processor has come along and cleared the flag. | 455 | * processor has come along and cleared the flag. |
464 | */ | 456 | */ |
465 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) | 457 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; |
466 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | ||
467 | } | 458 | } |
468 | if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { | 459 | if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { |
469 | /* | 460 | /* |
@@ -1125,7 +1116,7 @@ EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); | |||
1125 | * is probably wrong. Should make it like BSD or SYSV. | 1116 | * is probably wrong. Should make it like BSD or SYSV. |
1126 | */ | 1117 | */ |
1127 | 1118 | ||
1128 | static int kill_something_info(int sig, struct siginfo *info, int pid) | 1119 | static int kill_something_info(int sig, struct siginfo *info, pid_t pid) |
1129 | { | 1120 | { |
1130 | int ret; | 1121 | int ret; |
1131 | 1122 | ||
@@ -1237,17 +1228,6 @@ int kill_pid(struct pid *pid, int sig, int priv) | |||
1237 | } | 1228 | } |
1238 | EXPORT_SYMBOL(kill_pid); | 1229 | EXPORT_SYMBOL(kill_pid); |
1239 | 1230 | ||
1240 | int | ||
1241 | kill_proc(pid_t pid, int sig, int priv) | ||
1242 | { | ||
1243 | int ret; | ||
1244 | |||
1245 | rcu_read_lock(); | ||
1246 | ret = kill_pid_info(sig, __si_special(priv), find_pid(pid)); | ||
1247 | rcu_read_unlock(); | ||
1248 | return ret; | ||
1249 | } | ||
1250 | |||
1251 | /* | 1231 | /* |
1252 | * These functions support sending signals using preallocated sigqueue | 1232 | * These functions support sending signals using preallocated sigqueue |
1253 | * structures. This is needed "because realtime applications cannot | 1233 | * structures. This is needed "because realtime applications cannot |
@@ -1379,10 +1359,9 @@ void do_notify_parent(struct task_struct *tsk, int sig) | |||
1379 | 1359 | ||
1380 | info.si_uid = tsk->uid; | 1360 | info.si_uid = tsk->uid; |
1381 | 1361 | ||
1382 | /* FIXME: find out whether or not this is supposed to be c*time. */ | 1362 | info.si_utime = cputime_to_clock_t(cputime_add(tsk->utime, |
1383 | info.si_utime = cputime_to_jiffies(cputime_add(tsk->utime, | ||
1384 | tsk->signal->utime)); | 1363 | tsk->signal->utime)); |
1385 | info.si_stime = cputime_to_jiffies(cputime_add(tsk->stime, | 1364 | info.si_stime = cputime_to_clock_t(cputime_add(tsk->stime, |
1386 | tsk->signal->stime)); | 1365 | tsk->signal->stime)); |
1387 | 1366 | ||
1388 | info.si_status = tsk->exit_code & 0x7f; | 1367 | info.si_status = tsk->exit_code & 0x7f; |
@@ -1450,9 +1429,8 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why) | |||
1450 | 1429 | ||
1451 | info.si_uid = tsk->uid; | 1430 | info.si_uid = tsk->uid; |
1452 | 1431 | ||
1453 | /* FIXME: find out whether or not this is supposed to be c*time. */ | 1432 | info.si_utime = cputime_to_clock_t(tsk->utime); |
1454 | info.si_utime = cputime_to_jiffies(tsk->utime); | 1433 | info.si_stime = cputime_to_clock_t(tsk->stime); |
1455 | info.si_stime = cputime_to_jiffies(tsk->stime); | ||
1456 | 1434 | ||
1457 | info.si_code = why; | 1435 | info.si_code = why; |
1458 | switch (why) { | 1436 | switch (why) { |
@@ -1491,10 +1469,10 @@ static inline int may_ptrace_stop(void) | |||
1491 | * is a deadlock situation, and pointless because our tracer | 1469 | * is a deadlock situation, and pointless because our tracer |
1492 | * is dead so don't allow us to stop. | 1470 | * is dead so don't allow us to stop. |
1493 | * If SIGKILL was already sent before the caller unlocked | 1471 | * If SIGKILL was already sent before the caller unlocked |
1494 | * ->siglock we must see ->core_waiters != 0. Otherwise it | 1472 | * ->siglock we must see ->core_state != NULL. Otherwise it |
1495 | * is safe to enter schedule(). | 1473 | * is safe to enter schedule(). |
1496 | */ | 1474 | */ |
1497 | if (unlikely(current->mm->core_waiters) && | 1475 | if (unlikely(current->mm->core_state) && |
1498 | unlikely(current->mm == current->parent->mm)) | 1476 | unlikely(current->mm == current->parent->mm)) |
1499 | return 0; | 1477 | return 0; |
1500 | 1478 | ||
@@ -1507,9 +1485,8 @@ static inline int may_ptrace_stop(void) | |||
1507 | */ | 1485 | */ |
1508 | static int sigkill_pending(struct task_struct *tsk) | 1486 | static int sigkill_pending(struct task_struct *tsk) |
1509 | { | 1487 | { |
1510 | return ((sigismember(&tsk->pending.signal, SIGKILL) || | 1488 | return sigismember(&tsk->pending.signal, SIGKILL) || |
1511 | sigismember(&tsk->signal->shared_pending.signal, SIGKILL)) && | 1489 | sigismember(&tsk->signal->shared_pending.signal, SIGKILL); |
1512 | !unlikely(sigismember(&tsk->blocked, SIGKILL))); | ||
1513 | } | 1490 | } |
1514 | 1491 | ||
1515 | /* | 1492 | /* |
@@ -1525,8 +1502,6 @@ static int sigkill_pending(struct task_struct *tsk) | |||
1525 | */ | 1502 | */ |
1526 | static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) | 1503 | static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) |
1527 | { | 1504 | { |
1528 | int killed = 0; | ||
1529 | |||
1530 | if (arch_ptrace_stop_needed(exit_code, info)) { | 1505 | if (arch_ptrace_stop_needed(exit_code, info)) { |
1531 | /* | 1506 | /* |
1532 | * The arch code has something special to do before a | 1507 | * The arch code has something special to do before a |
@@ -1542,7 +1517,8 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) | |||
1542 | spin_unlock_irq(¤t->sighand->siglock); | 1517 | spin_unlock_irq(¤t->sighand->siglock); |
1543 | arch_ptrace_stop(exit_code, info); | 1518 | arch_ptrace_stop(exit_code, info); |
1544 | spin_lock_irq(¤t->sighand->siglock); | 1519 | spin_lock_irq(¤t->sighand->siglock); |
1545 | killed = sigkill_pending(current); | 1520 | if (sigkill_pending(current)) |
1521 | return; | ||
1546 | } | 1522 | } |
1547 | 1523 | ||
1548 | /* | 1524 | /* |
@@ -1559,7 +1535,7 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) | |||
1559 | __set_current_state(TASK_TRACED); | 1535 | __set_current_state(TASK_TRACED); |
1560 | spin_unlock_irq(¤t->sighand->siglock); | 1536 | spin_unlock_irq(¤t->sighand->siglock); |
1561 | read_lock(&tasklist_lock); | 1537 | read_lock(&tasklist_lock); |
1562 | if (!unlikely(killed) && may_ptrace_stop()) { | 1538 | if (may_ptrace_stop()) { |
1563 | do_notify_parent_cldstop(current, CLD_TRAPPED); | 1539 | do_notify_parent_cldstop(current, CLD_TRAPPED); |
1564 | read_unlock(&tasklist_lock); | 1540 | read_unlock(&tasklist_lock); |
1565 | schedule(); | 1541 | schedule(); |
@@ -1658,8 +1634,7 @@ static int do_signal_stop(int signr) | |||
1658 | } else { | 1634 | } else { |
1659 | struct task_struct *t; | 1635 | struct task_struct *t; |
1660 | 1636 | ||
1661 | if (unlikely((sig->flags & (SIGNAL_STOP_DEQUEUED | SIGNAL_UNKILLABLE)) | 1637 | if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || |
1662 | != SIGNAL_STOP_DEQUEUED) || | ||
1663 | unlikely(signal_group_exit(sig))) | 1638 | unlikely(signal_group_exit(sig))) |
1664 | return 0; | 1639 | return 0; |
1665 | /* | 1640 | /* |
@@ -1920,7 +1895,6 @@ EXPORT_SYMBOL(recalc_sigpending); | |||
1920 | EXPORT_SYMBOL_GPL(dequeue_signal); | 1895 | EXPORT_SYMBOL_GPL(dequeue_signal); |
1921 | EXPORT_SYMBOL(flush_signals); | 1896 | EXPORT_SYMBOL(flush_signals); |
1922 | EXPORT_SYMBOL(force_sig); | 1897 | EXPORT_SYMBOL(force_sig); |
1923 | EXPORT_SYMBOL(kill_proc); | ||
1924 | EXPORT_SYMBOL(ptrace_notify); | 1898 | EXPORT_SYMBOL(ptrace_notify); |
1925 | EXPORT_SYMBOL(send_sig); | 1899 | EXPORT_SYMBOL(send_sig); |
1926 | EXPORT_SYMBOL(send_sig_info); | 1900 | EXPORT_SYMBOL(send_sig_info); |
@@ -2196,7 +2170,7 @@ sys_rt_sigtimedwait(const sigset_t __user *uthese, | |||
2196 | } | 2170 | } |
2197 | 2171 | ||
2198 | asmlinkage long | 2172 | asmlinkage long |
2199 | sys_kill(int pid, int sig) | 2173 | sys_kill(pid_t pid, int sig) |
2200 | { | 2174 | { |
2201 | struct siginfo info; | 2175 | struct siginfo info; |
2202 | 2176 | ||
@@ -2209,7 +2183,7 @@ sys_kill(int pid, int sig) | |||
2209 | return kill_something_info(sig, &info, pid); | 2183 | return kill_something_info(sig, &info, pid); |
2210 | } | 2184 | } |
2211 | 2185 | ||
2212 | static int do_tkill(int tgid, int pid, int sig) | 2186 | static int do_tkill(pid_t tgid, pid_t pid, int sig) |
2213 | { | 2187 | { |
2214 | int error; | 2188 | int error; |
2215 | struct siginfo info; | 2189 | struct siginfo info; |
@@ -2255,7 +2229,7 @@ static int do_tkill(int tgid, int pid, int sig) | |||
2255 | * exists but it's not belonging to the target process anymore. This | 2229 | * exists but it's not belonging to the target process anymore. This |
2256 | * method solves the problem of threads exiting and PIDs getting reused. | 2230 | * method solves the problem of threads exiting and PIDs getting reused. |
2257 | */ | 2231 | */ |
2258 | asmlinkage long sys_tgkill(int tgid, int pid, int sig) | 2232 | asmlinkage long sys_tgkill(pid_t tgid, pid_t pid, int sig) |
2259 | { | 2233 | { |
2260 | /* This is only valid for single tasks */ | 2234 | /* This is only valid for single tasks */ |
2261 | if (pid <= 0 || tgid <= 0) | 2235 | if (pid <= 0 || tgid <= 0) |
@@ -2268,7 +2242,7 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig) | |||
2268 | * Send a signal to only one task, even if it's a CLONE_THREAD task. | 2242 | * Send a signal to only one task, even if it's a CLONE_THREAD task. |
2269 | */ | 2243 | */ |
2270 | asmlinkage long | 2244 | asmlinkage long |
2271 | sys_tkill(int pid, int sig) | 2245 | sys_tkill(pid_t pid, int sig) |
2272 | { | 2246 | { |
2273 | /* This is only valid for single tasks */ | 2247 | /* This is only valid for single tasks */ |
2274 | if (pid <= 0) | 2248 | if (pid <= 0) |
@@ -2278,7 +2252,7 @@ sys_tkill(int pid, int sig) | |||
2278 | } | 2252 | } |
2279 | 2253 | ||
2280 | asmlinkage long | 2254 | asmlinkage long |
2281 | sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo) | 2255 | sys_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t __user *uinfo) |
2282 | { | 2256 | { |
2283 | siginfo_t info; | 2257 | siginfo_t info; |
2284 | 2258 | ||