/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <mach/mach_types.h>
#include <kern/thread.h>
#include <kern/thread_act.h>
+#include <kern/sched_prim.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 *));
{
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_block(0);
+ thread_block(THREAD_CONTINUE_NULL);
/* NOTREACHED */
}
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 */
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_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)
{
- 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;
/* 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;
fixjobc(p, p->p_pgrp, 0);
p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+ (void)acct_process(p);
+
#if KTRACE
/*
* release trace file
}
#endif
-
q = p->p_children.lh_first;
if (q) /* only need this if any child is S_ZOMB */
wakeup((caddr_t) initproc);
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 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);
- threadsignal(q->sigwait_thread, SIGKILL, 0);
+ threadsignal((thread_act_t)q->sigwait_thread, SIGKILL, 0);
}
psignal(q, SIGKILL);
}
/*
* 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);
p = current_proc();
thread = current_act();
- vt = get_bsduthreadarg(thread);
- retval = get_bsduthreadrval(thread);
+ vt = (void *)get_bsduthreadarg(thread);
+ retval = (int *)get_bsduthreadrval(thread);
wait1((struct proc *)p, (struct wait4_args *)vt, retval, 0);
}
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);
p->p_flag &= ~P_WAITING;
void
vfork_exit(p, rv)
- register struct proc *p;
+ struct proc *p;
int rv;
{
register struct proc *q, *nq;
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;
- vproc_exit(p);
+ (void)vproc_exit(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;
*/
fdfree(p);
- /* Close ref SYSV Shared memory*/
- if (p->vm_shm)
- shmexit(p);
-
if (SESS_LEADER(p)) {
register struct session *sp = p->p_session;
fixjobc(p, p->p_pgrp, 0);
p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
+
#if KTRACE
/*
* release trace file
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 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);
- threadsignal(q->sigwait_thread, SIGKILL, 0);
+ threadsignal((thread_act_t)q->sigwait_thread, SIGKILL, 0);
}
psignal(q, SIGKILL);
}
/*
* 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. */