aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/signal.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@openvz.org>2007-01-23 11:03:17 -0500
committerTony Luck <tony.luck@intel.com>2007-05-08 17:51:59 -0400
commit4a177cbf84f827cf9f1d6cfa5264fafd3cc33ce0 (patch)
treeef04ada4e2b708ee965081cd905026c9156863d3 /arch/ia64/kernel/signal.c
parent690def21414fa43fac1b8053fd952c0366c476de (diff)
[IA64] Add TIF_RESTORE_SIGMASK
Preparation for pselect and ppoll. ia32 compat code not tested. :-( Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> Signed-off-by: Alexey Dobriyan <adobriyan@openvz.org> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/signal.c')
-rw-r--r--arch/ia64/kernel/signal.c71
1 files changed, 23 insertions, 48 deletions
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 77f8b49c7882..034b81d62bb1 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -41,47 +41,6 @@
41# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0]) 41# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0])
42#endif 42#endif
43 43
44long
45ia64_rt_sigsuspend (sigset_t __user *uset, size_t sigsetsize, struct sigscratch *scr)
46{
47 sigset_t oldset, set;
48
49 /* XXX: Don't preclude handling different sized sigset_t's. */
50 if (sigsetsize != sizeof(sigset_t))
51 return -EINVAL;
52
53 if (!access_ok(VERIFY_READ, uset, sigsetsize))
54 return -EFAULT;
55
56 if (GET_SIGSET(&set, uset))
57 return -EFAULT;
58
59 sigdelsetmask(&set, ~_BLOCKABLE);
60
61 spin_lock_irq(&current->sighand->siglock);
62 {
63 oldset = current->blocked;
64 current->blocked = set;
65 recalc_sigpending();
66 }
67 spin_unlock_irq(&current->sighand->siglock);
68
69 /*
70 * The return below usually returns to the signal handler. We need to
71 * pre-set the correct error code here to ensure that the right values
72 * get saved in sigcontext by ia64_do_signal.
73 */
74 scr->pt.r8 = EINTR;
75 scr->pt.r10 = -1;
76
77 while (1) {
78 current->state = TASK_INTERRUPTIBLE;
79 schedule();
80 if (ia64_do_signal(&oldset, scr, 1))
81 return -EINTR;
82 }
83}
84
85asmlinkage long 44asmlinkage long
86sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2, 45sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
87 long arg3, long arg4, long arg5, long arg6, long arg7, 46 long arg3, long arg4, long arg5, long arg6, long arg7,
@@ -478,10 +437,11 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
478 * Note that `init' is a special process: it doesn't get signals it doesn't want to 437 * Note that `init' is a special process: it doesn't get signals it doesn't want to
479 * handle. Thus you cannot kill init even with a SIGKILL even by mistake. 438 * handle. Thus you cannot kill init even with a SIGKILL even by mistake.
480 */ 439 */
481long 440void
482ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) 441ia64_do_signal (struct sigscratch *scr, long in_syscall)
483{ 442{
484 struct k_sigaction ka; 443 struct k_sigaction ka;
444 sigset_t *oldset;
485 siginfo_t info; 445 siginfo_t info;
486 long restart = in_syscall; 446 long restart = in_syscall;
487 long errno = scr->pt.r8; 447 long errno = scr->pt.r8;
@@ -493,9 +453,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
493 * doing anything if so. 453 * doing anything if so.
494 */ 454 */
495 if (!user_mode(&scr->pt)) 455 if (!user_mode(&scr->pt))
496 return 0; 456 return;
497 457
498 if (!oldset) 458 if (test_thread_flag(TIF_RESTORE_SIGMASK))
459 oldset = &current->saved_sigmask;
460 else
499 oldset = &current->blocked; 461 oldset = &current->blocked;
500 462
501 /* 463 /*
@@ -558,8 +520,15 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
558 * Whee! Actually deliver the signal. If the delivery failed, we need to 520 * Whee! Actually deliver the signal. If the delivery failed, we need to
559 * continue to iterate in this loop so we can deliver the SIGSEGV... 521 * continue to iterate in this loop so we can deliver the SIGSEGV...
560 */ 522 */
561 if (handle_signal(signr, &ka, &info, oldset, scr)) 523 if (handle_signal(signr, &ka, &info, oldset, scr)) {
562 return 1; 524 /* a signal was successfully delivered; the saved
525 * sigmask will have been stored in the signal frame,
526 * and will be restored by sigreturn, so we can simply
527 * clear the TIF_RESTORE_SIGMASK flag */
528 if (test_thread_flag(TIF_RESTORE_SIGMASK))
529 clear_thread_flag(TIF_RESTORE_SIGMASK);
530 return;
531 }
563 } 532 }
564 533
565 /* Did we come from a system call? */ 534 /* Did we come from a system call? */
@@ -585,5 +554,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
585 } 554 }
586 } 555 }
587 } 556 }
588 return 0; 557
558 /* if there's no signal to deliver, we just put the saved sigmask
559 * back */
560 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
561 clear_thread_flag(TIF_RESTORE_SIGMASK);
562 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
563 }
589} 564}