]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_exit.c
xnu-344.21.74.tar.gz
[apple/xnu.git] / bsd / kern / kern_exit.c
index ffb3efdcfa3e24cb50d9b30aff48934a12458968..25dc9ef7122edf290c3150770e7c49bf5771c637 100644 (file)
@@ -1,21 +1,24 @@
 /*
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 #include <mach/mach_types.h>
 #include <kern/thread.h>
 #include <kern/thread_act.h>
 #include <mach/mach_types.h>
 #include <kern/thread.h>
 #include <kern/thread_act.h>
+#include <kern/sched_prim.h>
 #include <kern/assert.h>
 #include <kern/assert.h>
+#if KTRACE   
+#include <sys/ktrace.h>
+#endif
 
 extern char init_task_failure_data[];
 int exit1 __P((struct proc *, int, int *));
 
 extern char init_task_failure_data[];
 int exit1 __P((struct proc *, int, int *));
@@ -106,12 +113,12 @@ exit(p, uap, retval)
 {
        exit1(p, W_EXITCODE(uap->rval, 0), retval);
 
 {
        exit1(p, W_EXITCODE(uap->rval, 0), retval);
 
-       /* drop funnel befewo we return */
+       /* drop funnel before we return */
        thread_funnel_set(kernel_flock, FALSE);
        thread_exception_return();
        /* NOTREACHED */
        while (TRUE)
        thread_funnel_set(kernel_flock, FALSE);
        thread_exception_return();
        /* NOTREACHED */
        while (TRUE)
-               thread_block(0);
+               thread_block(THREAD_CONTINUE_NULL);
        /* NOTREACHED */
 }
 
        /* NOTREACHED */
 }
 
