+ u.u_oldmask = p->p_sigmask;
+ p->p_flag |= SOMASK;
+ p->p_sigmask = uap->mask &~ sigcantmask;
+ (void) tsleep((caddr_t)&u, PPAUSE | PCATCH, "pause", 0);
+ /* always return EINTR rather than ERESTART... */
+ return (EINTR);
+}
+
+/* ARGSUSED */
+sigstack(p, uap, retval)
+ struct proc *p;
+ register struct args {
+ struct sigstack *nss;
+ struct sigstack *oss;
+ } *uap;
+ int *retval;
+{
+ struct sigstack ss;
+ int error = 0;
+
+ if (uap->oss && (error = copyout((caddr_t)&u.u_sigstack,
+ (caddr_t)uap->oss, sizeof (struct sigstack))))
+ return (error);
+ if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
+ sizeof (ss))) == 0)
+ u.u_sigstack = ss;
+ return (error);
+}
+
+/* ARGSUSED */
+kill(cp, uap, retval)
+ register struct proc *cp;
+ register struct args {
+ int pid;
+ int signo;
+ } *uap;
+ int *retval;
+{
+ register struct proc *p;
+
+ if ((unsigned) uap->signo >= NSIG)
+ return (EINVAL);
+ if (uap->pid > 0) {
+ /* kill single process */
+ p = pfind(uap->pid);
+ if (p == 0)
+ return (ESRCH);
+ if (!CANSIGNAL(cp, p, uap->signo))
+ return (EPERM);
+ if (uap->signo)
+ psignal(p, uap->signo);
+ return (0);
+ }
+ switch (uap->pid) {
+ case -1: /* broadcast signal */
+ return (killpg1(cp, uap->signo, 0, 1));
+ case 0: /* signal own process group */
+ return (killpg1(cp, uap->signo, 0, 0));
+ default: /* negative explicit process group */
+ return (killpg1(cp, uap->signo, -uap->pid, 0));
+ }
+ /* NOTREACHED */
+}
+
+#ifdef COMPAT_43
+/* ARGSUSED */
+okillpg(p, uap, retval)
+ struct proc *p;
+ register struct args {
+ int pgid;
+ int signo;
+ } *uap;
+ int *retval;
+{
+
+ if ((unsigned) uap->signo >= NSIG)
+ return (EINVAL);
+ return (killpg1(p, uap->signo, uap->pgid, 0));
+}
+#endif
+
+/*
+ * Common code for kill process group/broadcast kill.
+ * cp is calling process.
+ */
+killpg1(cp, signo, pgid, all)
+ register struct proc *cp;
+ int signo, pgid, all;
+{
+ register struct proc *p;
+ struct pgrp *pgrp;
+ int f = 0;
+
+ if (all)
+ /*
+ * broadcast