Simplify vn_lock(), VOP_LOCK(), and VOP_UNLOCK() by removing the thread_t
[dragonfly.git] / sys / kern / kern_sig.c
index edc8f58..1ea0029 100644 (file)
  *
  *     @(#)kern_sig.c  8.7 (Berkeley) 4/18/94
  * $FreeBSD: src/sys/kern/kern_sig.c,v 1.72.2.17 2003/05/16 16:34:34 obrien Exp $
- * $DragonFly: src/sys/kern/kern_sig.c,v 1.7 2003/06/27 01:53:25 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_sig.c,v 1.45 2006/05/05 21:15:08 dillon Exp $
  */
 
-#include "opt_compat.h"
 #include "opt_ktrace.h"
 
 #include <sys/param.h>
@@ -52,7 +51,7 @@
 #include <sys/vnode.h>
 #include <sys/event.h>
 #include <sys/proc.h>
-#include <sys/namei.h>
+#include <sys/nlookup.h>
 #include <sys/pioctl.h>
 #include <sys/systm.h>
 #include <sys/acct.h>
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
 #include <sys/unistd.h>
+#include <sys/kern_syscall.h>
+#include <sys/thread2.h>
 
 
 #include <machine/ipl.h>
 #include <machine/cpu.h>
 #include <machine/smp.h>
 
-#define        ONSIG   32              /* NSIG for osig* syscalls.  XXX. */
-
-static int coredump    __P((struct proc *));
-static int do_sigaction        __P((int sig, struct sigaction *act,
-                            struct sigaction *oact, int old));
-static int do_sigprocmask __P((int how, sigset_t *set,
-                              sigset_t *oset, int old));
-static char *expand_name __P((const char *, uid_t, pid_t));
-static int killpg1     __P((int sig, int pgid, int all));
-static int sig_ffs     __P((sigset_t *set));
-static int sigprop     __P((int sig));
-static void stop       __P((struct proc *));
+static int     coredump(struct proc *);
+static char    *expand_name(const char *, uid_t, pid_t);
+static int     killpg(int sig, int pgid, int all);
+static int     sig_ffs(sigset_t *set);
+static int     sigprop(int sig);
+#ifdef SMP
+static void    signotify_remote(void *arg);
+#endif
+static int     kern_sigtimedwait(sigset_t set, siginfo_t *info,
+                   struct timespec *timeout);
 
 static int     filt_sigattach(struct knote *kn);
 static void    filt_sigdetach(struct knote *kn);
@@ -115,7 +114,7 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW,
 
 int sugid_coredump;
 SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, 
-    &sugid_coredump, 0, "Enable coredumping set user/group ID processes");
+       &sugid_coredump, 0, "Enable coredumping set user/group ID processes");
 
 static int     do_coredump = 1;
 SYSCTL_INT(_kern, OID_AUTO, coredump, CTLFLAG_RW,
@@ -133,6 +132,8 @@ SYSCTL_INT(_kern, OID_AUTO, coredump, CTLFLAG_RW,
 #define        SA_IGNORE       0x10            /* ignore by default */
 #define        SA_CONT         0x20            /* continue if suspended */
 #define        SA_CANTMASK     0x40            /* non-maskable, catchable */
+#define SA_CKPT         0x80            /* checkpoint process */
+
 
 static int sigproptbl[NSIG] = {
         SA_KILL,                /* SIGHUP */
@@ -166,6 +167,40 @@ static int sigproptbl[NSIG] = {
         SA_IGNORE,              /* SIGINFO */
         SA_KILL,                /* SIGUSR1 */
         SA_KILL,                /* SIGUSR2 */
+       SA_IGNORE,              /* SIGTHR */
+       SA_CKPT,                /* SIGCKPT */ 
+       SA_KILL|SA_CKPT,        /* SIGCKPTEXIT */  
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+       SA_IGNORE,
+
 };
 
 static __inline int
@@ -188,15 +223,11 @@ sig_ffs(sigset_t *set)
        return (0);
 }
 
-/*
- * do_sigaction
- * sigaction
- * osigaction
- */
-static int
-do_sigaction(int sig, struct sigaction *act, struct sigaction *oact, int old)
+int
+kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact)
 {
-       struct proc *p = curproc;
+       struct thread *td = curthread;
+       struct proc *p = td->td_proc;
        struct sigacts *ps = p->p_sigacts;
 
        if (sig <= 0 || sig > _SIG_MAXSIG)
@@ -229,7 +260,7 @@ do_sigaction(int sig, struct sigaction *act, struct sigaction *oact, int old)
                /*
                 * Change setting atomically.
                 */
-               (void) splhigh();
+               crit_enter();
 
                ps->ps_catchmask[_SIG_IDX(sig)] = act->sa_mask;
                SIG_CANTMASK(ps->ps_catchmask[_SIG_IDX(sig)]);
@@ -257,12 +288,6 @@ do_sigaction(int sig, struct sigaction *act, struct sigaction *oact, int old)
                        SIGADDSET(ps->ps_signodefer, sig);
                else
                        SIGDELSET(ps->ps_signodefer, sig);
-#ifdef COMPAT_SUNOS
-               if (act->sa_flags & SA_USERTRAMP)
-                       SIGADDSET(ps->ps_usertramp, sig);
-               else
-                       SIGDELSET(ps->ps_usertramp, seg);
-#endif
                if (sig == SIGCHLD) {
                        if (act->sa_flags & SA_NOCLDSTOP)
                                p->p_procsig->ps_flag |= PS_NOCLDSTOP;
@@ -279,8 +304,9 @@ do_sigaction(int sig, struct sigaction *act, struct sigaction *oact, int old)
                                        p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
                                else
                                        p->p_procsig->ps_flag |= PS_NOCLDWAIT;
-                       } else
+                       } else {
                                p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
+                       }
                }
                /*
                 * Set bit in p_sigignore for signals that are set to SIG_IGN,
@@ -304,30 +330,17 @@ do_sigaction(int sig, struct sigaction *act, struct sigaction *oact, int old)
                        else
                                SIGADDSET(p->p_sigcatch, sig);
                }
-               if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN ||
-                   ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL || !old)
-                       SIGDELSET(ps->ps_osigset, sig);
-               else
-                       SIGADDSET(ps->ps_osigset, sig);
 
-               (void) spl0();
+               crit_exit();
        }
        return (0);
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct sigaction_args {
-       int     sig;
-       struct  sigaction *act;
-       struct  sigaction *oact;
-};
-#endif
-/* ARGSUSED */
 int
 sigaction(struct sigaction_args *uap)
 {
        struct sigaction act, oact;
-       register struct sigaction *actp, *oactp;
+       struct sigaction *actp, *oactp;
        int error;
 
        actp = (uap->act != NULL) ? &act : NULL;
@@ -337,60 +350,21 @@ sigaction(struct sigaction_args *uap)
                if (error)
                        return (error);
        }