@@ -141,7 +148,7 @@ exit1(p, rv, retval)
 
         ut = get_bsdthread_info(th_act_self);
         if (ut->uu_flag & P_VFORK) {
 
         ut = get_bsdthread_info(th_act_self);
         if (ut->uu_flag & P_VFORK) {
-                       vfork_exit(p, rv);
+                       (void)vfork_exit(p, rv);
                        vfork_return(th_act_self, p->p_pptr, p , retval);
                        unix_syscall_return(0);
                        /* NOT REACHED */
                        vfork_return(th_act_self, p->p_pptr, p , retval);
                        unix_syscall_return(0);
                        /* NOT REACHED */
@@ -172,7 +179,7 @@ exit1(p, rv, retval)
        s = splsched();
        p->p_flag |= P_WEXIT;
        splx(s);
        s = splsched();
        p->p_flag |= P_WEXIT;
        splx(s);
-       proc_prepareexit(p);
+       (void)proc_prepareexit(p);
        p->p_xstat = rv;
 
        /* task terminate will call proc_terminate and that cleans it up */
        p->p_xstat = rv;
 
        /* task terminate will call proc_terminate and that cleans it up */
@@ -204,7 +211,6 @@ proc_prepareexit(struct proc *p)
        thread_t self = current_thread();
        thread_act_t th_act_self = current_act();
 
        thread_t self = current_thread();
        thread_act_t th_act_self = current_act();
 
-
        /*
         * Remove proc from allproc queue and from pidhash chain.
         * Need to do this before we do anything that can block.
        /*
         * Remove proc from allproc queue and from pidhash chain.
         * Need to do this before we do anything that can block.
@@ -225,20 +231,18 @@ proc_prepareexit(struct proc *p)
        p->p_sigignore = ~0;
        p->p_siglist = 0;
        ut = get_bsdthread_info(th_act_self);
        p->p_sigignore = ~0;
        p->p_siglist = 0;
        ut = get_bsdthread_info(th_act_self);
-       ut->uu_sig = 0;
-       untimeout(realitexpire, (caddr_t)p);
-
+       ut->uu_siglist = 0;
+       untimeout(realitexpire, (caddr_t)p->p_pid);
 }
 
 void 
 proc_exit(struct proc *p)
 {
 }
 
 void 
 proc_exit(struct proc *p)
 {
-       register struct proc *q, *nq;
+       register struct proc *q, *nq, *pp;
        thread_t self = current_thread();
        thread_act_t th_act_self = current_act();
        struct task *task = p->task;
        register int i,s;
        thread_t self = current_thread();
        thread_act_t th_act_self = current_act();
        struct task *task = p->task;
        register int i,s;
-       struct uthread *ut;
        boolean_t funnel_state;
 
        /* This can happen if thread_terminate of the single thread
        boolean_t funnel_state;
 
        /* This can happen if thread_terminate of the single thread
@@ -265,11 +269,15 @@ proc_exit(struct proc *p)
        /* Close ref SYSV Shared memory*/
        if (p->vm_shm)
                shmexit(p);
        /* Close ref SYSV Shared memory*/
        if (p->vm_shm)
                shmexit(p);
+       /* Release SYSV semaphores */
+       semexit(p);
        
        if (SESS_LEADER(p)) {
                register struct session *sp = p->p_session;
 
                if (sp->s_ttyvp) {
        
        if (SESS_LEADER(p)) {
                register struct session *sp = p->p_session;
 
                if (sp->s_ttyvp) {
+                       struct vnode *ttyvp;
+
                        /*
                         * Controlling process.
                         * Signal foreground pgrp,
                        /*
                         * Controlling process.
                         * Signal foreground pgrp,
@@ -287,9 +295,10 @@ proc_exit(struct proc *p)
                                if (sp->s_ttyvp)
                                        VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
                        }
                                if (sp->s_ttyvp)
                                        VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
                        }
-                       if (sp->s_ttyvp)
-                               vrele(sp->s_ttyvp);
+                       ttyvp = sp->s_ttyvp;
                        sp->s_ttyvp = NULL;
                        sp->s_ttyvp = NULL;
+                       if (ttyvp)
+                               vrele(ttyvp);
                        /*
                         * s_ttyp is not zero'd; we use this to indicate
                         * that the session once had a controlling terminal.
                        /*
                         * s_ttyp is not zero'd; we use this to indicate
                         * that the session once had a controlling terminal.
@@ -301,16 +310,20 @@ proc_exit(struct proc *p)
 
        fixjobc(p, p->p_pgrp, 0);
        p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
        fixjobc(p, p->p_pgrp, 0);
        p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+       (void)acct_process(p);
+
 #if KTRACE
        /* 
         * release trace file
         */
        p->p_traceflag = 0;     /* don't trace the vrele() */
 #if KTRACE
        /* 
         * release trace file
         */
        p->p_traceflag = 0;     /* don't trace the vrele() */
-       if (p->p_tracep)
-               vrele(p->p_tracep);
+       if (p->p_tracep) {
+               struct vnode *tvp = p->p_tracep;
+               p->p_tracep = NULL;
+               vrele(tvp);
+       }
 #endif
 
 #endif
 
-
        q = p->p_children.lh_first;
        if (q)          /* only need this if any child is S_ZOMB */
                wakeup((caddr_t) initproc);
        q = p->p_children.lh_first;
        if (q)          /* only need this if any child is S_ZOMB */
                wakeup((caddr_t) initproc);
@@ -324,7 +337,9 @@ proc_exit(struct proc *p)
                if (q->p_flag & P_TRACED) {
                        q->p_flag &= ~P_TRACED;
                        if (q->sigwait_thread) {
                if (q->p_flag & P_TRACED) {
                        q->p_flag &= ~P_TRACED;
                        if (q->sigwait_thread) {
-                               thread_t sig_shuttle  = getshuttle_thread(q->sigwait_thread);
+                               thread_t sig_shuttle;
+
+                               sig_shuttle = (thread_t)getshuttle_thread((thread_act_t)q->sigwait_thread);
                                /*
                                 * The sigwait_thread could be stopped at a
                                 * breakpoint. Wake it up to kill.
                                /*
                                 * The sigwait_thread could be stopped at a
                                 * breakpoint. Wake it up to kill.
@@ -332,15 +347,14 @@ proc_exit(struct proc *p)
                                 * the first thread in the task. So any attempts to kill
                                 * the process would result into a deadlock on q->sigwait.
                                 */
                                 * the first thread in the task. So any attempts to kill
                                 * the process would result into a deadlock on q->sigwait.
                                 */
-                               thread_resume((struct thread *)q->sigwait_thread);
+                               thread_resume((thread_act_t)q->sigwait_thread);
                                clear_wait(sig_shuttle, THREAD_INTERRUPTED);
                                clear_wait(sig_shuttle, THREAD_INTERRUPTED);
-                               threadsignal(q->sigwait_thread, SIGKILL, 0);
+                               threadsignal((thread_act_t)q->sigwait_thread, SIGKILL, 0);
                        }
                        psignal(q, SIGKILL);
                }
        }
 
                        }
                        psignal(q, SIGKILL);
                }
        }
 
-
        /*
         * Save exit status and final rusage info, adding in child rusage
         * info and self times.
        /*
         * Save exit status and final rusage info, adding in child rusage
         * info and self times.
@@ -376,7 +390,6 @@ proc_exit(struct proc *p)
                timeradd(&st,&p->p_ru->ru_stime,&p->p_ru->ru_stime);
        }
 
                timeradd(&st,&p->p_ru->ru_stime,&p->p_ru->ru_stime);
        }
 
-
        ruadd(p->p_ru, &p->p_stats->p_cru);
 
        /*
        ruadd(p->p_ru, &p->p_stats->p_cru);
 
        /*
@@ -420,7 +433,24 @@ proc_exit(struct proc *p)
        /*
         * Notify parent that we're gone.
         */
        /*
         * Notify parent that we're gone.
         */
-       psignal(p->p_pptr, SIGCHLD);
+       if (p->p_pptr->p_flag & P_NOCLDWAIT) {
+               struct proc * pp = p->p_pptr;
+
+               proc_reparent(p, initproc);
+               /* If there are no more children wakeup parent */
+               if (LIST_EMPTY(&pp->p_children))
+                       wakeup((caddr_t)pp);
+       }
+       /* should be fine as parent proc would be initproc */
+       pp = p->p_pptr;
+       if (pp != initproc) {
+               pp->si_pid = p->p_pid;
+               pp->si_status = p->p_xstat;
+               pp->si_code = CLD_EXITED;
+               pp->si_uid = p->p_cred->p_ruid;
+       }
+       psignal(pp, SIGCHLD);
+
 
        /* Place onto zombproc. */
        LIST_INSERT_HEAD(&zombproc, p, p_list);
 
        /* Place onto zombproc. */
        LIST_INSERT_HEAD(&zombproc, p, p_list);
@@ -464,7 +494,6 @@ wait4(p, uap, retval)
        struct wait4_args *uap;
        int *retval;
 {
        struct wait4_args *uap;
        int *retval;
 {
-
        return (wait1(p, uap, retval, 0));
 }
 
        return (wait1(p, uap, retval, 0));
 }
 
@@ -499,23 +528,18 @@ owait3(p, uap, retval)
 int
 wait1continue(result)
 {
 int
 wait1continue(result)
 {
-  void *vt;
-  thread_act_t thread;
-  struct uthread *ut;
-  int *retval;
-  struct proc *p;
+       void *vt;
+       thread_act_t thread;
+       int *retval;
+       struct proc *p;
 
 
-       p = current_proc();
-       p->p_flag &= ~P_WAITING;
+       if (result)
+               return(result);
 
 
-      if (result != 0) {
-         return(result);
-       }
-
-    thread = current_act();
-       ut = get_bsdthread_info(thread);
-       vt = get_bsduthreadarg(thread);
-       retval = get_bsduthreadrval(thread);
+       p = current_proc();
+       thread = current_act();
+       vt = (void *)get_bsduthreadarg(thread);
+       retval = (int *)get_bsduthreadrval(thread);
        wait1((struct proc *)p, (struct wait4_args *)vt, retval, 0);
 }
 
        wait1((struct proc *)p, (struct wait4_args *)vt, retval, 0);
 }
 
@@ -531,16 +555,9 @@ wait1(q, uap, retval, compat)
        register int nfound;
        register struct proc *p, *t;
        int status, error;
        register int nfound;
        register struct proc *p, *t;
        int status, error;
+       struct vnode *tvp;
 
 
-
-#if 0
-       /* since we are funneled we don't need to do this atomically, yet */
-       if (q->p_flag & P_WAITING) {
-         return(EINVAL);
-       }
-       q->p_flag |= P_WAITING;   /* only allow single thread to wait() */
-#endif
-
+retry:
        if (uap->pid == 0)
                uap->pid = -q->p_pgid;
 
        if (uap->pid == 0)
                uap->pid = -q->p_pgid;
 
@@ -552,6 +569,12 @@ loop:
                    p->p_pgid != -(uap->pid))
                        continue;
                nfound++;
                    p->p_pgid != -(uap->pid))
                        continue;
                nfound++;
+               if (p->p_flag & P_WAITING) {
+                       (void)tsleep(&p->p_stat, PWAIT, "waitcoll", 0);
+                       goto loop;
+               }
+               p->p_flag |= P_WAITING;   /* only allow single thread to wait() */
+
                if (p->p_stat == SZOMB) {
                        retval[0] = p->p_pid;
 #if COMPAT_43
                if (p->p_stat == SZOMB) {
                        retval[0] = p->p_pid;
 #if COMPAT_43
@@ -564,7 +587,8 @@ loop:
                                if (error = copyout((caddr_t)&status,
                                    (caddr_t)uap->status,
                                                    sizeof(status))) {
                                if (error = copyout((caddr_t)&status,
                                    (caddr_t)uap->status,
                                                    sizeof(status))) {
-                                       q->p_flag &= ~P_WAITING;
+                                       p->p_flag &= ~P_WAITING;
+                                       wakeup(&p->p_stat);
                                        return (error);
                                }
                        }
                                        return (error);
                                }
                        }
@@ -572,7 +596,8 @@ loop:
                            (error = copyout((caddr_t)p->p_ru,
                            (caddr_t)uap->rusage,
                                             sizeof (struct rusage)))) {
                            (error = copyout((caddr_t)p->p_ru,
                            (caddr_t)uap->rusage,
                                             sizeof (struct rusage)))) {
-                                       q->p_flag &= ~P_WAITING;
+                               p->p_flag &= ~P_WAITING;
+                               wakeup(&p->p_stat);
                                return (error);
                        }
                        /*
                                return (error);
                        }
                        /*
@@ -582,9 +607,16 @@ loop:
                        if (p->p_oppid && (t = pfind(p->p_oppid))) {
                                p->p_oppid = 0;
                                proc_reparent(p, t);
                        if (p->p_oppid && (t = pfind(p->p_oppid))) {
                                p->p_oppid = 0;
                                proc_reparent(p, t);
+                               if (t != initproc) {
+                                       t->si_pid = p->p_pid;
+                                       t->si_status = p->p_xstat;
+                                       t->si_code = CLD_CONTINUED;
+                                       t->si_uid = p->p_cred->p_ruid;
+                               }
                                psignal(t, SIGCHLD);
                                wakeup((caddr_t)t);
                                psignal(t, SIGCHLD);
                                wakeup((caddr_t)t);
-                                       q->p_flag &= ~P_WAITING;
+                               p->p_flag &= ~P_WAITING;
+                               wakeup(&p->p_stat);
                                return (0);
                        }
                        p->p_xstat = 0;
                                return (0);
                        }
                        p->p_xstat = 0;
@@ -620,8 +652,10 @@ loop:
                        /*
                         * Release reference to text vnode
                         */
                        /*
                         * Release reference to text vnode
                         */
-                       if (p->p_textvp)
-                               vrele(p->p_textvp);
+                       tvp = p->p_textvp;
+                       p->p_textvp = NULL;
+                       if (tvp)
+                               vrele(tvp);
 
                        /*
                         * Finally finished with old proc entry.
 
                        /*
                         * Finally finished with old proc entry.
@@ -630,9 +664,10 @@ loop:
                        leavepgrp(p);
                        LIST_REMOVE(p, p_list); /* off zombproc */
                        LIST_REMOVE(p, p_sibling);
                        leavepgrp(p);
                        LIST_REMOVE(p, p_list); /* off zombproc */
                        LIST_REMOVE(p, p_sibling);
+                       p->p_flag &= ~P_WAITING;
                        FREE_ZONE(p, sizeof *p, M_PROC);
                        nprocs--;
                        FREE_ZONE(p, sizeof *p, M_PROC);
                        nprocs--;
-                                       q->p_flag &= ~P_WAITING;
+                       wakeup(&p->p_stat);
                        return (0);
                }
                if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
                        return (0);
                }
                if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
