FreeBSD/sys/kern/sys_procdesc.c
/*
 * procdesc_close() - last close on a process descriptor.  If the process is
 * still running, terminate with SIGKILL (unless PDF_DAEMON is set) and let
 * init(8) clean up the mess; if not, we have to clean up the zombie ourselves.
 */
last close on a process descriptor.  If the process is
still running, terminate with SIGKILL (unless PDF_DAEMON is set) and let
init(8) clean up the mess; if not, we have to clean up the zombie ourselves.
last close on a process descriptor . If the process is still running terminate with SIGKILL ( unless PDF_DAEMON is set ) and let init ( 8 ) clean up the mess ; if not we have to clean up the zombie ourselves .
static int
procdesc_close(struct file *fp, struct thread *td)
{
	struct procdesc *pd;
	struct proc *p;
	KASSERT(fp->f_type == DTYPE_PROCDESC, ("procdesc_close: !procdesc"));
	pd = fp->f_data;
	fp->f_ops = &badfileops;
	fp->f_data = NULL;
	sx_xlock(&proctree_lock);
	PROCDESC_LOCK(pd);
	pd->pd_flags |= PDF_CLOSED;
	PROCDESC_UNLOCK(pd);
	p = pd->pd_proc;
	if (p == NULL) {
		sx_xunlock(&proctree_lock);
	} else {
		PROC_LOCK(p);
		if (p->p_state == PRS_ZOMBIE) {
			PROC_SLOCK(p);
			proc_reap(curthread, p, NULL, 0);
		} else {
			pd->pd_proc = NULL;
			p->p_procdesc = NULL;
			procdesc_free(pd);
			p->p_sigparent = SIGCHLD;
			proc_reparent(p, initproc);
			if ((pd->pd_flags & PDF_DAEMON) == 0)
				kern_psignal(p, SIGKILL);
			PROC_UNLOCK(p);
			sx_xunlock(&proctree_lock);
		}
	}
	procdesc_free(pd);
	return (0);
}
static int procdesc_close ( struct file * fp , struct thread * td ) { struct procdesc * pd ; struct proc * p ; KASSERT ( fp -> f_type == DTYPE_PROCDESC , ( " " ) ) ; pd = fp -> f_data ; fp -> f_ops = & badfileops ; fp -> f_data = NULL ; sx_xlock ( & proctree_lock ) ; PROCDESC_LOCK ( pd ) ; pd -> pd_flags |= PDF_CLOSED ; PROCDESC_UNLOCK ( pd ) ; p = pd -> pd_proc ; if ( p == NULL ) { sx_xunlock ( & proctree_lock ) ; } else { PROC_LOCK ( p ) ; if ( p -> p_state == PRS_ZOMBIE ) { PROC_SLOCK ( p ) ; proc_reap ( curthread , p , NULL , 0 ) ; } else { pd -> pd_proc = NULL ; p -> p_procdesc = NULL ; procdesc_free ( pd ) ; p -> p_sigparent = SIGCHLD ; proc_reparent ( p , initproc ) ; if ( ( pd -> pd_flags & PDF_DAEMON ) == 0 ) kern_psignal ( p , SIGKILL ) ; PROC_UNLOCK ( p ) ; sx_xunlock ( & proctree_lock ) ; } } procdesc_free ( pd ) ; return ( 0 ) ; }
procdesc_close() - last close on a process descriptor.
procdesc_close () - last close on a process descriptor .
/*
		 * This is the case where process' exit status was already
		 * collected and procdesc_reap() was already called.
		 */ /*
			 * If the process is already dead and just awaiting
			 * reaping, do that now.  This will release the
			 * process's reference to the process descriptor when it
			 * calls back into procdesc_reap().
			 */ /*
			 * If the process is not yet dead, we need to kill it,
			 * but we can't wait around synchronously for it to go
			 * away, as that path leads to madness (and deadlocks).
			 * First, detach the process from its descriptor so that
			 * its exit status will be reported normally.
			 */ /*
			 * Next, reparent it to init(8) so that there's someone
			 * to pick up the pieces; finally, terminate with
			 * prejudice.
			 */ /*
	 * Release the file descriptor's reference on the process descriptor.
	 */