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 08fe8071a7f..2e45e8604e3 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 5e435e42dac..a94d75fef59 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 356d9809cc0..ce2055bdc9e 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 85e0032e664..693771961f8 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 fb4c79d5b76..0a3614dab88 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 36a2dffc8eb..d4ccc0728df 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 5aab87eae1f..f13d5e82d4b 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 89ef7adc63a..140e340569c 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 b8a0a7d257a..774f34b675c 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 5aef7e406ef..71763f7a1d1 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 30dceb59a46..43a2726c0d0 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 40244782a8e..4c114ae2179 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 65ee15396ff..0209c1dd142 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 c1a69cf232f..f6875f023a2 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 9421bb98ea6..55d71c15e1f 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 8aaeb6f4e75..2244bf91e59 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 bf782276984..49a79a55c32 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 3c2fa5c284c..46f4d6cc7fc 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 d05d65ac969..7358cdb8441 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 610c1d03e97..6a3f5b7473a 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 8022243f017..b475c4d2405 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 c6a14a87c59..3ea8929e483 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 011ff35057a..5f34d7dc2b8 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 b27934671c3..60f5dfabb1e 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 f28428f4170..b1ed23091fb 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 7807a3e8c42..03618bd13d5 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 37061e32e1a..633e4e1b825 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 98590a989f3..d642fbf3da2 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 df6e1e17b09..dc42cede939 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 | } |