@@ -652,24 +687,24 @@ loop:
                                    sizeof(status));
                        } else
                                error = 0;
                                    sizeof(status));
                        } else
                                error = 0;
-                                       q->p_flag &= ~P_WAITING;
+                       p->p_flag &= ~P_WAITING;
+                       wakeup(&p->p_stat);
                        return (error);
                }
                        return (error);
                }
+               p->p_flag &= ~P_WAITING;
+               wakeup(&p->p_stat);
        }
        }
-       if (nfound == 0) {
-                                       q->p_flag &= ~P_WAITING;
+       if (nfound == 0)
                return (ECHILD);
                return (ECHILD);
-       }
+
        if (uap->options & WNOHANG) {
                retval[0] = 0;
        if (uap->options & WNOHANG) {
                retval[0] = 0;
-                                       q->p_flag &= ~P_WAITING;
                return (0);
        }
 
                return (0);
        }
 
-       if (error = tsleep0((caddr_t)q, PWAIT | PCATCH, "wait", 0, wait1continue)) {
-                                       q->p_flag &= ~P_WAITING;
+       if (error = tsleep0((caddr_t)q, PWAIT | PCATCH, "wait", 0, wait1continue))
                return (error);
                return (error);
-       }
+
        goto loop;
 }
 
        goto loop;
 }
 