-       error = do_sigaction(uap->sig, actp, oactp, 0);
+       error = kern_sigaction(uap->sig, actp, oactp);
        if (oactp && !error) {
                error = copyout(oactp, uap->oact, sizeof(oact));
        }
        return (error);
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct osigaction_args {
-       int     signum;
-       struct  osigaction *nsa;
-       struct  osigaction *osa;
-};
-#endif
-/* ARGSUSED */
-int
-osigaction(struct osigaction_args *uap)
-{
-       struct osigaction sa;
-       struct sigaction nsa, osa;
-       register struct sigaction *nsap, *osap;
-       int error;
-
-       if (uap->signum <= 0 || uap->signum >= ONSIG)
-               return (EINVAL);
-       nsap = (uap->nsa != NULL) ? &nsa : NULL;
-       osap = (uap->osa != NULL) ? &osa : NULL;
-       if (nsap) {
-               error = copyin(uap->nsa, &sa, sizeof(sa));
-               if (error)
-                       return (error);
-               nsap->sa_handler = sa.sa_handler;
-               nsap->sa_flags = sa.sa_flags;
-               OSIG2SIG(sa.sa_mask, nsap->sa_mask);
-       }
-       error = do_sigaction(uap->signum, nsap, osap, 1);
-       if (osap && !error) {
-               sa.sa_handler = osap->sa_handler;
-               sa.sa_flags = osap->sa_flags;
-               SIG2OSIG(osap->sa_mask, sa.sa_mask);
-               error = copyout(&sa, uap->osa, sizeof(sa));
-       }
-       return (error);
-}
-
 /*
  * Initialize signal state for process 0;
  * set to ignore signals that are ignored by default.
  */
 void
