+ sig = uap->signo;
+ if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
+ u.u_error = EINVAL;
+ return;
+ }
+ sv = &vec;
+ if (uap->osv) {
+ sv->sv_handler = u.u_signal[sig];
+ sv->sv_mask = u.u_sigmask[sig];
+ bit = sigmask(sig);
+ sv->sv_flags = 0;
+ if ((u.u_sigonstack & bit) != 0)
+ sv->sv_flags |= SV_ONSTACK;
+ if ((u.u_sigintr & bit) != 0)
+ sv->sv_flags |= SV_INTERRUPT;
+ u.u_error =
+ copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec));
+ if (u.u_error)
+ return;
+ }
+ if (uap->nsv) {
+ u.u_error =
+ copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec));
+ if (u.u_error)
+ return;
+ if (sig == SIGCONT && sv->sv_handler == SIG_IGN) {
+ u.u_error = EINVAL;
+ return;
+ }
+ setsigvec(sig, sv);
+ }
+}
+
+setsigvec(sig, sv)
+ int sig;
+ register struct sigvec *sv;
+{
+ register struct proc *p;
+ register int bit;
+
+ bit = sigmask(sig);
+ p = u.u_procp;
+ /*
+ * Change setting atomically.
+ */
+ (void) splhigh();
+ u.u_signal[sig] = sv->sv_handler;
+ u.u_sigmask[sig] = sv->sv_mask &~ cantmask;
+ if (sv->sv_flags & SV_INTERRUPT)
+ u.u_sigintr |= bit;
+ else
+ u.u_sigintr &= ~bit;
+ if (sv->sv_flags & SV_ONSTACK)
+ u.u_sigonstack |= bit;
+ else
+ u.u_sigonstack &= ~bit;
+ if (sv->sv_handler == SIG_IGN) {
+ p->p_sig &= ~bit; /* never to be seen again */
+ p->p_sigignore |= bit;
+ p->p_sigcatch &= ~bit;
+ } else {
+ p->p_sigignore &= ~bit;
+ if (sv->sv_handler == SIG_DFL)
+ p->p_sigcatch &= ~bit;
+ else
+ p->p_sigcatch |= bit;
+ }
+ (void) spl0();