asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
{
    compat_sigset_t __user *unewset;
    compat_sigset_t uset;
    size_t sigsetsize;
    sigset_t newset;

    /* XXX Don't preclude handling different sized sigset_t's.  */
    sigsetsize = regs.regs[5];
    if (sigsetsize != sizeof(sigset_t))
        return -EINVAL;

    unewset = (compat_sigset_t __user *) regs.regs[4];
    if (copy_from_user(&uset, unewset, sizeof(uset)))
        return -EFAULT;
    sigset_from_compat(&newset, &uset);
    sigdelsetmask(&newset, ~_BLOCKABLE);

    spin_lock_irq(&current->sighand->siglock);
    current->saved_sigmask = current->blocked;
    current->blocked = newset;
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);

    current->state = TASK_INTERRUPTIBLE;
    schedule();
    set_thread_flag(TIF_RESTORE_SIGMASK);
    return -ERESTARTNOHAND;
}
Exemplo n.º 2
0
COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
			struct compat_sigaction __user *,act,
			struct compat_sigaction __user *,oact,
			void __user *,restorer,
			compat_size_t,sigsetsize)
{
        struct k_sigaction new_ka, old_ka;
        int ret;
	compat_sigset_t set32;

        /* XXX: Don't preclude handling different sized sigset_t's.  */
        if (sigsetsize != sizeof(compat_sigset_t))
                return -EINVAL;

        if (act) {
		u32 u_handler, u_restorer;

		new_ka.ka_restorer = restorer;
		ret = get_user(u_handler, &act->sa_handler);
		new_ka.sa.sa_handler =  compat_ptr(u_handler);
		ret |= copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));
		sigset_from_compat(&new_ka.sa.sa_mask, &set32);
		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
		ret |= get_user(u_restorer, &act->sa_restorer);
		new_ka.sa.sa_restorer = compat_ptr(u_restorer);
                if (ret)
                	return -EFAULT;
	}

	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

	if (!ret && oact) {
		sigset_to_compat(&set32, &old_ka.sa.sa_mask);
		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
		ret |= copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t));
		ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
		if (ret)
			ret = -EFAULT;
        }

        return ret;
}