-siginit(p)
-       struct proc *p;
+siginit(struct proc *p)
 {
-       register int i;
+       int i;
 
        for (i = 1; i <= NSIG; i++)
                if (sigprop(i) & SA_IGNORE && i != SIGCONT)
@@ -401,11 +375,10 @@ siginit(p)
  * Reset signals for an exec of the specified process.
  */
 void
-execsigs(p)
-       register struct proc *p;
+execsigs(struct proc *p)
 {
-       register struct sigacts *ps = p->p_sigacts;
-       register int sig;
+       struct sigacts *ps = p->p_sigacts;
+       int sig;
 
        /*
         * Reset caught signals.  Held signals remain held
@@ -437,16 +410,16 @@ execsigs(p)
 }
 
 /*
- * do_sigprocmask() - MP SAFE ONLY IF p == curproc
+ * kern_sigprocmask() - MP SAFE ONLY IF p == curproc
  *
  *     Manipulate signal mask.  This routine is MP SAFE *ONLY* if
- *     p == curproc.  Also remember that in order to remain MP SAFE
- *     no spl*() calls may be made.
+ *     p == curproc.
  */
-static int
-do_sigprocmask(int how, sigset_t *set, sigset_t *oset, int old)
+int
+kern_sigprocmask(int how, sigset_t *set, sigset_t *oset)
 {
-       struct proc *p = curproc;
+       struct thread *td = curthread;
+       struct proc *p = td->td_proc;
        int error;
 
        if (oset != NULL)
@@ -464,10 +437,7 @@ do_sigprocmask(int how, sigset_t *set, sigset_t *oset, int old)
                        break;
                case SIG_SETMASK:
                        SIG_CANTMASK(*set);
-                       if (old)
-                               SIGSETLO(p->p_sigmask, *set);
-                       else
-                               p->p_sigmask = *set;
+                       p->p_sigmask = *set;
                        break;
                default:
                        error = EINVAL;
@@ -480,14 +450,6 @@ do_sigprocmask(int how, sigset_t *set, sigset_t *oset, int old)
 /*
  * sigprocmask() - MP SAFE
  */
-
-#ifndef _SYS_SYSPROTO_H_
-struct sigprocmask_args {
-       int     how;
-       const sigset_t *set;
-       sigset_t *oset;
-};
-#endif
 int
 sigprocmask(struct sigprocmask_args *uap)
 {
@@ -502,178 +464,47 @@ sigprocmask(struct sigprocmask_args *uap)
                if (error)
                        return (error);
        }
-       error = do_sigprocmask(uap->how, setp, osetp, 0);
+       error = kern_sigprocmask(uap->how, setp, osetp);
        if (osetp && !error) {
                error = copyout(osetp, uap->oset, sizeof(oset));
        }
        return (error);
 }
 
-/*
- * osigprocmask() - MP SAFE
- */
-
-#ifndef _SYS_SYSPROTO_H_
-struct osigprocmask_args {
-       int     how;
-       osigset_t mask;
-};
-#endif
-int
-osigprocmask(struct osigprocmask_args *uap)
-{
-       sigset_t set, oset;
-       int error;
-
-       OSIG2SIG(uap->mask, set);
-       error = do_sigprocmask(uap->how, &set, &oset, 1);
-       SIG2OSIG(oset, curproc->p_retval[0]);
-       return (error);
-}
-
-#ifndef _SYS_SYSPROTO_H_
-struct sigpending_args {
-       sigset_t        *set;
-};
-#endif
-/* ARGSUSED */
 int
-sigpending(struct sigpending_args *uap)
+kern_sigpending(struct __sigset *set)
 {
-       struct proc *p = curproc;
+       struct thread *td = curthread;
+       struct proc *p = td->td_proc;
 
-       return (copyout(&p->p_siglist, uap->set, sizeof(sigset_t)));
-}
-
-#ifndef _SYS_SYSPROTO_H_
-struct osigpending_args {
-       int     dummy;
-};
-#endif
-/* ARGSUSED */
-int
-osigpending(struct osigpending_args *uap)
-{
-       struct proc *p = curproc;
+       *set = p->p_siglist;
 
-       SIG2OSIG(p->p_siglist, p->p_retval[0]);
        return (0);
 }
 
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-/*
- * Generalized interface signal handler, 4.3-compatible.
- */
-#ifndef _SYS_SYSPROTO_H_
-struct osigvec_args {
-       int     signum;
-       struct  sigvec *nsv;
-       struct  sigvec *osv;
-};
-#endif
-/* ARGSUSED */
 int
-osigvec(struct osigvec_args *uap)
-{
-       struct sigvec vec;
-       struct sigaction nsa, osa;
-       register struct sigaction *nsap, *osap;
-       int error;
-
-       if (uap->signum <= 0 || uap->signum >= ONSIG)
-               return (EINVAL);
-       nsap = (uap->nsv != NULL) ? &nsa : NULL;
-       osap = (uap->osv != NULL) ? &osa : NULL;
-       if (nsap) {
-               error = copyin(uap->nsv, &vec, sizeof(vec));
-               if (error)
-                       return (error);
-               nsap->sa_handler = vec.sv_handler;
-               OSIG2SIG(vec.sv_mask, nsap->sa_mask);
-               nsap->sa_flags = vec.sv_flags;
-               nsap->sa_flags ^= SA_RESTART;   /* opposite of SV_INTERRUPT */
-#ifdef COMPAT_SUNOS
-               nsap->sa_flags |= SA_USERTRAMP;
-#endif
-       }
-       error = do_sigaction(uap->signum, nsap, osap, 1);
-       if (osap && !error) {
-               vec.sv_handler = osap->sa_handler;
-               SIG2OSIG(osap->sa_mask, vec.sv_mask);
-               vec.sv_flags = osap->sa_flags;
-               vec.sv_flags &= ~SA_NOCLDWAIT;
-               vec.sv_flags ^= SA_RESTART;
-#ifdef COMPAT_SUNOS
-               vec.sv_flags &= ~SA_NOCLDSTOP;
-#endif
-               error = copyout(&vec, uap->osv, sizeof(vec));
-       }
-       return (error);
-}
-
-#ifndef _SYS_SYSPROTO_H_
-struct osigblock_args {
-       int     mask;
-};
-#endif
-int
-osigblock(struct osigblock_args *uap)
+sigpending(struct sigpending_args *uap)
 {
-       struct proc *p = curproc;
        sigset_t set;
+       int error;
 
-       OSIG2SIG(uap->mask, set);
-       SIG_CANTMASK(set);
-       (void) splhigh();
-       SIG2OSIG(p->p_sigmask, p->p_retval[0]);
-       SIGSETOR(p->p_sigmask, set);
-       (void) spl0();
-       return (0);
-}
-
-#ifndef _SYS_SYSPROTO_H_
-struct osigsetmask_args {
-       int     mask;
-};
-#endif
-int
-osigsetmask(struct osigsetmask_args *uap)
-{
-       struct proc *p = curproc;
-       sigset_t set;
+       error = kern_sigpending(&set);
 
-       OSIG2SIG(uap->mask, set);
-       SIG_CANTMASK(set);
-       (void) splhigh();
-       SIG2OSIG(p->p_sigmask, p->p_retval[0]);
-       SIGSETLO(p->p_sigmask, set);
-       (void) spl0();
-       return (0);
+       if (error == 0)
+               error = copyout(&set, uap->set, sizeof(set));
+       return (error);
 }
-#endif /* COMPAT_43 || COMPAT_SUNOS */
 
 /*
  * Suspend process until signal, providing mask to be set
- * in the meantime.  Note nonstandard calling convention:
- * libc stub passes mask, not pointer, to save a copyin.
+ * in the meantime.
  */
-#ifndef _SYS_SYSPROTO_H_
-struct sigsuspend_args {
-       const sigset_t *sigmask;
-};
-#endif
-/* ARGSUSED */
 int
-sigsuspend(struct sigsuspend_args *uap)
+kern_sigsuspend(struct __sigset *set)
 {
-       struct proc *p = curproc;
-       sigset_t mask;
+       struct thread *td = curthread;
+       struct proc *p = td->td_proc;
        struct sigacts *ps = p->p_sigacts;
-       int error;
-
-       error = copyin(uap->sigmask, &mask, sizeof(mask));
-       if (error)
-               return (error);
 
        /*
         * When returning from sigsuspend, we want
@@ -685,122 +516,99 @@ sigsuspend(struct sigsuspend_args *uap)
        p->p_oldsigmask = p->p_sigmask;
        p->p_flag |= P_OLDMASK;
 
-       SIG_CANTMASK(mask);
-       p->p_sigmask = mask;
-       while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
+       SIG_CANTMASK(*set);
+       p->p_sigmask = *set;
+       while (tsleep(ps, PCATCH, "pause", 0) == 0)
                /* void */;
        /* always return EINTR rather than ERESTART... */
        return (EINTR);
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct osigsuspend_args {
-       osigset_t mask;
-};
-#endif
-/* ARGSUSED */
+/*
+ * Note nonstandard calling convention: libc stub passes mask, not
+ * pointer, to save a copyin.
+ */
 int
-osigsuspend(struct osigsuspend_args *uap)
+sigsuspend(struct sigsuspend_args *uap)
 {
        sigset_t mask;
-       struct proc *p = curproc;
-       struct sigacts *ps = p->p_sigacts;
+       int error;
 
-       p->p_oldsigmask = p->p_sigmask;
-       p->p_flag |= P_OLDMASK;
-       OSIG2SIG(uap->mask, mask);
-       SIG_CANTMASK(mask);
-       SIGSETLO(p->p_sigmask, mask);
-       while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "opause", 0) == 0)
-               /* void */;
-       /* always return EINTR rather than ERESTART... */
-       return (EINTR);
+       error = copyin(uap->sigmask, &mask, sizeof(mask));
+       if (error)
+               return (error);
+
+       error = kern_sigsuspend(&mask);
+
+       return (error);
 }
 
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-#ifndef _SYS_SYSPROTO_H_
-struct osigstack_args {
-       struct  sigstack *nss;
-       struct  sigstack *oss;
-};
-#endif
-/* ARGSUSED */
 int
-osigstack(struct osigstack_args *uap)
+kern_sigaltstack(struct sigaltstack *ss, struct sigaltstack *oss)
 {
-       struct proc *p = curproc;
-       struct sigstack ss;
-       int error = 0;
+       struct thread *td = curthread;
+       struct proc *p = td->td_proc;
 
-       ss.ss_sp = p->p_sigstk.ss_sp;
-       ss.ss_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
-       if (uap->oss && (error = copyout(&ss, uap->oss,
-           sizeof(struct sigstack))))
-               return (error);
-       if (uap->nss && (error = copyin(uap->nss, &ss, sizeof(ss))) == 0) {
-               p->p_sigstk.ss_sp = ss.ss_sp;
-               p->p_sigstk.ss_size = 0;
-               p->p_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK;
-               p->p_flag |= P_ALTSTACK;
+       if ((p->p_flag & P_ALTSTACK) == 0)
+               p->p_sigstk.ss_flags |= SS_DISABLE;
+
+       if (oss)
+               *oss = p->p_sigstk;
+
+       if (ss) {
+               if (ss->ss_flags & SS_DISABLE) {
+                       if (p->p_sigstk.ss_flags & SS_ONSTACK)
+                               return (EINVAL);
+                       p->p_flag &= ~P_ALTSTACK;
+                       p->p_sigstk.ss_flags = ss->ss_flags;
+               } else {
+                       if (ss->ss_size < p->p_sysent->sv_minsigstksz)
+                               return (ENOMEM);
+                       p->p_flag |= P_ALTSTACK;
+                       p->p_sigstk = *ss;
+               }
        }
-       return (error);
+
+       return (0);
 }
-#endif /* COMPAT_43 || COMPAT_SUNOS */
 
-#ifndef _SYS_SYSPROTO_H_
-struct sigaltstack_args {
-       stack_t *ss;
-       stack_t *oss;
-};
-#endif
-/* ARGSUSED */
 int
 sigaltstack(struct sigaltstack_args *uap)
 {
-       struct proc *p = curproc;
-       stack_t ss;
+       stack_t ss, oss;
        int error;
 
-       if ((p->p_flag & P_ALTSTACK) == 0)
-               p->p_sigstk.ss_flags |= SS_DISABLE;
-       if (uap->oss && (error = copyout(&p->p_sigstk, uap->oss,
-           sizeof(stack_t))))
-               return (error);
-       if (uap->ss == 0)
-               return (0);
-       if ((error = copyin(uap->ss, &ss, sizeof(ss))))
-               return (error);
-       if (ss.ss_flags & SS_DISABLE) {
-               if (p->p_sigstk.ss_flags & SS_ONSTACK)
-                       return (EINVAL);
-               p->p_flag &= ~P_ALTSTACK;
-               p->p_sigstk.ss_flags = ss.ss_flags;
-               return (0);
+       if (uap->ss) {
+               error = copyin(uap->ss, &ss, sizeof(ss));
+               if (error)
+                       return (error);
        }
-       if (ss.ss_size < p->p_sysent->sv_minsigstksz)
-               return (ENOMEM);
-       p->p_flag |= P_ALTSTACK;
-       p->p_sigstk = ss;
-       return (0);
+
+       error = kern_sigaltstack(uap->ss ? &ss : NULL,
+           uap->oss ? &oss : NULL);
+
+       if (error == 0 && uap->oss)
+               error = copyout(&oss, uap->oss, sizeof(*uap->oss));
+       return (error);
 }
 
 /*
  * Common code for kill process group/broadcast kill.
  * cp is calling process.
  */
-int
-killpg1(int sig, int pgid, int all)
+static int
+killpg(int sig, int pgid, int all)
 {
        struct proc *cp = curproc;
        struct proc *p;
        struct pgrp *pgrp;
        int nfound = 0;
 
-       if (all)
+       if (all) {
                /*
                 * broadcast
                 */
-               LIST_FOREACH(p, &allproc, p_list) {
+               FOREACH_PROC_IN_SYSTEM(p) {
                        if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
                            p == cp || !CANSIGNAL(p, sig))
                                continue;
@@ -808,22 +616,23 @@ killpg1(int sig, int pgid, int all)
                        if (sig)
                                psignal(p, sig);
                }
-       else {
-               if (pgid == 0)
+       else {
+               if (pgid == 0) {
                        /*
                         * zero pgid means send to my process group.
                         */
                        pgrp = cp->p_pgrp;
-               else {
+               else {
                        pgrp = pgfind(pgid);
                        if (pgrp == NULL)
                                return (ESRCH);
                }
                LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
-                       if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
-                           p->p_stat == SZOMB ||
-                           !CANSIGNAL(p, sig))
+                       if (p->p_pid <= 1 || 
+                           (p->p_flag & (P_SYSTEM | P_ZOMBIE)) ||
+                           !CANSIGNAL(p, sig)) {
                                continue;
+                       }
                        nfound++;
                        if (sig)
                                psignal(p, sig);
@@ -832,57 +641,44 @@ killpg1(int sig, int pgid, int all)
        return (nfound ? 0 : ESRCH);
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct kill_args {
-       int     pid;
-       int     signum;
-};
-#endif
-/* ARGSUSED */
 int
-kill(struct kill_args *uap)
+kern_kill(int sig, int pid)
 {
-       struct proc *p;
+       struct thread *td = curthread;
+       struct proc *p = td->td_proc;
 
-       if ((u_int)uap->signum > _SIG_MAXSIG)
+       if ((u_int)sig > _SIG_MAXSIG)
                return (EINVAL);
-       if (uap->pid > 0) {
+       if (pid > 0) {
                /* kill single process */
-               if ((p = pfind(uap->pid)) == NULL)
+               if ((p = pfind(pid)) == NULL)
                        return (ESRCH);
-               if (!CANSIGNAL(p, uap->signum))
+               if (!CANSIGNAL(p, sig))
                        return (EPERM);
-               if (uap->signum)
-                       psignal(p, uap->signum);
+               if (sig)
+                       psignal(p, sig);
                return (0);
        }
-       switch (uap->pid) {
+       switch (pid) {
        case -1:                /* broadcast signal */
-               return (killpg1(uap->signum, 0, 1));
+               return (killpg(sig, 0, 1));
        case 0:                 /* signal own process group */
-               return (killpg1(uap->signum, 0, 0));
+               return (killpg(sig, 0, 0));
        default:                /* negative explicit process group */
-               return (killpg1(uap->signum, -uap->pid, 0));
+               return (killpg(sig, -pid, 0));
        }
        /* NOTREACHED */
 }
 
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-#ifndef _SYS_SYSPROTO_H_
-struct okillpg_args {
-       int     pgid;
-       int     signum;
-};
-#endif
-/* ARGSUSED */
 int
-okillpg(struct okillpg_args *uap)
+kill(struct kill_args *uap)
 {
-       if ((u_int)uap->signum > _SIG_MAXSIG)
-               return (EINVAL);
-       return (killpg1(uap->signum, uap->pgid, 0));
+       int error;
+
+       error = kern_kill(uap->signum, uap->pid);
+
+       return (error);
 }
-#endif /* COMPAT_43 || COMPAT_SUNOS */
 
 /*
  * Send a signal to a process group.
@@ -901,11 +697,9 @@ gsignal(int pgid, int sig)
  * limit to members which have a controlling terminal.
  */
 void
-pgsignal(pgrp, sig, checkctty)
-       struct pgrp *pgrp;
-       int sig, checkctty;
+pgsignal(struct pgrp *pgrp, int sig, int checkctty)
 {
-       register struct proc *p;
+       struct proc *p;
 
        if (pgrp)
                LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
@@ -919,10 +713,7 @@ pgsignal(pgrp, sig, checkctty)
  * Otherwise, post it normally.
  */
 void
-trapsignal(p, sig, code)
-       struct proc *p;
-       register int sig;
-       u_long code;
+trapsignal(struct proc *p, int sig, u_long code)
 {
        struct sigacts *ps = p->p_sigacts;
 
@@ -941,7 +732,7 @@ trapsignal(p, sig, code)
                        SIGADDSET(p->p_sigmask, sig);
                if (SIGISMEMBER(ps->ps_sigreset, sig)) {
                        /*
-                        * See do_sigaction() for origin of this code.
+                        * See kern_sigaction() for origin of this code.
                         */
                        SIGDELSET(p->p_sigcatch, sig);
                        if (sig != SIGCONT &&
@@ -970,21 +761,20 @@ trapsignal(p, sig, code)
  * Other ignored signals are discarded immediately.
  */
 void
-psignal(p, sig)
-       register struct proc *p;
-       register int sig;
+psignal(struct proc *p, int sig)
 {
-       register int s, prop;
-       register sig_t action;
+       struct lwp *lp = &p->p_lwp;
+       int prop;
+       sig_t action;
 
        if (sig > _SIG_MAXSIG || sig <= 0) {
                printf("psignal: signal %d\n", sig);
                panic("psignal signal number");
        }
 
-       s = splhigh();
+       crit_enter();
        KNOTE(&p->p_klist, NOTE_SIGNAL | sig);
-       splx(s);
+       crit_exit();
 
        prop = sigprop(sig);
 
@@ -993,9 +783,9 @@ psignal(p, sig)
         * if signal event is tracked by procfs, give *that*
         * a chance, as well.
         */
-       if ((p->p_flag & P_TRACED) || (p->p_stops & S_SIG))
+       if ((p->p_flag & P_TRACED) || (p->p_stops & S_SIG)) {
                action = SIG_DFL;
-       else {
+       else {
                /*
                 * If the signal is being ignored,
                 * then we forget about it immediately.
@@ -1014,12 +804,16 @@ psignal(p, sig)
        }
 
        if (p->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) &&
-           (p->p_flag & P_TRACED) == 0)
+           (p->p_flag & P_TRACED) == 0) {
                p->p_nice = NZERO;
+       }
 
+       /*
+        * If continuing, clear any pending STOP signals.
+        */
        if (prop & SA_CONT)
                SIG_STOPSIGMASK(p->p_siglist);
-
+       
        if (prop & SA_STOP) {
                /*
                 * If sending a tty stop signal to a member of an orphaned
@@ -1028,8 +822,9 @@ psignal(p, sig)
                 * and don't clear any pending SIGCONT.
                 */
                if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0 &&
-                   action == SIG_DFL)
+                   action == SIG_DFL) {
                        return;
+               }
                SIG_CONTSIGMASK(p->p_siglist);
        }
        SIGADDSET(p->p_siglist, sig);
@@ -1038,75 +833,111 @@ psignal(p, sig)
         * Defer further processing for signals which are held,
         * except that stopped processes must be continued by SIGCONT.
         */
-       if (action == SIG_HOLD && (!(prop & SA_CONT) || p->p_stat != SSTOP))
-               return;
-       s = splhigh();
-       switch (p->p_stat) {
+       if (action == SIG_HOLD) {
+               if ((prop & SA_CONT) == 0 || (p->p_flag & P_STOPPED) == 0)
+                       return;
+       }
 
-       case SSLEEP:
+       crit_enter();
+
+       /*
+        * Process is in tsleep and not stopped
+        */
+       if (p->p_stat == SSLEEP && (p->p_flag & P_STOPPED) == 0) {
                /*
-                * If process is sleeping uninterruptibly
+                * If the process is sleeping uninterruptibly
                 * we can't interrupt the sleep... the signal will
                 * be noticed when the process returns through
                 * trap() or syscall().
                 */
                if ((p->p_flag & P_SINTR) == 0)
                        goto out;
+
                /*
-                * Process is sleeping and traced... make it runnable
+                * If the process is sleeping and traced, make it runnable
                 * so it can discover the signal in issignal() and stop
                 * for the parent.
+                *
+                * If the process is stopped and traced, no further action
+                * is necessary.
                 */
                if (p->p_flag & P_TRACED)
                        goto run;
+
                /*
-                * If SIGCONT is default (or ignored) and process is
-                * asleep, we are finished; the process should not
-                * be awakened.
+                * If the process is sleeping and SA_CONT, and the signal
+                * mode is SIG_DFL, then make the process runnable.
+                *
+                * However, do *NOT* set P_BREAKTSLEEP.  We do not want 
+                * a SIGCONT to terminate an interruptable tsleep early
+                * and generate a spurious EINTR.
                 */
                if ((prop & SA_CONT) && action == SIG_DFL) {
                        SIGDELSET(p->p_siglist, sig);
-                       goto out;
+                       goto run_no_break;
                }
+
                /*
-                * When a sleeping process receives a stop
-                * signal, process immediately if possible.
-                * All other (caught or default) signals
-                * cause the process to run.
+                * If the process is sleeping and receives a STOP signal,
+                * process immediately if possible.  All other (caught or
+                * default) signals cause the process to run.
                 */
                if (prop & SA_STOP) {
                        if (action != SIG_DFL)
-                               goto runfast;
+                               goto run;
+
                        /*
-                        * If a child holding parent blocked,
-                        * stopping could cause deadlock.
+                        * If a child holding parent blocked, stopping 
+                        * could cause deadlock.  Take no action at this
+                        * time.
                         */
                        if (p->p_flag & P_PPWAIT)
                                goto out;
+
+                       /*
+                        * Do not actually try to manipulate the process
+                        * while it is sleeping, simply set P_STOPPED to
+                        * indicate that it should stop as soon as it safely
+                        * can.
+                        */
                        SIGDELSET(p->p_siglist, sig);
+                       p->p_flag |= P_STOPPED;
+                       p->p_flag &= ~P_WAITED;
                        p->p_xstat = sig;
+                       wakeup(p->p_pptr);
                        if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0)
                                psignal(p->p_pptr, SIGCHLD);
-                       stop(p);
                        goto out;
-               } else
-                       goto runfast;
-               /*NOTREACHED*/
+               }
 
-       case SSTOP:
                /*
-                * If traced process is already stopped,
-                * then no further action is necessary.
+                * Otherwise the signal can interrupt the sleep.
+                */
+               goto run;
+       }
+
+       /*
+        * Process is in tsleep and is stopped
+        */
+       if (p->p_stat == SSLEEP && (p->p_flag & P_STOPPED)) {
+               /*
+                * If the process is stopped and is being traced, then no
+                * further action is necessary.
                 */
                if (p->p_flag & P_TRACED)
                        goto out;
 
                /*
-                * Kill signal always sets processes running.
+                * If the process is stopped and receives a KILL signal,
+                * make the process runnable.
                 */
                if (sig == SIGKILL)
-                       goto runfast;
+                       goto run;
 
+               /*
+                * If the process is stopped and receives a CONT signal,
+                * then try to make the process runnable again.
+                */
                if (prop & SA_CONT) {
                        /*
                         * If SIGCONT is default (or ignored), we continue the
@@ -1114,65 +945,284 @@ psignal(p, sig)
                         * it has no further action.  If SIGCONT is held, we
                         * continue the process and leave the signal in
                         * p_siglist.  If the process catches SIGCONT, let it
-                        * handle the signal itself.  If it isn't waiting on
-                        * an event, then it goes back to run state.
-                        * Otherwise, process goes back to sleep state.
+                        * handle the signal itself.
                         */
                        if (action == SIG_DFL)
                                SIGDELSET(p->p_siglist, sig);
                        if (action == SIG_CATCH)
-                               goto runfast;
-                       if (p->p_wchan == 0)
                                goto run;
-                       p->p_stat = SSLEEP;
-                       goto out;
-               }
 
-               if (prop & SA_STOP) {
                        /*
-                        * Already stopped, don't need to stop again.
-                        * (If we did the shell could get confused.)
+                        * Make runnable but do not break a tsleep unless
+                        * some other signal was pending.
                         */
+                       goto run_no_break;
+               }
+
+               /*
+                * If the process is stopped and receives another STOP
+                * signal, we do not need to stop it again.  If we did
+                * the shell could get confused.
+                */
+               if (prop & SA_STOP) {
                        SIGDELSET(p->p_siglist, sig);
                        goto out;
                }
 
                /*
-                * If process is sleeping interruptibly, then simulate a
-                * wakeup so that when it is continued, it will be made
-                * runnable and can look at the signal.  But don't make
-                * the process runnable, leave it stopped.
+                * Otherwise the process is sleeping interruptably but
+                * is stopped, just set the P_BREAKTSLEEP flag and take
+                * no further action.  The next runnable action will wake
+                * the process up.
                 */
-               if (p->p_wchan && (p->p_flag & P_SINTR))
-                       unsleep(p->p_thread);
+               p->p_flag |= P_BREAKTSLEEP;
                goto out;
+       }
+
+       /*
+        * Otherwise the process is running
+        *
+        * SRUN, SIDL, SZOMB do nothing with the signal,
+        * other than kicking ourselves if we are running.
+        * It will either never be noticed, or noticed very soon.
+        *
+        * Note that p_thread may be NULL or may not be completely
+        * initialized if the process is in the SIDL or SZOMB state.
+        *
+        * For SMP we may have to forward the request to another cpu.
+        * YYY the MP lock prevents the target process from moving
+        * to another cpu, see kern/kern_switch.c
+        *
+        * If the target thread is waiting on its message port,
+        * wakeup the target thread so it can check (or ignore)
+        * the new signal.  YYY needs cleanup.
+        */
+       if (lp == lwkt_preempted_proc()) {
+               signotify();
+       } else if (p->p_stat == SRUN) {
+               struct thread *td = p->p_thread;
+
+               KASSERT(td != NULL, 
+                   ("pid %d NULL p_thread stat %d flags %08x",
+                   p->p_pid, p->p_stat, p->p_flag));
 
-       default:
-               /*
-                * SRUN, SIDL, SZOMB do nothing with the signal,
-                * other than kicking ourselves if we are running.
-                * It will either never be noticed, or noticed very soon.
-                */
-               if (p == curproc)
-                       signotify(p);
 #ifdef SMP
-               else if (p->p_stat == SRUN)
-                       forward_signal(p);
+               if (td->td_gd != mycpu)
+                       lwkt_send_ipiq(td->td_gd, signotify_remote, lp);
+               else
 #endif
-               goto out;
+               if (td->td_msgport.mp_flags & MSGPORTF_WAITING)
+                       lwkt_schedule(td);
        }
+       goto out;
        /*NOTREACHED*/
-
-runfast:
+run:
        /*
-        * Raise priority to at least PUSER.
+        * Make runnable and break out of any tsleep as well.
         */
-       if (p->p_priority > PUSER)
-               p->p_priority = PUSER;
-run:
+       p->p_flag |= P_BREAKTSLEEP;
+run_no_break:
        setrunnable(p);
 out:
-       splx(s);
+       crit_exit();
+}
+
+#ifdef SMP
+
+/*
+ * This function is called via an IPI.  We will be in a critical section but
+ * the MP lock will NOT be held.  Also note that by the time the ipi message
+ * gets to us the process 'p' (arg) may no longer be scheduled or even valid.
+ */
+static void
+signotify_remote(void *arg)
+{
+       struct lwp *lp = arg;
+
+       if (lp == lwkt_preempted_proc()) {
+               signotify();
+       } else {
+               struct thread *td = lp->lwp_thread;
+               if (td->td_msgport.mp_flags & MSGPORTF_WAITING)
+                       lwkt_schedule(td);
+       }
+}
+
+#endif
+
+static int
+kern_sigtimedwait(sigset_t waitset, siginfo_t *info, struct timespec *timeout)
+{
+       sigset_t savedmask, set;
+       struct proc *p = curproc;
+       int error, sig, hz, timevalid = 0;
+       struct timespec rts, ets, ts;
+       struct timeval tv;
+
+       error = 0;
+       sig = 0;
+       SIG_CANTMASK(waitset);
+       savedmask = p->p_sigmask;
+
+       if (timeout) {
+               if (timeout->tv_sec >= 0 && timeout->tv_nsec >= 0 &&
+                   timeout->tv_nsec < 1000000000) {
+                       timevalid = 1;
+                       getnanouptime(&rts);
+                       ets = rts;
+                       timespecadd(&ets, timeout);
+               }
+       }
+
+       for (;;) {
+               set = p->p_siglist;
+               SIGSETAND(set, waitset);
+               if ((sig = sig_ffs(&set)) != 0) {
+                       SIGFILLSET(p->p_sigmask);
+                       SIGDELSET(p->p_sigmask, sig);
+                       SIG_CANTMASK(p->p_sigmask);
+                       sig = issignal(p);
+                       /*
+                        * It may be a STOP signal, in the case, issignal
+                        * returns 0, because we may stop there, and new
+                        * signal can come in, we should restart if we got
+                        * nothing.
+                        */
+                       if (sig == 0)
+                               continue;
+                       else
+                               break;
+               }
+
+               /*
+                * Previous checking got nothing, and we retried but still
+                * got nothing, we should return the error status.
+                */
+               if (error)
+                       break;
+
+               /*
+                * POSIX says this must be checked after looking for pending
+                * signals.
+                */
+               if (timeout) {
+                       if (!timevalid) {
+                               error = EINVAL;
+                               break;
+                       }
+                       getnanouptime(&rts);
+                       if (timespeccmp(&rts, &ets, >=)) {
+                               error = EAGAIN;
+                               break;
+                       }
+                       ts = ets;
+                       timespecsub(&ts, &rts);
+                       TIMESPEC_TO_TIMEVAL(&tv, &ts);
+                       hz = tvtohz_high(&tv);
+               } else
+                       hz = 0;
+
+               p->p_sigmask = savedmask;
+               SIGSETNAND(p->p_sigmask, waitset);
+               error = tsleep(&p->p_sigacts, PCATCH, "sigwt", hz);
+               if (timeout) {
+                       if (error == ERESTART) {
+                               /* can not restart a timeout wait. */
+                               error = EINTR;
+                       } else if (error == EAGAIN) {
+                               /* will calculate timeout by ourself. */
+                               error = 0;
+                       }
+               }
+               /* Retry ... */
+       }
+
+       p->p_sigmask = savedmask;
+       if (sig) {
+               error = 0;
+               bzero(info, sizeof(*info));
+               info->si_signo = sig;
+               SIGDELSET(p->p_siglist, sig);   /* take the signal! */
+
+               if (sig == SIGKILL)
+                       sigexit(p, sig);
+       }
+       return (error);
+}
+
+int
+sigtimedwait(struct sigtimedwait_args *uap)
+{
+       struct timespec ts;
+       struct timespec *timeout;
+       sigset_t set;
+       siginfo_t info;
+       int error;
+
+       if (uap->timeout) {
+               error = copyin(uap->timeout, &ts, sizeof(ts));
+               if (error)
+                       return (error);
+               timeout = &ts;
+       } else {
+               timeout = NULL;
+       }
+       error = copyin(uap->set, &set, sizeof(set));
+       if (error)
+               return (error);
+       error = kern_sigtimedwait(set, &info, timeout);
+       if (error)
+               return (error);
+       if (uap->info)
+               error = copyout(&info, uap->info, sizeof(info));
+       /* Repost if we got an error. */
+       if (error)
+               psignal(curproc, info.si_signo);
+       else
+               uap->sysmsg_result = info.si_signo;
+       return (error);
+}
+
+int
+sigwaitinfo(struct sigwaitinfo_args *uap)
+{
+       siginfo_t info;
+       sigset_t set;
+       int error;
+
+       error = copyin(uap->set, &set, sizeof(set));
+       if (error)
+               return (error);
+       error = kern_sigtimedwait(set, &info, NULL);
+       if (error)
+               return (error);
+       if (uap->info)
+               error = copyout(&info, uap->info, sizeof(info));
+       /* Repost if we got an error. */
+       if (error)
+               psignal(curproc, info.si_signo);
+       else
+               uap->sysmsg_result = info.si_signo;
+       return (error);
+}
+
+/*
+ * If the current process has received a signal that would interrupt a
+ * system call, return EINTR or ERESTART as appropriate.
+ */
+int
+iscaught(struct proc *p)
+{
+       int sig;
+
+       if (p) {
+               if ((sig = CURSIG(p)) != 0) {
+                       if (SIGISMEMBER(p->p_sigacts->ps_sigintr, sig))
+                               return (EINTR);                        
+                       return (ERESTART);     
+               }                         
+       }
+       return(EWOULDBLOCK);
 }
 
 /*
@@ -1184,16 +1234,19 @@ out:
  * by checking the pending signal masks in the CURSIG macro.) The normal call
  * sequence is
  *
+ * This routine is called via CURSIG/__cursig and the MP lock might not be
+ * held.  Obtain the MP lock for the duration of the operation.
+ *
  *     while (sig = CURSIG(curproc))
  *             postsig(sig);
  */
 int
-issignal(p)
-       register struct proc *p;
+issignal(struct proc *p)
 {
        sigset_t mask;
-       register int sig, prop;
+       int sig, prop;
 
+       get_mplock();
        for (;;) {
                int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG);
 
@@ -1201,8 +1254,10 @@ issignal(p)
                SIGSETNAND(mask, p->p_sigmask);
                if (p->p_flag & P_PPWAIT)
                        SIG_STOPSIGMASK(mask);
-               if (!SIGNOTEMPTY(mask))         /* no signal to send */
+               if (!SIGNOTEMPTY(mask)) {       /* no signal to send */
+                       rel_mplock();
                        return (0);
+               }
                sig = sig_ffs(&mask);
 
                STOPEVENT(p, S_SIG, sig);
@@ -1215,18 +1270,24 @@ issignal(p)
                        SIGDELSET(p->p_siglist, sig);
                        continue;
                }
-               if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
+               if ((p->p_flag & P_TRACED) && (p->p_flag & P_PPWAIT) == 0) {
                        /*
-                        * If traced, always stop, and stay
-                        * stopped until released by the parent.
+                        * If traced, always stop, and stay stopped until
+                        * released by the parent.
+                        *
+                        * NOTE: P_STOPPED may get cleared during the loop,
+                        * but we do not re-notify the parent if we have 
+                        * to loop several times waiting for the parent
+                        * to let us continue.
                         */
                        p->p_xstat = sig;
+                       p->p_flag |= P_STOPPED;
+                       p->p_flag &= ~P_WAITED;
                        psignal(p->p_pptr, SIGCHLD);
                        do {
-                               stop(p);
-                               mi_switch();
-                       } while (!trace_req(p)
-                                && p->p_flag & P_TRACED);
+                               tstop(p);
+                       } while (!trace_req(p) && (p->p_flag & P_TRACED));
+                       p->p_flag &= ~P_STOPPED;
 
                        /*
                         * If parent wants us to take the signal,
@@ -1263,7 +1324,6 @@ issignal(p)
                 * to clear it from the pending mask.
                 */
                switch ((int)(intptr_t)p->p_sigacts->ps_sigact[_SIG_IDX(sig)]) {
-
                case (int)SIG_DFL:
                        /*
                         * Don't take default actions on system processes.
@@ -1279,6 +1339,15 @@ issignal(p)
 #endif
                                break;          /* == ignore */
                        }
+
+                       /*
+                        * Handle the in-kernel checkpoint action
+                        */
+                       if (prop & SA_CKPT) {
+                               checkpoint_signal_handler(p);
+                               break;
+                       }
+
                        /*
                         * If there is a pending stop signal to process
                         * with default action, stop here,
@@ -1292,10 +1361,14 @@ issignal(p)
                                    prop & SA_TTYSTOP))
                                        break;  /* == ignore */
                                p->p_xstat = sig;
-                               stop(p);
+                               p->p_flag |= P_STOPPED;
+                               p->p_flag &= ~P_WAITED;
+
                                if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0)
                                        psignal(p->p_pptr, SIGCHLD);
-                               mi_switch();
+                               while (p->p_flag & P_STOPPED) {
+                                       tstop(p);
+                               }
                                break;
                        } else if (prop & SA_IGNORE) {
                                /*
@@ -1303,8 +1376,11 @@ issignal(p)
                                 * Default action is to ignore; drop it.
                                 */
                                break;          /* == ignore */
-                       } else
+                       } else {
+                               rel_mplock();
                                return (sig);
+                       }
+
                        /*NOTREACHED*/
 
                case (int)SIG_IGN:
@@ -1323,6 +1399,7 @@ issignal(p)
                         * This signal has an action, let
                         * postsig() process it.
                         */
+                       rel_mplock();
                        return (sig);
                }
                SIGDELSET(p->p_siglist, sig);           /* take the signal! */
@@ -1330,28 +1407,12 @@ issignal(p)
        /* NOTREACHED */
 }
 
-/*
- * Put the argument process into the stopped state and notify the parent
- * via wakeup.  Signals are handled elsewhere.  The process must not be
- * on the run queue.
- */
-void
-stop(p)
-       register struct proc *p;
-{
-
-       p->p_stat = SSTOP;
-       p->p_flag &= ~P_WAITED;
-       wakeup((caddr_t)p->p_pptr);
-}
-
 /*
  * Take the action for the specified signal
  * from the current set of pending signals.
  */
 void
-postsig(sig)
-       register int sig;
+postsig(int sig)
 {
        struct proc *p = curproc;
        struct sigacts *ps = p->p_sigacts;
@@ -1392,12 +1453,13 @@ postsig(sig)
                 * mask from before the sigsuspend is what we want
                 * restored after the signal processing is completed.
                 */
-               (void) splhigh();
+               crit_enter();
                if (p->p_flag & P_OLDMASK) {
                        returnmask = p->p_oldsigmask;
                        p->p_flag &= ~P_OLDMASK;
-               } else
+               } else {
                        returnmask = p->p_sigmask;
+               }
 
                SIGSETOR(p->p_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
                if (!SIGISMEMBER(ps->ps_signodefer, sig))
@@ -1405,7 +1467,7 @@ postsig(sig)
 
                if (SIGISMEMBER(ps->ps_sigreset, sig)) {
                        /*
-                        * See do_sigaction() for origin of this code.
+                        * See kern_sigaction() for origin of this code.
                         */
                        SIGDELSET(p->p_sigcatch, sig);
                        if (sig != SIGCONT &&
@@ -1413,7 +1475,7 @@ postsig(sig)
                                SIGADDSET(p->p_sigignore, sig);
                        ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
                }
-               (void) spl0();
+               crit_exit();
                p->p_stats->p_ru.ru_nsignals++;
                if (p->p_sig != sig) {
                        code = 0;
@@ -1430,9 +1492,7 @@ postsig(sig)
  * Kill the current process for stated reason.
  */
 void
-killproc(p, why)
-       struct proc *p;
-       char *why;
+killproc(struct proc *p, char *why)
 {
        log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm,
                p->p_ucred ? p->p_ucred->cr_uid : -1, why);
@@ -1490,8 +1550,8 @@ SYSCTL_STRING(_kern, OID_AUTO, corefile, CTLFLAG_RW, corefilename,
  */
 
 static char *
-expand_name(name, uid, pid)
-const char *name; uid_t uid; pid_t pid; {
+expand_name(const char *name, uid_t uid, pid_t pid)
+{
        char *temp;
        char buf[11];           /* Buffer for pid/uid -- max 4B */
        int i, n;
@@ -1570,7 +1630,7 @@ coredump(struct proc *p)
        struct ucred *cred = p->p_ucred;
        struct thread *td = p->p_thread;
        struct flock lf;
-       struct nameidata nd;
+       struct nlookupdata nd;
        struct vattr vattr;
        int error, error1;
        char *name;                     /* name of corefile */
@@ -1591,20 +1651,24 @@ coredump(struct proc *p)
         */
        limit = p->p_rlimit[RLIMIT_CORE].rlim_cur;
        if (limit == 0)
-               return 0;
+               return EFBIG;
 
        name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
        if (name == NULL)
                return (EINVAL);
-       NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td);
-       error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
+       error = nlookup_init(&nd, name, UIO_SYSSPACE, NLC_LOCKVP);
+       if (error == 0)
+               error = vn_open(&nd, NULL, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
        free(name, M_TEMP);
-       if (error)
+       if (error) {
+               nlookup_done(&nd);
                return (error);
-       NDFREE(&nd, NDF_ONLY_PNBUF);
-       vp = nd.ni_vp;
+       }
+       vp = nd.nl_open_vp;
+       nd.nl_open_vp = NULL;
+       nlookup_done(&nd);
 
-       VOP_UNLOCK(vp, 0, td);
+       VOP_UNLOCK(vp, 0);
        lf.l_whence = SEEK_SET;
        lf.l_start = 0;
        lf.l_len = 0;
@@ -1621,16 +1685,14 @@ coredump(struct proc *p)
        }
 
        VATTR_NULL(&vattr);
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
        vattr.va_size = 0;
-       VOP_LEASE(vp, td, cred, LEASE_WRITE);
        VOP_SETATTR(vp, &vattr, cred, td);
        p->p_acflag |= ACORE;
-       VOP_UNLOCK(vp, 0, td);
+       VOP_UNLOCK(vp, 0);
 
        error = p->p_sysent->sv_coredump ?
-         p->p_sysent->sv_coredump(p, vp, limit) :
-         ENOSYS;
+                 p->p_sysent->sv_coredump(p, vp, limit) : ENOSYS;
 
 out1:
        lf.l_type = F_UNLCK;
@@ -1646,11 +1708,6 @@ out2:
  * Nonexistent system call-- signal process (may want to handle it).
  * Flag error in case process won't see signal immediately (blocked or ignored).
  */
-#ifndef _SYS_SYSPROTO_H_
-struct nosys_args {
-       int     dummy;
-};
-#endif
 /* ARGSUSED */
 int
 nosys(struct nosys_args *args)
@@ -1714,7 +1771,6 @@ filt_sigdetach(struct knote *kn)
 static int
 filt_signal(struct knote *kn, long hint)
 {
-
        if (hint & NOTE_SIGNAL) {
                hint &= ~NOTE_SIGNAL;