[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>
This commit is contained in:

committed by
Tony Luck

parent
690def2141
commit
4a177cbf84
@@ -41,47 +41,6 @@
|
||||
# define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0])
|
||||
#endif
|
||||
|
||||
long
|
||||
ia64_rt_sigsuspend (sigset_t __user *uset, size_t sigsetsize, struct sigscratch *scr)
|
||||
{
|
||||
sigset_t oldset, set;
|
||||
|
||||
/* XXX: Don't preclude handling different sized sigset_t's. */
|
||||
if (sigsetsize != sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
|
||||
if (!access_ok(VERIFY_READ, uset, sigsetsize))
|
||||
return -EFAULT;
|
||||
|
||||
if (GET_SIGSET(&set, uset))
|
||||
return -EFAULT;
|
||||
|
||||
sigdelsetmask(&set, ~_BLOCKABLE);
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
{
|
||||
oldset = current->blocked;
|
||||
current->blocked = set;
|
||||
recalc_sigpending();
|
||||
}
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
/*
|
||||
* The return below usually returns to the signal handler. We need to
|
||||
* pre-set the correct error code here to ensure that the right values
|
||||
* get saved in sigcontext by ia64_do_signal.
|
||||
*/
|
||||
scr->pt.r8 = EINTR;
|
||||
scr->pt.r10 = -1;
|
||||
|
||||
while (1) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
if (ia64_do_signal(&oldset, scr, 1))
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage long
|
||||
sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
|
||||
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
|
||||
* Note that `init' is a special process: it doesn't get signals it doesn't want to
|
||||
* handle. Thus you cannot kill init even with a SIGKILL even by mistake.
|
||||
*/
|
||||
long
|
||||
ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
|
||||
void
|
||||
ia64_do_signal (struct sigscratch *scr, long in_syscall)
|
||||
{
|
||||
struct k_sigaction ka;
|
||||
sigset_t *oldset;
|
||||
siginfo_t info;
|
||||
long restart = in_syscall;
|
||||
long errno = scr->pt.r8;
|
||||
@@ -493,9 +453,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
|
||||
* doing anything if so.
|
||||
*/
|
||||
if (!user_mode(&scr->pt))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (!oldset)
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else
|
||||
oldset = ¤t->blocked;
|
||||
|
||||
/*
|
||||
@@ -558,8 +520,15 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
|
||||
* Whee! Actually deliver the signal. If the delivery failed, we need to
|
||||
* continue to iterate in this loop so we can deliver the SIGSEGV...
|
||||
*/
|
||||
if (handle_signal(signr, &ka, &info, oldset, scr))
|
||||
return 1;
|
||||
if (handle_signal(signr, &ka, &info, oldset, scr)) {
|
||||
/* a signal was successfully delivered; the saved
|
||||
* sigmask will have been stored in the signal frame,
|
||||
* and will be restored by sigreturn, so we can simply
|
||||
* clear the TIF_RESTORE_SIGMASK flag */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we come from a system call? */
|
||||
@@ -585,5 +554,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
/* if there's no signal to deliver, we just put the saved sigmask
|
||||
* back */
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user