@@ -690,13 +725,13 @@ proc_reparent(child, parent)
        child->p_pptr = parent;
 }
 
        child->p_pptr = parent;
 }
 
-kern_return_t
-init_process(void)
 /*
  *     Make the current process an "init" process, meaning
  *     that it doesn't have a parent, and that it won't be
  *     gunned down by kill(-1, 0).
  */
 /*
  *     Make the current process an "init" process, meaning
  *     that it doesn't have a parent, and that it won't be
  *     gunned down by kill(-1, 0).
  */
+kern_return_t
+init_process(void)
 {
        register struct proc *p = current_proc();
 
 {
        register struct proc *p = current_proc();
 
@@ -729,6 +764,7 @@ process_terminate_self(void)
                /*NOTREACHED*/
        }
 }
                /*NOTREACHED*/
        }
 }
+
 /*
  * Exit: deallocate address space and other resources, change proc state
  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
 /*
  * Exit: deallocate address space and other resources, change proc state
  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
@@ -737,7 +773,7 @@ process_terminate_self(void)
 
 void
 vfork_exit(p, rv)
 
 void
 vfork_exit(p, rv)
-       register struct proc *p;
+       struct proc *p;
        int rv;
 {
        register struct proc *q, *nq;
        int rv;
 {
        register struct proc *q, *nq;
@@ -797,24 +833,22 @@ panic("init died\nState at Last Exception:\n\n%s", init_task_failure_data);
        p->p_sigignore = ~0;
        p->p_siglist = 0;
 
        p->p_sigignore = ~0;
        p->p_siglist = 0;
 
-       ut->uu_sig = 0;
-       untimeout(realitexpire, (caddr_t)p);
+       ut->uu_siglist = 0;
+       untimeout(realitexpire, (caddr_t)p->p_pid);
 
        p->p_xstat = rv;
 
 
        p->p_xstat = rv;
 
-       vproc_exit(p);
+       (void)vproc_exit(p);
 }
 
 }
 
-
 void 
 vproc_exit(struct proc *p)
 {
 void 
 vproc_exit(struct proc *p)
 {
-       register struct proc *q, *nq;
+       register struct proc *q, *nq, *pp;
        thread_t self = current_thread();
        thread_act_t th_act_self = current_act();
        struct task *task = p->task;
        register int i,s;
        thread_t self = current_thread();
        thread_act_t th_act_self = current_act();
        struct task *task = p->task;
        register int i,s;
-       struct uthread *ut;
        boolean_t funnel_state;
 
        MALLOC_ZONE(p->p_ru, struct rusage *,
        boolean_t funnel_state;
 
        MALLOC_ZONE(p->p_ru, struct rusage *,
@@ -826,14 +860,12 @@ vproc_exit(struct proc *p)
         */
        fdfree(p);
 
         */
        fdfree(p);
 
