int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize) { sigset_t saveset, newset; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) return -EINVAL; if (copy_from_user(&newset, unewset, sizeof(newset))) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); if (kern_do_signal(¤t->thread.regs, &saveset, -EINTR)) return(-EINTR); } }
/* * 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(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); if(kern_do_signal(¤t->thread.regs, &saveset, -EINTR)) return(-EINTR); } }
int do_signal(void) { return kern_do_signal(¤t->thread.regs); }
int do_signal(int error) { return(kern_do_signal(¤t->thread.regs, NULL, error)); }