static int handle_signal( unsigned long signum, siginfo_t * siginfo, struct sigaction * sigact, sigset_t * oldset, struct pt_regs * regs ) { int status; unsigned long irqstate; // Did we come here from a system call? if ((long)regs->orig_rax >= 0) { // If so, and if requested, setup to restart the interrupted // system call automatically once the signal handler is finished switch ((long)(int)regs->rax) { case -ERESTARTNOHAND: sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); regs->rax = (unsigned)-EINTR; break; case -ERESTARTSYS: if (!(sigact->sa_flags & SA_RESTART)) { regs->rax = (unsigned)-EINTR; break; } // fallthrough case -ERESTARTNOINTR: regs->rax = regs->orig_rax; regs->rip -= 2; break; } } status = setup_signal_frame(signum, siginfo, sigact, oldset, regs); if (status) { spin_lock_irqsave(¤t->aspace->lock, irqstate); sigset_or(¤t->sigblocked, ¤t->sigblocked, &sigact->sa_mask); if (!(sigact->sa_flags & SA_NODEFER)) sigset_add(¤t->sigblocked, signum); spin_unlock_irqrestore(¤t->aspace->lock, irqstate); } return status; }
sigset_t sigset_xor(sigset_t a, sigset_t b) { sigset_t result; result = sigset_and( sigset_not( sigset_and(a, b)), sigset_or(a, b)); return result; }