diff options
author | Alexey Dobriyan <adobriyan@openvz.org> | 2007-01-23 11:03:17 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2007-05-08 17:51:59 -0400 |
commit | 4a177cbf84f827cf9f1d6cfa5264fafd3cc33ce0 (patch) | |
tree | ef04ada4e2b708ee965081cd905026c9156863d3 /arch/ia64/ia32/ia32_signal.c | |
parent | 690def21414fa43fac1b8053fd952c0366c476de (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/ia32/ia32_signal.c')
-rw-r--r-- | arch/ia64/ia32/ia32_signal.c | 59 |
1 files changed, 10 insertions, 49 deletions
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c index 7b38b73e7827..b2bb7f227920 100644 --- a/arch/ia64/ia32/ia32_signal.c +++ b/arch/ia64/ia32/ia32_signal.c | |||
@@ -452,59 +452,20 @@ sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int r | |||
452 | sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); | 452 | sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); |
453 | } | 453 | } |
454 | 454 | ||
455 | long | 455 | asmlinkage long |
456 | __ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr) | 456 | sys32_sigsuspend (int history0, int history1, old_sigset_t mask) |
457 | { | 457 | { |
458 | extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall); | 458 | mask &= _BLOCKABLE; |
459 | sigset_t oldset, set; | ||
460 | |||
461 | scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */ | ||
462 | memset(&set, 0, sizeof(set)); | ||
463 | |||
464 | memcpy(&set.sig, &sset->sig, sigsetsize); | ||
465 | |||
466 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
467 | |||
468 | spin_lock_irq(¤t->sighand->siglock); | 459 | spin_lock_irq(¤t->sighand->siglock); |
469 | { | 460 | current->saved_sigmask = current->blocked; |
470 | oldset = current->blocked; | 461 | siginitset(¤t->blocked, mask); |
471 | current->blocked = set; | 462 | recalc_sigpending(); |
472 | recalc_sigpending(); | ||
473 | } | ||
474 | spin_unlock_irq(¤t->sighand->siglock); | 463 | spin_unlock_irq(¤t->sighand->siglock); |
475 | 464 | ||
476 | /* | 465 | current->state = TASK_INTERRUPTIBLE; |
477 | * The return below usually returns to the signal handler. We need to pre-set the | 466 | schedule(); |
478 | * correct error code here to ensure that the right values get saved in sigcontext | 467 | set_thread_flag(TIF_RESTORE_SIGMASK); |
479 | * by ia64_do_signal. | 468 | return -ERESTARTNOHAND; |
480 | */ | ||
481 | scr->pt.r8 = -EINTR; | ||
482 | while (1) { | ||
483 | current->state = TASK_INTERRUPTIBLE; | ||
484 | schedule(); | ||
485 | if (ia64_do_signal(&oldset, scr, 1)) | ||
486 | return -EINTR; | ||
487 | } | ||
488 | } | ||
489 | |||
490 | asmlinkage long | ||
491 | ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr) | ||
492 | { | ||
493 | compat_sigset_t set; | ||
494 | |||
495 | if (sigsetsize > sizeof(compat_sigset_t)) | ||
496 | return -EINVAL; | ||
497 | |||
498 | if (copy_from_user(&set.sig, &uset->sig, sigsetsize)) | ||
499 | return -EFAULT; | ||
500 | |||
501 | return __ia32_rt_sigsuspend(&set, sigsetsize, scr); | ||
502 | } | ||
503 | |||
504 | asmlinkage long | ||
505 | ia32_sigsuspend (unsigned int mask, struct sigscratch *scr) | ||
506 | { | ||
507 | return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr); | ||
508 | } | 469 | } |
509 | 470 | ||
510 | asmlinkage long | 471 | asmlinkage long |