asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
{
	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_restore_sigmask();
	return -ERESTARTNOHAND;
}
/*
 * Atomically swap in the new signal mask, and wait for a signal.  Define
 * dummy arguments to be able to reach the regs argument.  (Note that this
 * arrangement relies on old_sigset_t occupying one register.)
 */
int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
	long srp, struct pt_regs *regs)
{
	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}
Exemple #3
0
/*
 * The OSF/1 sigprocmask calling sequence is different from the
 * C sigprocmask() sequence..
 */
SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask)
{
	sigset_t oldmask;
	sigset_t mask;
	unsigned long res;

	siginitset(&mask, newmask & _BLOCKABLE);
	res = sigprocmask(how, &mask, &oldmask);
	if (!res) {
		force_successful_syscall_return();
		res = oldmask.sig[0];
	}
	return res;
}
Exemple #4
0
static long _sigpause_common(old_sigset_t set)
{
    set &= _BLOCKABLE;
    spin_lock_irq(&current->sighand->siglock);
    current->saved_sigmask = current->blocked;
    siginitset(&current->blocked, set);
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);

    current->state = TASK_INTERRUPTIBLE;
    schedule();
    set_thread_flag(TIF_RESTORE_SIGMASK);
    return -ERESTARTNOHAND;
}
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
{
	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}
Exemple #6
0
/*
 * atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
{
	sigset_t blocked;

	current->saved_sigmask = current->blocked;

	mask &= _BLOCKABLE;
	siginitset(&blocked, mask);
	set_current_blocked(&blocked);

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_restore_sigmask();
	return -ERESTARTNOHAND;
}
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
{
	sigset_t blocked;

	current->saved_sigmask = current->blocked;

	mask &= _BLOCKABLE;
	siginitset(&blocked, mask);
	set_current_blocked(&blocked);

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}
Exemple #8
0
static int context_thread(void *startup)
{
	struct task_struct *curtask = current;
	DECLARE_WAITQUEUE(wait, curtask);
	struct k_sigaction sa;

	daemonize();
	strcpy(curtask->comm, "keventd");
	current->flags |= PF_IOTHREAD;
	keventd_running = 1;
	keventd_task = curtask;

	spin_lock_irq(&curtask->sigmask_lock);
	siginitsetinv(&curtask->blocked, sigmask(SIGCHLD));
	recalc_sigpending(curtask);
	spin_unlock_irq(&curtask->sigmask_lock);

	complete((struct completion *)startup);

	/* Install a handler so SIGCLD is delivered */
	sa.sa.sa_handler = SIG_IGN;
	sa.sa.sa_flags = 0;
	siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
	do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);

	/*
	 * If one of the functions on a task queue re-adds itself
	 * to the task queue we call schedule() in state TASK_RUNNING
	 */
	for (;;) {
		set_task_state(curtask, TASK_INTERRUPTIBLE);
		add_wait_queue(&context_task_wq, &wait);
		if (TQ_ACTIVE(tq_context))
			set_task_state(curtask, TASK_RUNNING);
		schedule();
		remove_wait_queue(&context_task_wq, &wait);
		run_task_queue(&tq_context);
		wake_up(&context_task_done);
		if (signal_pending(curtask)) {
			while (waitpid(-1, (unsigned int *)0, __WALL|WNOHANG) > 0)
				;
			spin_lock_irq(&curtask->sigmask_lock);
			flush_signals(curtask);
			recalc_sigpending(curtask);
			spin_unlock_irq(&curtask->sigmask_lock);
		}
	}
}
asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
{
	sigset_t blocked;

	current->saved_sigmask = current->blocked;

	mask &= _BLOCKABLE;
	siginitset(&blocked, mask);
	set_current_blocked(&blocked);

	current->state = TASK_INTERRUPTIBLE;
	schedule();

	set_restore_sigmask();
	return -ERESTARTNOHAND;
}
Exemple #10
0
static int _sigpause_common(old_sigset_t set)
{
	sigset_t blocked;

	current->saved_sigmask = current->blocked;

	set &= _BLOCKABLE;
	siginitset(&blocked, set);
	set_current_blocked(&blocked);

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);

	return -ERESTARTNOHAND;
}
static long _sigpause_common(old_sigset_t set)
{
	sigset_t blocked;

	current->saved_sigmask = current->blocked;

	set &= _BLOCKABLE;
	siginitset(&blocked, set);
	set_current_blocked(&blocked);

	current->state = TASK_INTERRUPTIBLE;
	schedule();

	set_restore_sigmask();

	return -ERESTARTNOHAND;
}
Exemple #12
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int do_sigsuspend(struct pt_regs *regs)
{
	old_sigset_t mask = regs->dn[0];
	sigset_t saveset;

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	/*
	 * Call common handler
	 */
	return signal_suspend(&saveset, regs);
}
Exemple #13
0
/*
 * atomically swap in the new signal mask, and wait for a signal.
 * This is really tricky on the Sparc, watch out...
 */
asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
{
	sigset_t saveset;

#ifdef CONFIG_SPARC32_COMPAT
	if (current->thread.flags & SPARC_FLAG_32BIT) {
		extern asmlinkage void _sigpause32_common(old_sigset_t32,
							  struct pt_regs *);
		_sigpause32_common(set, regs);
		return;
	}
#endif
	set &= _BLOCKABLE;
	spin_lock_irq(&current->sigmask_lock);
	saveset = current->blocked;
	siginitset(&current->blocked, set);
	recalc_sigpending(current);
	spin_unlock_irq(&current->sigmask_lock);
	
	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
		regs->tpc = (regs->tnpc & 0xffffffff);
		regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
	} else {
		regs->tpc = regs->tnpc;
		regs->tnpc += 4;
	}

	/* Condition codes and return value where set here for sigpause,
	 * and so got used by setup_frame, which again causes sigreturn()
	 * to return -EINTR.
	 */
	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		/*
		 * Return -EINTR and set condition code here,
		 * so the interrupted system call actually returns
		 * these.
		 */
		regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
		regs->u_regs[UREG_I0] = EINTR;
		if (do_signal(&saveset, regs, 0, 0))
			return;
	}
}
Exemple #14
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int do_sigsuspend(struct pt_regs *regs)
{
	old_sigset_t mask = regs->d3;
	sigset_t saveset;

	mask &= _BLOCKABLE;
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();

	regs->d0 = -EINTR;
	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		if (do_signal(&saveset, regs))
			return -EINTR;
	}
}
Exemple #15
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
{
	sigset_t saveset;

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		if(kern_do_signal(&current->thread.regs, &saveset, -EINTR))
			return(-EINTR);
	}
}
Exemple #16
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
sys_sigsuspend(old_sigset_t mask,
	       unsigned long r5, unsigned long r6, unsigned long r7,
	       struct pt_regs __regs)
{
	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_restore_sigmask();

	return -ERESTARTNOHAND;
}
Exemple #17
0
/*
 * atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
{
    sigset_t saveset;

    mask &= _BLOCKABLE;
    spin_lock_irq(&current->sighand->siglock);
    saveset = current->blocked;
    siginitset(&current->blocked, mask);
    recalc_sigpending();
    spin_unlock_irq(&current->sighand->siglock);
    regs->ARM_r0 = -EINTR;

    while (1) {
        current->state = TASK_INTERRUPTIBLE;
        schedule();
        if (do_signal(&saveset, regs, 0))
            return regs->ARM_r0;
    }
}
Exemple #18
0
asmlinkage int
sparc_sigaction (int sig, const struct old_sigaction *act,
		 struct old_sigaction *oact)
{
	struct k_sigaction new_ka, old_ka;
	int ret;

	if (sig < 0) {
		current->thread.new_signal = 1;
		sig = -sig;
	}

	if (act) {
		unsigned long mask;

		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
			return -EFAULT;
		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
		__get_user(mask, &act->sa_mask);
		siginitset(&new_ka.sa.sa_mask, mask);
		new_ka.ka_restorer = NULL;
	}

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

	if (!ret && oact) {
		/* In the clone() case we could copy half consistant
		 * state to the user, however this could sleep and
		 * deadlock us if we held the signal lock on SMP.  So for
		 * now I take the easy way out and do no locking.
		 */
		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
			return -EFAULT;
		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
	}

	return ret;
}
Exemple #19
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
do_sigsuspend(old_sigset_t mask, struct pt_regs *reg, struct switch_stack *sw)
{
    sigset_t oldset;

    mask &= _BLOCKABLE;
    spin_lock_irq(&current->sigmask_lock);
    oldset = current->blocked;
    siginitset(&current->blocked, mask);
    recalc_sigpending(current);
    spin_unlock_irq(&current->sigmask_lock);

    while (1) {
        current->state = TASK_INTERRUPTIBLE;
        schedule();
        if (do_signal(&oldset, reg, sw, 0, 0))
            return -EINTR;
    }
}
Exemple #20
0
asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
                               struct sigaction32 *oact)
{
	struct k_sigaction new_ka, old_ka;
	int ret;
	int err = 0;

	if (act) {
		old_sigset_t mask;
		s32 handler;

		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
			return -EFAULT;
		err |= __get_user(handler, &act->sa_handler);
		new_ka.sa.sa_handler = (__sighandler_t)(s64)handler;
		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
		err |= __get_user(mask, &act->sa_mask.sig[0]);
		if (err)
			return -EFAULT;

		siginitset(&new_ka.sa.sa_mask, mask);
	}

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