-       /* Close ref SYSV Shared memory*/
-       if (p->vm_shm)
-               shmexit(p);
-       
        if (SESS_LEADER(p)) {
                register struct session *sp = p->p_session;
 
                if (sp->s_ttyvp) {
        if (SESS_LEADER(p)) {
                register struct session *sp = p->p_session;
 
                if (sp->s_ttyvp) {
+                       struct vnode *ttyvp;
+
                        /*
                         * Controlling process.
                         * Signal foreground pgrp,
                        /*
                         * Controlling process.
                         * Signal foreground pgrp,
@@ -851,9 +883,10 @@ vproc_exit(struct proc *p)
                                if (sp->s_ttyvp)
                                        VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
                        }
                                if (sp->s_ttyvp)
                                        VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
                        }
-                       if (sp->s_ttyvp)
-                               vrele(sp->s_ttyvp);
+                       ttyvp = sp->s_ttyvp;
                        sp->s_ttyvp = NULL;
                        sp->s_ttyvp = NULL;
+                       if (ttyvp)
+                               vrele(ttyvp);
                        /*
                         * s_ttyp is not zero'd; we use this to indicate
                         * that the session once had a controlling terminal.
                        /*
                         * s_ttyp is not zero'd; we use this to indicate
                         * that the session once had a controlling terminal.
@@ -865,16 +898,19 @@ vproc_exit(struct proc *p)
 
        fixjobc(p, p->p_pgrp, 0);
        p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
        fixjobc(p, p->p_pgrp, 0);
        p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+
 #if KTRACE
        /* 
         * release trace file
         */
        p->p_traceflag = 0;     /* don't trace the vrele() */
 #if KTRACE
        /* 
         * release trace file
         */
        p->p_traceflag = 0;     /* don't trace the vrele() */
-       if (p->p_tracep)
-               vrele(p->p_tracep);
+       if (p->p_tracep) {
+               struct vnode *tvp = p->p_tracep;
+               p->p_tracep = NULL;
+               vrele(tvp);
+       }
 #endif
 
 #endif
 
-
        q = p->p_children.lh_first;
        if (q)          /* only need this if any child is S_ZOMB */
                wakeup((caddr_t) initproc);
        q = p->p_children.lh_first;
        if (q)          /* only need this if any child is S_ZOMB */
                wakeup((caddr_t) initproc);
@@ -888,7 +924,9 @@ vproc_exit(struct proc *p)
                if (q->p_flag & P_TRACED) {
                        q->p_flag &= ~P_TRACED;
                        if (q->sigwait_thread) {
                if (q->p_flag & P_TRACED) {
                        q->p_flag &= ~P_TRACED;
                        if (q->sigwait_thread) {
-                               thread_t sig_shuttle  = getshuttle_thread(q->sigwait_thread);
+                               thread_t sig_shuttle;
+
+                               sig_shuttle = (thread_t) getshuttle_thread((thread_act_t)q->sigwait_thread);
                                /*
                                 * The sigwait_thread could be stopped at a
                                 * breakpoint. Wake it up to kill.
                                /*
                                 * The sigwait_thread could be stopped at a
                                 * breakpoint. Wake it up to kill.
@@ -896,15 +934,14 @@ vproc_exit(struct proc *p)
                                 * the first thread in the task. So any attempts to kill
                                 * the process would result into a deadlock on q->sigwait.
                                 */
                                 * the first thread in the task. So any attempts to kill
                                 * the process would result into a deadlock on q->sigwait.
                                 */
-                               thread_resume((struct thread *)q->sigwait_thread);
+                               thread_resume((thread_act_t)q->sigwait_thread);
                                clear_wait(sig_shuttle, THREAD_INTERRUPTED);
                                clear_wait(sig_shuttle, THREAD_INTERRUPTED);
-                               threadsignal(q->sigwait_thread, SIGKILL, 0);
+                               threadsignal((thread_act_t)q->sigwait_thread, SIGKILL, 0);
                        }
                        psignal(q, SIGKILL);
                }
        }
 
                        }
                        psignal(q, SIGKILL);
                }
        }
 
-
        /*
         * Save exit status and final rusage info, adding in child rusage
         * info and self times.
        /*
         * Save exit status and final rusage info, adding in child rusage
         * info and self times.
@@ -983,6 +1020,13 @@ vproc_exit(struct proc *p)
        /*
         * Notify parent that we're gone.
         */
        /*
         * Notify parent that we're gone.
         */
+       pp = p->p_pptr;
+       if (pp != initproc) {
+               pp->si_pid = p->p_pid;
+               pp->si_status = p->p_xstat;
+               pp->si_code = CLD_EXITED;
+               pp->si_uid = p->p_cred->p_ruid;
+       }
        psignal(p->p_pptr, SIGCHLD);
 
        /* Place onto zombproc. */
        psignal(p->p_pptr, SIGCHLD);
 
        /* Place onto zombproc. */
@@ -991,6 +1035,4 @@ vproc_exit(struct proc *p)
 
        /* and now wakeup the parent */
        wakeup((caddr_t)p->p_pptr);
 
        /* and now wakeup the parent */
        wakeup((caddr_t)p->p_pptr);
-
 }
 }
-