+/*
+ * Initialize signal state for process 0;
+ * set to ignore signals that are ignored by default.
+ */
+void
+siginit(p)
+ struct proc *p;
+{
+ register int i;
+
+ for (i = 0; i < NSIG; i++)
+ if (sigprop[i] & SA_IGNORE && i != SIGCONT)
+ p->p_sigignore |= sigmask(i);
+}
+
+/*
+ * Reset signals for an exec of the specified process.
+ */
+void
+execsigs(p)
+ register struct proc *p;
+{
+ register struct sigacts *ps = p->p_sigacts;
+ register int nc, mask;
+
+ /*
+ * Reset caught signals. Held signals remain held
+ * through p_sigmask (unless they were caught,
+ * and are now ignored by default).
+ */
+ while (p->p_sigcatch) {
+ nc = ffs((long)p->p_sigcatch);
+ mask = sigmask(nc);
+ p->p_sigcatch &= ~mask;
+ if (sigprop[nc] & SA_IGNORE) {
+ if (nc != SIGCONT)
+ p->p_sigignore |= mask;
+ p->p_siglist &= ~mask;
+ }
+ ps->ps_sigact[nc] = SIG_DFL;
+ }
+ /*
+ * Reset stack state to the user stack.
+ * Clear set of signals caught on the signal stack.
+ */
+ ps->ps_sigstk.ss_flags = SA_DISABLE;
+ ps->ps_sigstk.ss_size = 0;
+ ps->ps_sigstk.ss_base = 0;
+ ps->ps_flags = 0;
+}
+
+/*
+ * Manipulate signal mask.
+ * Note that we receive new mask, not pointer,
+ * and return old mask as return value;
+ * the library stub does the rest.
+ */
+struct sigprocmask_args {
+ int how;
+ sigset_t mask;
+};
+sigprocmask(p, uap, retval)
+ register struct proc *p;
+ struct sigprocmask_args *uap;
+ int *retval;
+{
+ int error = 0;
+
+ *retval = p->p_sigmask;
+ (void) splhigh();
+
+ switch (uap->how) {
+ case SIG_BLOCK:
+ p->p_sigmask |= uap->mask &~ sigcantmask;
+ break;
+
+ case SIG_UNBLOCK:
+ p->p_sigmask &= ~uap->mask;
+ break;
+
+ case SIG_SETMASK:
+ p->p_sigmask = uap->mask &~ sigcantmask;
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ (void) spl0();
+ return (error);
+}
+
+struct sigpending_args {
+ int dummy;
+};
+/* ARGSUSED */
+sigpending(p, uap, retval)
+ struct proc *p;
+ struct sigpending_args *uap;
+ int *retval;
+{
+
+ *retval = p->p_siglist;
+ return (0);
+}
+
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+/*
+ * Generalized interface signal handler, 4.3-compatible.
+ */
+struct osigvec_args {
+ int signum;
+ struct sigvec *nsv;
+ struct sigvec *osv;
+};
+/* ARGSUSED */
+osigvec(p, uap, retval)
+ struct proc *p;
+ register struct osigvec_args *uap;
+ int *retval;
+{
+ struct sigvec vec;
+ register struct sigacts *ps = p->p_sigacts;
+ register struct sigvec *sv;
+ register int signum;
+ int bit, error;
+
+ signum = uap->signum;
+ if (signum <= 0 || signum >= NSIG ||
+ signum == SIGKILL || signum == SIGSTOP)
+ return (EINVAL);
+ sv = &vec;
+ if (uap->osv) {
+ *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
+ sv->sv_mask = ps->ps_catchmask[signum];
+ bit = sigmask(signum);
+ sv->sv_flags = 0;
+ if ((ps->ps_sigonstack & bit) != 0)
+ sv->sv_flags |= SV_ONSTACK;
+ if ((ps->ps_sigintr & bit) != 0)
+ sv->sv_flags |= SV_INTERRUPT;
+#ifndef COMPAT_SUNOS
+ if (p->p_flag & P_NOCLDSTOP)
+ sv->sv_flags |= SA_NOCLDSTOP;
+#endif
+ if (error = copyout((caddr_t)sv, (caddr_t)uap->osv,
+ sizeof (vec)))
+ return (error);
+ }
+ if (uap->nsv) {
+ if (error = copyin((caddr_t)uap->nsv, (caddr_t)sv,
+ sizeof (vec)))
+ return (error);
+#ifdef COMPAT_SUNOS
+ /*
+ * SunOS uses this bit (4, aka SA_DISABLE) as SV_RESETHAND,
+ * `reset to SIG_DFL on delivery'. We have no such option
+ * now or ever!
+ */
+ if (sv->sv_flags & SA_DISABLE)
+ return (EINVAL);
+ sv->sv_flags |= SA_USERTRAMP;
+#endif
+ sv->sv_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */
+ setsigvec(p, signum, (struct sigaction *)sv);
+ }
+ return (0);
+}
+
+struct osigblock_args {
+ int mask;
+};
+osigblock(p, uap, retval)
+ register struct proc *p;
+ struct osigblock_args *uap;
+ int *retval;