diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2005-08-29 11:44:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-29 13:03:11 -0400 |
commit | 69be8f189653cd81aae5a74e26615b12871bb72e (patch) | |
tree | 89c7d7b5b68ae47818b9dbc9015f1e4452ec2075 | |
parent | 02b3e4e2d71b6058ec11cc01c72ac651eb3ded2b (diff) |
[PATCH] convert signal handling of NODEFER to act like other Unix boxes.
It has been reported that the way Linux handles NODEFER for signals is
not consistent with the way other Unix boxes handle it. I've written a
program to test the behavior of how this flag affects signals and had
several reports from people who ran this on various Unix boxes,
confirming that Linux seems to be unique on the way this is handled.
The way NODEFER affects signals on other Unix boxes is as follows:
1) If NODEFER is set, other signals in sa_mask are still blocked.
2) If NODEFER is set and the signal is in sa_mask, then the signal is
still blocked. (Note: this is the behavior of all tested but Linux _and_
NetBSD 2.0 *).
The way NODEFER affects signals on Linux:
1) If NODEFER is set, other signals are _not_ blocked regardless of
sa_mask (Even NetBSD doesn't do this).
2) If NODEFER is set and the signal is in sa_mask, then the signal being
handled is not blocked.
The patch converts signal handling in all current Linux architectures to
the way most Unix boxes work.
Unix boxes that were tested: DU4, AIX 5.2, Irix 6.5, NetBSD 2.0, SFU
3.5 on WinXP, AIX 5.3, Mac OSX, and of course Linux 2.6.13-rcX.
* NetBSD was the only other Unix to behave like Linux on point #2. The
main concern was brought up by point #1 which even NetBSD isn't like
Linux. So with this patch, we leave NetBSD as the lonely one that
behaves differently here with #2.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
29 files changed, 135 insertions, 155 deletions
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 08fe8071a7f8..2e45e8604e32 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
@@ -566,13 +566,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
566 | if (ka->sa.sa_flags & SA_RESETHAND) | 566 | if (ka->sa.sa_flags & SA_RESETHAND) |
567 | ka->sa.sa_handler = SIG_DFL; | 567 | ka->sa.sa_handler = SIG_DFL; |
568 | 568 | ||
569 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 569 | spin_lock_irq(¤t->sighand->siglock); |
570 | spin_lock_irq(¤t->sighand->siglock); | 570 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
571 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 571 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
572 | sigaddset(¤t->blocked,sig); | 572 | sigaddset(¤t->blocked,sig); |
573 | recalc_sigpending(); | 573 | recalc_sigpending(); |
574 | spin_unlock_irq(¤t->sighand->siglock); | 574 | spin_unlock_irq(¤t->sighand->siglock); |
575 | } | ||
576 | } | 575 | } |
577 | 576 | ||
578 | static inline void | 577 | static inline void |
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 5e435e42dacd..a94d75fef598 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -658,11 +658,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
658 | /* | 658 | /* |
659 | * Block the signal if we were unsuccessful. | 659 | * Block the signal if we were unsuccessful. |
660 | */ | 660 | */ |
661 | if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) { | 661 | if (ret != 0) { |
662 | spin_lock_irq(&tsk->sighand->siglock); | 662 | spin_lock_irq(&tsk->sighand->siglock); |
663 | sigorsets(&tsk->blocked, &tsk->blocked, | 663 | sigorsets(&tsk->blocked, &tsk->blocked, |
664 | &ka->sa.sa_mask); | 664 | &ka->sa.sa_mask); |
665 | sigaddset(&tsk->blocked, sig); | 665 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
666 | sigaddset(&tsk->blocked, sig); | ||
666 | recalc_sigpending(); | 667 | recalc_sigpending(); |
667 | spin_unlock_irq(&tsk->sighand->siglock); | 668 | spin_unlock_irq(&tsk->sighand->siglock); |
668 | } | 669 | } |
diff --git a/arch/arm26/kernel/signal.c b/arch/arm26/kernel/signal.c index 356d9809cc0b..ce2055bdc9ee 100644 --- a/arch/arm26/kernel/signal.c +++ b/arch/arm26/kernel/signal.c | |||
@@ -454,14 +454,13 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, | |||
454 | if (ka->sa.sa_flags & SA_ONESHOT) | 454 | if (ka->sa.sa_flags & SA_ONESHOT) |
455 | ka->sa.sa_handler = SIG_DFL; | 455 | ka->sa.sa_handler = SIG_DFL; |
456 | 456 | ||
457 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 457 | spin_lock_irq(&tsk->sighand->siglock); |
458 | spin_lock_irq(&tsk->sighand->siglock); | 458 | sigorsets(&tsk->blocked, &tsk->blocked, |
459 | sigorsets(&tsk->blocked, &tsk->blocked, | 459 | &ka->sa.sa_mask); |
460 | &ka->sa.sa_mask); | 460 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
461 | sigaddset(&tsk->blocked, sig); | 461 | sigaddset(&tsk->blocked, sig); |
462 | recalc_sigpending(); | 462 | recalc_sigpending(); |
463 | spin_unlock_irq(&tsk->sighand->siglock); | 463 | spin_unlock_irq(&tsk->sighand->siglock); |
464 | } | ||
465 | return; | 464 | return; |
466 | } | 465 | } |
467 | 466 | ||
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index 85e0032e664f..693771961f85 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c | |||
@@ -517,13 +517,12 @@ handle_signal(int canrestart, unsigned long sig, | |||
517 | if (ka->sa.sa_flags & SA_ONESHOT) | 517 | if (ka->sa.sa_flags & SA_ONESHOT) |
518 | ka->sa.sa_handler = SIG_DFL; | 518 | ka->sa.sa_handler = SIG_DFL; |
519 | 519 | ||
520 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 520 | spin_lock_irq(¤t->sighand->siglock); |
521 | spin_lock_irq(¤t->sighand->siglock); | 521 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
522 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 522 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
523 | sigaddset(¤t->blocked,sig); | 523 | sigaddset(¤t->blocked,sig); |
524 | recalc_sigpending(); | 524 | recalc_sigpending(); |
525 | spin_unlock_irq(¤t->sighand->siglock); | 525 | spin_unlock_irq(¤t->sighand->siglock); |
526 | } | ||
527 | } | 526 | } |
528 | 527 | ||
529 | /* | 528 | /* |
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index fb4c79d5b76b..0a3614dab887 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c | |||
@@ -568,13 +568,12 @@ handle_signal(int canrestart, unsigned long sig, | |||
568 | if (ka->sa.sa_flags & SA_ONESHOT) | 568 | if (ka->sa.sa_flags & SA_ONESHOT) |
569 | ka->sa.sa_handler = SIG_DFL; | 569 | ka->sa.sa_handler = SIG_DFL; |
570 | 570 | ||
571 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 571 | spin_lock_irq(¤t->sighand->siglock); |
572 | spin_lock_irq(¤t->sighand->siglock); | 572 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
573 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 573 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
574 | sigaddset(¤t->blocked,sig); | 574 | sigaddset(¤t->blocked,sig); |
575 | recalc_sigpending(); | 575 | recalc_sigpending(); |
576 | spin_unlock_irq(¤t->sighand->siglock); | 576 | spin_unlock_irq(¤t->sighand->siglock); |
577 | } | ||
578 | } | 577 | } |
579 | 578 | ||
580 | /* | 579 | /* |
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 36a2dffc8ebd..d4ccc0728dfe 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
@@ -506,13 +506,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info, | |||
506 | else | 506 | else |
507 | setup_frame(sig, ka, oldset, regs); | 507 | setup_frame(sig, ka, oldset, regs); |
508 | 508 | ||
509 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 509 | spin_lock_irq(¤t->sighand->siglock); |
510 | spin_lock_irq(¤t->sighand->siglock); | 510 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
511 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 511 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
512 | sigaddset(¤t->blocked, sig); | 512 | sigaddset(¤t->blocked, sig); |
513 | recalc_sigpending(); | 513 | recalc_sigpending(); |
514 | spin_unlock_irq(¤t->sighand->siglock); | 514 | spin_unlock_irq(¤t->sighand->siglock); |
515 | } | ||
516 | } /* end handle_signal() */ | 515 | } /* end handle_signal() */ |
517 | 516 | ||
518 | /*****************************************************************************/ | 517 | /*****************************************************************************/ |
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index 5aab87eae1f9..f13d5e82d4b9 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c | |||
@@ -488,13 +488,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
488 | else | 488 | else |
489 | setup_frame(sig, ka, oldset, regs); | 489 | setup_frame(sig, ka, oldset, regs); |
490 | 490 | ||
491 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 491 | spin_lock_irq(¤t->sighand->siglock); |
492 | spin_lock_irq(¤t->sighand->siglock); | 492 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
493 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 493 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
494 | sigaddset(¤t->blocked,sig); | 494 | sigaddset(¤t->blocked,sig); |
495 | recalc_sigpending(); | 495 | recalc_sigpending(); |
496 | spin_unlock_irq(¤t->sighand->siglock); | 496 | spin_unlock_irq(¤t->sighand->siglock); |
497 | } | ||
498 | } | 497 | } |
499 | 498 | ||
500 | /* | 499 | /* |
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 89ef7adc63a4..140e340569c6 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c | |||
@@ -577,10 +577,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
577 | else | 577 | else |
578 | ret = setup_frame(sig, ka, oldset, regs); | 578 | ret = setup_frame(sig, ka, oldset, regs); |
579 | 579 | ||
580 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { | 580 | if (ret) { |
581 | spin_lock_irq(¤t->sighand->siglock); | 581 | spin_lock_irq(¤t->sighand->siglock); |
582 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 582 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
583 | sigaddset(¤t->blocked,sig); | 583 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
584 | sigaddset(¤t->blocked,sig); | ||
584 | recalc_sigpending(); | 585 | recalc_sigpending(); |
585 | spin_unlock_irq(¤t->sighand->siglock); | 586 | spin_unlock_irq(¤t->sighand->siglock); |
586 | } | 587 | } |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index b8a0a7d257a9..774f34b675cf 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -467,15 +467,12 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse | |||
467 | if (!setup_frame(sig, ka, info, oldset, scr)) | 467 | if (!setup_frame(sig, ka, info, oldset, scr)) |
468 | return 0; | 468 | return 0; |
469 | 469 | ||
470 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 470 | spin_lock_irq(¤t->sighand->siglock); |
471 | spin_lock_irq(¤t->sighand->siglock); | 471 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
472 | { | 472 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
473 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 473 | sigaddset(¤t->blocked, sig); |
474 | sigaddset(¤t->blocked, sig); | 474 | recalc_sigpending(); |
475 | recalc_sigpending(); | 475 | spin_unlock_irq(¤t->sighand->siglock); |
476 | } | ||
477 | spin_unlock_irq(¤t->sighand->siglock); | ||
478 | } | ||
479 | return 1; | 476 | return 1; |
480 | } | 477 | } |
481 | 478 | ||
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 5aef7e406ef5..71763f7a1d19 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -341,13 +341,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
341 | /* Set up the stack frame */ | 341 | /* Set up the stack frame */ |
342 | setup_rt_frame(sig, ka, info, oldset, regs); | 342 | setup_rt_frame(sig, ka, info, oldset, regs); |
343 | 343 | ||
344 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 344 | spin_lock_irq(¤t->sighand->siglock); |
345 | spin_lock_irq(¤t->sighand->siglock); | 345 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
346 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 346 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
347 | sigaddset(¤t->blocked,sig); | 347 | sigaddset(¤t->blocked,sig); |
348 | recalc_sigpending(); | 348 | recalc_sigpending(); |
349 | spin_unlock_irq(¤t->sighand->siglock); | 349 | spin_unlock_irq(¤t->sighand->siglock); |
350 | } | ||
351 | } | 350 | } |
352 | 351 | ||
353 | /* | 352 | /* |
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c index 30dceb59a462..43a2726c0d0a 100644 --- a/arch/m68knommu/kernel/signal.c +++ b/arch/m68knommu/kernel/signal.c | |||
@@ -732,13 +732,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
732 | if (ka->sa.sa_flags & SA_ONESHOT) | 732 | if (ka->sa.sa_flags & SA_ONESHOT) |
733 | ka->sa.sa_handler = SIG_DFL; | 733 | ka->sa.sa_handler = SIG_DFL; |
734 | 734 | ||
735 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 735 | spin_lock_irq(¤t->sighand->siglock); |
736 | spin_lock_irq(¤t->sighand->siglock); | 736 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
737 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 737 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
738 | sigaddset(¤t->blocked,sig); | 738 | sigaddset(¤t->blocked,sig); |
739 | recalc_sigpending(); | 739 | recalc_sigpending(); |
740 | spin_unlock_irq(¤t->sighand->siglock); | 740 | spin_unlock_irq(¤t->sighand->siglock); |
741 | } | ||
742 | } | 741 | } |
743 | 742 | ||
744 | /* | 743 | /* |
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index 40244782a8e5..4c114ae21793 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c | |||
@@ -155,13 +155,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
155 | else | 155 | else |
156 | setup_irix_frame(ka, regs, sig, oldset); | 156 | setup_irix_frame(ka, regs, sig, oldset); |
157 | 157 | ||
158 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 158 | spin_lock_irq(¤t->sighand->siglock); |
159 | spin_lock_irq(¤t->sighand->siglock); | 159 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
160 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 160 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
161 | sigaddset(¤t->blocked,sig); | 161 | sigaddset(¤t->blocked,sig); |
162 | recalc_sigpending(); | 162 | recalc_sigpending(); |
163 | spin_unlock_irq(¤t->sighand->siglock); | 163 | spin_unlock_irq(¤t->sighand->siglock); |
164 | } | ||
165 | } | 164 | } |
166 | 165 | ||
167 | asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) | 166 | asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 65ee15396ffd..0209c1dd1429 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -425,13 +425,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
425 | setup_frame(ka, regs, sig, oldset); | 425 | setup_frame(ka, regs, sig, oldset); |
426 | #endif | 426 | #endif |
427 | 427 | ||
428 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 428 | spin_lock_irq(¤t->sighand->siglock); |
429 | spin_lock_irq(¤t->sighand->siglock); | 429 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
430 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 430 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
431 | sigaddset(¤t->blocked,sig); | 431 | sigaddset(¤t->blocked,sig); |
432 | recalc_sigpending(); | 432 | recalc_sigpending(); |
433 | spin_unlock_irq(¤t->sighand->siglock); | 433 | spin_unlock_irq(¤t->sighand->siglock); |
434 | } | ||
435 | } | 434 | } |
436 | 435 | ||
437 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | 436 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index c1a69cf232f9..f6875f023a29 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -751,13 +751,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
751 | else | 751 | else |
752 | setup_frame(ka, regs, sig, oldset); | 752 | setup_frame(ka, regs, sig, oldset); |
753 | 753 | ||
754 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 754 | spin_lock_irq(¤t->sighand->siglock); |
755 | spin_lock_irq(¤t->sighand->siglock); | 755 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
756 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 756 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
757 | sigaddset(¤t->blocked,sig); | 757 | sigaddset(¤t->blocked,sig); |
758 | recalc_sigpending(); | 758 | recalc_sigpending(); |
759 | spin_unlock_irq(¤t->sighand->siglock); | 759 | spin_unlock_irq(¤t->sighand->siglock); |
760 | } | ||
761 | } | 760 | } |
762 | 761 | ||
763 | int do_signal32(sigset_t *oldset, struct pt_regs *regs) | 762 | int do_signal32(sigset_t *oldset, struct pt_regs *regs) |
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 9421bb98ea63..55d71c15e1f7 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
@@ -517,13 +517,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
517 | if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) | 517 | if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) |
518 | return 0; | 518 | return 0; |
519 | 519 | ||
520 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 520 | spin_lock_irq(¤t->sighand->siglock); |
521 | spin_lock_irq(¤t->sighand->siglock); | 521 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
522 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 522 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
523 | sigaddset(¤t->blocked,sig); | 523 | sigaddset(¤t->blocked,sig); |
524 | recalc_sigpending(); | 524 | recalc_sigpending(); |
525 | spin_unlock_irq(¤t->sighand->siglock); | 525 | spin_unlock_irq(¤t->sighand->siglock); |
526 | } | ||
527 | return 1; | 526 | return 1; |
528 | } | 527 | } |
529 | 528 | ||
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 8aaeb6f4e750..2244bf91e593 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c | |||
@@ -759,13 +759,12 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
759 | else | 759 | else |
760 | handle_signal(signr, &ka, &info, oldset, regs, newsp); | 760 | handle_signal(signr, &ka, &info, oldset, regs, newsp); |
761 | 761 | ||
762 | if (!(ka.sa.sa_flags & SA_NODEFER)) { | 762 | spin_lock_irq(¤t->sighand->siglock); |
763 | spin_lock_irq(¤t->sighand->siglock); | 763 | sigorsets(¤t->blocked,¤t->blocked,&ka.sa.sa_mask); |
764 | sigorsets(¤t->blocked,¤t->blocked,&ka.sa.sa_mask); | 764 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
765 | sigaddset(¤t->blocked, signr); | 765 | sigaddset(¤t->blocked, signr); |
766 | recalc_sigpending(); | 766 | recalc_sigpending(); |
767 | spin_unlock_irq(¤t->sighand->siglock); | 767 | spin_unlock_irq(¤t->sighand->siglock); |
768 | } | ||
769 | 768 | ||
770 | return 1; | 769 | return 1; |
771 | } | 770 | } |
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index bf782276984c..49a79a55c32d 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c | |||
@@ -481,10 +481,11 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
481 | /* Set up Signal Frame */ | 481 | /* Set up Signal Frame */ |
482 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 482 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
483 | 483 | ||
484 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { | 484 | if (ret) { |
485 | spin_lock_irq(¤t->sighand->siglock); | 485 | spin_lock_irq(¤t->sighand->siglock); |
486 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 486 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
487 | sigaddset(¤t->blocked,sig); | 487 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
488 | sigaddset(¤t->blocked,sig); | ||
488 | recalc_sigpending(); | 489 | recalc_sigpending(); |
489 | spin_unlock_irq(¤t->sighand->siglock); | 490 | spin_unlock_irq(¤t->sighand->siglock); |
490 | } | 491 | } |
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c index 3c2fa5c284c0..46f4d6cc7fc9 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/ppc64/kernel/signal32.c | |||
@@ -976,11 +976,12 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) | |||
976 | else | 976 | else |
977 | ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp); | 977 | ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp); |
978 | 978 | ||
979 | if (ret && !(ka.sa.sa_flags & SA_NODEFER)) { | 979 | if (ret) { |
980 | spin_lock_irq(¤t->sighand->siglock); | 980 | spin_lock_irq(¤t->sighand->siglock); |
981 | sigorsets(¤t->blocked, ¤t->blocked, | 981 | sigorsets(¤t->blocked, ¤t->blocked, |
982 | &ka.sa.sa_mask); | 982 | &ka.sa.sa_mask); |
983 | sigaddset(¤t->blocked, signr); | 983 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
984 | sigaddset(¤t->blocked, signr); | ||
984 | recalc_sigpending(); | 985 | recalc_sigpending(); |
985 | spin_unlock_irq(¤t->sighand->siglock); | 986 | spin_unlock_irq(¤t->sighand->siglock); |
986 | } | 987 | } |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index d05d65ac9694..7358cdb8441f 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -637,12 +637,11 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
637 | else | 637 | else |
638 | setup_frame32(sig, ka, oldset, regs); | 638 | setup_frame32(sig, ka, oldset, regs); |
639 | 639 | ||
640 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 640 | spin_lock_irq(¤t->sighand->siglock); |
641 | spin_lock_irq(¤t->sighand->siglock); | 641 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
642 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 642 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
643 | sigaddset(¤t->blocked,sig); | 643 | sigaddset(¤t->blocked,sig); |
644 | recalc_sigpending(); | 644 | recalc_sigpending(); |
645 | spin_unlock_irq(¤t->sighand->siglock); | 645 | spin_unlock_irq(¤t->sighand->siglock); |
646 | } | ||
647 | } | 646 | } |
648 | 647 | ||
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 610c1d03e975..6a3f5b7473a9 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -429,13 +429,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
429 | else | 429 | else |
430 | setup_frame(sig, ka, oldset, regs); | 430 | setup_frame(sig, ka, oldset, regs); |
431 | 431 | ||
432 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 432 | spin_lock_irq(¤t->sighand->siglock); |
433 | spin_lock_irq(¤t->sighand->siglock); | 433 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
434 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 434 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
435 | sigaddset(¤t->blocked,sig); | 435 | sigaddset(¤t->blocked,sig); |
436 | recalc_sigpending(); | 436 | recalc_sigpending(); |
437 | spin_unlock_irq(¤t->sighand->siglock); | 437 | spin_unlock_irq(¤t->sighand->siglock); |
438 | } | ||
439 | } | 438 | } |
440 | 439 | ||
441 | /* | 440 | /* |
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 8022243f0178..b475c4d2405f 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c | |||
@@ -546,13 +546,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
546 | if (ka->sa.sa_flags & SA_ONESHOT) | 546 | if (ka->sa.sa_flags & SA_ONESHOT) |
547 | ka->sa.sa_handler = SIG_DFL; | 547 | ka->sa.sa_handler = SIG_DFL; |
548 | 548 | ||
549 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 549 | spin_lock_irq(¤t->sighand->siglock); |
550 | spin_lock_irq(¤t->sighand->siglock); | 550 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
551 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 551 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
552 | sigaddset(¤t->blocked,sig); | 552 | sigaddset(¤t->blocked,sig); |
553 | recalc_sigpending(); | 553 | recalc_sigpending(); |
554 | spin_unlock_irq(¤t->sighand->siglock); | 554 | spin_unlock_irq(¤t->sighand->siglock); |
555 | } | ||
556 | } | 555 | } |
557 | 556 | ||
558 | /* | 557 | /* |
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c index c6a14a87c59b..3ea8929e483b 100644 --- a/arch/sh64/kernel/signal.c +++ b/arch/sh64/kernel/signal.c | |||
@@ -664,13 +664,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
664 | else | 664 | else |
665 | setup_frame(sig, ka, oldset, regs); | 665 | setup_frame(sig, ka, oldset, regs); |
666 | 666 | ||
667 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 667 | spin_lock_irq(¤t->sighand->siglock); |
668 | spin_lock_irq(¤t->sighand->siglock); | 668 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
669 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 669 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
670 | sigaddset(¤t->blocked,sig); | 670 | sigaddset(¤t->blocked,sig); |
671 | recalc_sigpending(); | 671 | recalc_sigpending(); |
672 | spin_unlock_irq(¤t->sighand->siglock); | 672 | spin_unlock_irq(¤t->sighand->siglock); |
673 | } | ||
674 | } | 673 | } |
675 | 674 | ||
676 | /* | 675 | /* |
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index 011ff35057a5..5f34d7dc2b89 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c | |||
@@ -1034,13 +1034,12 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
1034 | else | 1034 | else |
1035 | setup_frame(&ka->sa, regs, signr, oldset, info); | 1035 | setup_frame(&ka->sa, regs, signr, oldset, info); |
1036 | } | 1036 | } |
1037 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 1037 | spin_lock_irq(¤t->sighand->siglock); |
1038 | spin_lock_irq(¤t->sighand->siglock); | 1038 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
1039 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 1039 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
1040 | sigaddset(¤t->blocked, signr); | 1040 | sigaddset(¤t->blocked, signr); |
1041 | recalc_sigpending(); | 1041 | recalc_sigpending(); |
1042 | spin_unlock_irq(¤t->sighand->siglock); | 1042 | spin_unlock_irq(¤t->sighand->siglock); |
1043 | } | ||
1044 | } | 1043 | } |
1045 | 1044 | ||
1046 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 1045 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index b27934671c35..60f5dfabb1e1 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
@@ -574,13 +574,12 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
574 | { | 574 | { |
575 | setup_rt_frame(ka, regs, signr, oldset, | 575 | setup_rt_frame(ka, regs, signr, oldset, |
576 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | 576 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); |
577 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 577 | spin_lock_irq(¤t->sighand->siglock); |
578 | spin_lock_irq(¤t->sighand->siglock); | 578 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
579 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 579 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
580 | sigaddset(¤t->blocked,signr); | 580 | sigaddset(¤t->blocked,signr); |
581 | recalc_sigpending(); | 581 | recalc_sigpending(); |
582 | spin_unlock_irq(¤t->sighand->siglock); | 582 | spin_unlock_irq(¤t->sighand->siglock); |
583 | } | ||
584 | } | 583 | } |
585 | 584 | ||
586 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 585 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index f28428f4170e..b1ed23091fbb 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -1325,13 +1325,12 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | |||
1325 | else | 1325 | else |
1326 | setup_frame32(&ka->sa, regs, signr, oldset, info); | 1326 | setup_frame32(&ka->sa, regs, signr, oldset, info); |
1327 | } | 1327 | } |
1328 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 1328 | spin_lock_irq(¤t->sighand->siglock); |
1329 | spin_lock_irq(¤t->sighand->siglock); | 1329 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
1330 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 1330 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
1331 | sigaddset(¤t->blocked,signr); | 1331 | sigaddset(¤t->blocked,signr); |
1332 | recalc_sigpending(); | 1332 | recalc_sigpending(); |
1333 | spin_unlock_irq(¤t->sighand->siglock); | 1333 | spin_unlock_irq(¤t->sighand->siglock); |
1334 | } | ||
1335 | } | 1334 | } |
1336 | 1335 | ||
1337 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, | 1336 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c index 7807a3e8c426..03618bd13d55 100644 --- a/arch/um/kernel/signal_kern.c +++ b/arch/um/kernel/signal_kern.c | |||
@@ -87,12 +87,12 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, | |||
87 | recalc_sigpending(); | 87 | recalc_sigpending(); |
88 | spin_unlock_irq(¤t->sighand->siglock); | 88 | spin_unlock_irq(¤t->sighand->siglock); |
89 | force_sigsegv(signr, current); | 89 | force_sigsegv(signr, current); |
90 | } | 90 | } else { |
91 | else if(!(ka->sa.sa_flags & SA_NODEFER)){ | ||
92 | spin_lock_irq(¤t->sighand->siglock); | 91 | spin_lock_irq(¤t->sighand->siglock); |
93 | sigorsets(¤t->blocked, ¤t->blocked, | 92 | sigorsets(¤t->blocked, ¤t->blocked, |
94 | &ka->sa.sa_mask); | 93 | &ka->sa.sa_mask); |
95 | sigaddset(¤t->blocked, signr); | 94 | if(!(ka->sa.sa_flags & SA_NODEFER)) |
95 | sigaddset(¤t->blocked, signr); | ||
96 | recalc_sigpending(); | 96 | recalc_sigpending(); |
97 | spin_unlock_irq(¤t->sighand->siglock); | 97 | spin_unlock_irq(¤t->sighand->siglock); |
98 | } | 98 | } |
diff --git a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c index 37061e32e1a4..633e4e1b825f 100644 --- a/arch/v850/kernel/signal.c +++ b/arch/v850/kernel/signal.c | |||
@@ -462,13 +462,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
462 | else | 462 | else |
463 | setup_frame(sig, ka, oldset, regs); | 463 | setup_frame(sig, ka, oldset, regs); |
464 | 464 | ||
465 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 465 | spin_lock_irq(¤t->sighand->siglock); |
466 | spin_lock_irq(¤t->sighand->siglock); | 466 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
467 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 467 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
468 | sigaddset(¤t->blocked,sig); | 468 | sigaddset(¤t->blocked,sig); |
469 | recalc_sigpending(); | 469 | recalc_sigpending(); |
470 | spin_unlock_irq(¤t->sighand->siglock); | 470 | spin_unlock_irq(¤t->sighand->siglock); |
471 | } | ||
472 | } | 471 | } |
473 | 472 | ||
474 | /* | 473 | /* |
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 98590a989f3d..d642fbf3da29 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -394,10 +394,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
394 | #endif | 394 | #endif |
395 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 395 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
396 | 396 | ||
397 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { | 397 | if (ret) { |
398 | spin_lock_irq(¤t->sighand->siglock); | 398 | spin_lock_irq(¤t->sighand->siglock); |
399 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 399 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
400 | sigaddset(¤t->blocked,sig); | 400 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
401 | sigaddset(¤t->blocked,sig); | ||
401 | recalc_sigpending(); | 402 | recalc_sigpending(); |
402 | spin_unlock_irq(¤t->sighand->siglock); | 403 | spin_unlock_irq(¤t->sighand->siglock); |
403 | } | 404 | } |
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index df6e1e17b096..dc42cede9394 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
@@ -702,12 +702,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
702 | if (ka.sa.sa_flags & SA_ONESHOT) | 702 | if (ka.sa.sa_flags & SA_ONESHOT) |
703 | ka.sa.sa_handler = SIG_DFL; | 703 | ka.sa.sa_handler = SIG_DFL; |
704 | 704 | ||
705 | if (!(ka.sa.sa_flags & SA_NODEFER)) { | 705 | spin_lock_irq(¤t->sighand->siglock); |
706 | spin_lock_irq(¤t->sighand->siglock); | 706 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); |
707 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); | 707 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
708 | sigaddset(¤t->blocked, signr); | 708 | sigaddset(¤t->blocked, signr); |
709 | recalc_sigpending(); | 709 | recalc_sigpending(); |
710 | spin_unlock_irq(¤t->sighand->siglock); | 710 | spin_unlock_irq(¤t->sighand->siglock); |
711 | } | ||
712 | return 1; | 711 | return 1; |
713 | } | 712 | } |