	if (!ret && oact) {
		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
                        return -EFAULT;
		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
		                  &oact->sa_handler);
		BUG();
//		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
                err |= __put_user(0, &oact->sa_mask.sig[1]);
                err |= __put_user(0, &oact->sa_mask.sig[2]);
                err |= __put_user(0, &oact->sa_mask.sig[3]);
                if (err)
			return -EFAULT;
	}

	return ret;
}
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
{
	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	/* Indicate EINTR on return from any possible signal handler,
	   which will not come back through here, but via sigreturn.  */
	regs->r0 = EINTR;
	regs->r19 = 1;

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
sys32_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask)
{
	sigset_t saveset;

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
	regs->gprs[2] = -EINTR;

	while (1) {
		set_current_state(TASK_INTERRUPTIBLE);
		schedule();
		if (do_signal(regs, &saveset))
			return -EINTR;
	}
}
int xtensa_sigsuspend(struct pt_regs *regs)
{
	old_sigset_t mask = (old_sigset_t) regs->areg[3];
	sigset_t saveset;

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	regs->areg[2] = -EINTR;
	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		if (do_signal(regs, &saveset))
			return -EINTR;
	}
}
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
{
	sigset_t saveset;

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sigmask_lock);
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending(current);
	spin_unlock_irq(&current->sigmask_lock);

	regs->gpr[GPR_RVAL] = -EINTR;
	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		if (do_signal(regs, &saveset))
			return -EINTR;
	}
}
Exemple #25
0
/*
 * atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
{
	sigset_t saveset;

	printk_dbg("XXX - %s() called\n", __func__);

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
	ARM_put_r0(regs, -ERESTART_RESTARTBLOCK);

	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		if (l4_do_signal(&saveset, regs, 1))
			return ARM_r0(regs);
	}
}
asmlinkage int
sunos_sigaction(int sig, const struct old_sigaction __user *act,
                struct old_sigaction __user *oact)
{
    struct k_sigaction new_ka, old_ka;
    int ret;

    if (act) {
        old_sigset_t mask;

        if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
                __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
                __get_user(new_ka.sa.sa_flags, &act->sa_flags))
            return -EFAULT;
        __get_user(mask, &act->sa_mask);
        new_ka.sa.sa_restorer = NULL;
        new_ka.ka_restorer = NULL;
        siginitset(&new_ka.sa.sa_mask, mask);
        new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
    }

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

    if (!ret && oact) {
        /* In the clone() case we could copy half consistent
         * state to the user, however this could sleep and
         * deadlock us if we held the signal lock on SMP.  So for
         * now I take the easy way out and do no locking.
         * But then again we don't support SunOS lwp's anyways ;-)
         */
        old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
        if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
                __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
                __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
            return -EFAULT;
        __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
    }

    return ret;
}
Exemple #27
0
/*
 * Atomically swap in the new signal mask, and wait for a signal.
 */
asmlinkage int
sys_sigsuspend(old_sigset_t mask,
	       unsigned long r5, unsigned long r6, unsigned long r7,
	       struct pt_regs regs)
{
	sigset_t saveset;

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	saveset = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	regs.regs[0] = -EINTR;
	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		if (do_signal(&regs, &saveset))
			return -EINTR;
	}
}
Exemple #28
0
asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act,
				     struct old_sigaction32 __user *oact)
{
        struct k_sigaction new_ka, old_ka;
        int ret;

	if (sig < 0) {
		set_thread_flag(TIF_NEWSIGNALS);
		sig = -sig;
	}

        if (act) {
		compat_old_sigset_t mask;
		u32 u_handler, u_restorer;
		
		ret = get_user(u_handler, &act->sa_handler);
		new_ka.sa.sa_handler =  compat_ptr(u_handler);
		ret |= __get_user(u_restorer, &act->sa_restorer);
		new_ka.sa.sa_restorer = compat_ptr(u_restorer);
		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
		ret |= __get_user(mask, &act->sa_mask);
		if (ret)
			return ret;
		new_ka.ka_restorer = NULL;
		siginitset(&new_ka.sa.sa_mask, mask);
        }

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

	if (!ret && oact) {
		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
		ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
        }

	return ret;
}
Exemple #29
0
SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act,
	struct sigaction __user *, oact)
{
	struct k_sigaction new_ka, old_ka;
	int ret;
	int err = 0;

	if (act) {
		old_sigset_t mask;

		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
			return -EFAULT;
		err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
		err |= __get_user(mask, &act->sa_mask.sig[0]);
		if (err)
			return -EFAULT;

		siginitset(&new_ka.sa.sa_mask, mask);
	}

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

	if (!ret && oact) {
		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
			return -EFAULT;
		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
		err |= __put_user(0, &oact->sa_mask.sig[1]);
		err |= __put_user(0, &oact->sa_mask.sig[2]);
		err |= __put_user(0, &oact->sa_mask.sig[3]);
		if (err)
			return -EFAULT;
	}

	return ret;
}
Exemple #30
0
long sys_sigaction(int sig, const struct old_sigaction *act,
	      struct old_sigaction *oact)
{
	struct k_sigaction new_ka, old_ka;
	int ret;

        PPCDBG(PPCDBG_SYS64X, "sys_sigaction - running - pid=%ld current=%lx comm=%s \n",
                current->pid, current, current->comm);

 

	if (act) {
		old_sigset_t mask;
		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
			return -EFAULT;
		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
		__get_user(mask, &act->sa_mask);
		siginitset(&new_ka.sa.sa_mask, mask);
	}

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

	if (!ret && oact) {
		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
			return -EFAULT;
		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
	}


 

	return ret;
}