[BACK]Return to kern_exit.c CVS log [TXT][DIR] Up to [local] / sys / kern

Annotation of sys/kern/kern_exit.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: kern_exit.c,v 1.71 2007/04/12 22:14:15 tedu Exp $     */
                      2: /*     $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $  */
                      3:
                      4: /*
                      5:  * Copyright (c) 1982, 1986, 1989, 1991, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  * (c) UNIX System Laboratories, Inc.
                      8:  * All or some portions of this file are derived from material licensed
                      9:  * to the University of California by American Telephone and Telegraph
                     10:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
                     11:  * the permission of UNIX System Laboratories, Inc.
                     12:  *
                     13:  * Redistribution and use in source and binary forms, with or without
                     14:  * modification, are permitted provided that the following conditions
                     15:  * are met:
                     16:  * 1. Redistributions of source code must retain the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer.
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  * 3. Neither the name of the University nor the names of its contributors
                     22:  *    may be used to endorse or promote products derived from this software
                     23:  *    without specific prior written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     35:  * SUCH DAMAGE.
                     36:  *
                     37:  *     @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
                     38:  */
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/ioctl.h>
                     43: #include <sys/proc.h>
                     44: #include <sys/tty.h>
                     45: #include <sys/time.h>
                     46: #include <sys/resource.h>
                     47: #include <sys/kernel.h>
                     48: #include <sys/buf.h>
                     49: #include <sys/wait.h>
                     50: #include <sys/file.h>
                     51: #include <sys/vnode.h>
                     52: #include <sys/syslog.h>
                     53: #include <sys/malloc.h>
                     54: #include <sys/resourcevar.h>
                     55: #include <sys/ptrace.h>
                     56: #include <sys/acct.h>
                     57: #include <sys/filedesc.h>
                     58: #include <sys/signalvar.h>
                     59: #include <sys/sched.h>
                     60: #include <sys/ktrace.h>
                     61: #include <sys/pool.h>
                     62: #include <sys/mutex.h>
                     63: #ifdef SYSVSHM
                     64: #include <sys/shm.h>
                     65: #endif
                     66: #ifdef SYSVSEM
                     67: #include <sys/sem.h>
                     68: #endif
                     69:
                     70: #include "systrace.h"
                     71: #include <dev/systrace.h>
                     72:
                     73: #include <sys/mount.h>
                     74: #include <sys/syscallargs.h>
                     75:
                     76: #include <machine/cpu.h>
                     77:
                     78: #include <uvm/uvm_extern.h>
                     79:
                     80: /*
                     81:  * exit --
                     82:  *     Death of process.
                     83:  */
                     84: int
                     85: sys_exit(struct proc *p, void *v, register_t *retval)
                     86: {
                     87:        struct sys_exit_args /* {
                     88:                syscallarg(int) rval;
                     89:        } */ *uap = v;
                     90:
                     91:        exit1(p, W_EXITCODE(SCARG(uap, rval), 0), EXIT_NORMAL);
                     92:        /* NOTREACHED */
                     93:        return (0);
                     94: }
                     95:
                     96: #ifdef RTHREADS
                     97: int
                     98: sys_threxit(struct proc *p, void *v, register_t *retval)
                     99: {
                    100:        struct sys_threxit_args *uap = v;
                    101:
                    102:        exit1(p, W_EXITCODE(SCARG(uap, rval), 0), EXIT_THREAD);
                    103:
                    104:        return (0);
                    105: }
                    106: #endif
                    107:
                    108: /*
                    109:  * Exit: deallocate address space and other resources, change proc state
                    110:  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
                    111:  * status and rusage for wait().  Check for child processes and orphan them.
                    112:  */
                    113: void
                    114: exit1(struct proc *p, int rv, int flags)
                    115: {
                    116:        struct proc *q, *nq;
                    117:
                    118:        if (p->p_pid == 1)
                    119:                panic("init died (signal %d, exit %d)",
                    120:                    WTERMSIG(rv), WEXITSTATUS(rv));
                    121:
                    122:        /* unlink ourselves from the active threads */
                    123:        TAILQ_REMOVE(&p->p_p->ps_threads, p, p_thr_link);
                    124: #ifdef RTHREADS
                    125:        if (TAILQ_EMPTY(&p->p_p->ps_threads))
                    126:                wakeup(&p->p_p->ps_threads);
                    127:        /*
                    128:         * if one thread calls exit, we take down everybody.
                    129:         * we have to be careful not to get recursively caught.
                    130:         * this is kinda sick.
                    131:         */
                    132:        if (flags == EXIT_NORMAL && p->p_p->ps_mainproc != p &&
                    133:            (p->p_p->ps_mainproc->p_flag & P_WEXIT) == 0) {
                    134:                /*
                    135:                 * we are one of the threads.  we SIGKILL the parent,
                    136:                 * it will wake us up again, then we proceed.
                    137:                 */
                    138:                atomic_setbits_int(&p->p_p->ps_mainproc->p_flag, P_IGNEXITRV);
                    139:                p->p_p->ps_mainproc->p_xstat = rv;
                    140:                psignal(p->p_p->ps_mainproc, SIGKILL);
                    141:                tsleep(p->p_p, PUSER, "thrdying", 0);
                    142:        } else if (p == p->p_p->ps_mainproc) {
                    143:                atomic_setbits_int(&p->p_flag, P_WEXIT);
                    144:                if (flags == EXIT_NORMAL) {
                    145:                        q = TAILQ_FIRST(&p->p_p->ps_threads);
                    146:                        for (; q != NULL; q = nq) {
                    147:                                nq = TAILQ_NEXT(q, p_thr_link);
                    148:                                atomic_setbits_int(&q->p_flag, P_IGNEXITRV);
                    149:                                q->p_xstat = rv;
                    150:                                psignal(q, SIGKILL);
                    151:                        }
                    152:                }
                    153:                wakeup(p->p_p);
                    154:                while (!TAILQ_EMPTY(&p->p_p->ps_threads))
                    155:                        tsleep(&p->p_p->ps_threads, PUSER, "thrdeath", 0);
                    156:        }
                    157: #endif
                    158:
                    159:        if (p->p_flag & P_PROFIL)
                    160:                stopprofclock(p);
                    161:        p->p_ru = pool_get(&rusage_pool, PR_WAITOK);
                    162:        /*
                    163:         * If parent is waiting for us to exit or exec, P_PPWAIT is set; we
                    164:         * wake up the parent early to avoid deadlock.
                    165:         */
                    166:        atomic_setbits_int(&p->p_flag, P_WEXIT);
                    167:        atomic_clearbits_int(&p->p_flag, P_TRACED);
                    168:        if (p->p_flag & P_PPWAIT) {
                    169:                atomic_clearbits_int(&p->p_flag, P_PPWAIT);
                    170:                wakeup(p->p_pptr);
                    171:        }
                    172:        p->p_sigignore = ~0;
                    173:        p->p_siglist = 0;
                    174:        timeout_del(&p->p_realit_to);
                    175:        timeout_del(&p->p_stats->p_virt_to);
                    176:        timeout_del(&p->p_stats->p_prof_to);
                    177:
                    178:        /*
                    179:         * Close open files and release open-file table.
                    180:         * This may block!
                    181:         */
                    182:        fdfree(p);
                    183:
                    184: #ifdef SYSVSEM
                    185:        semexit(p);
                    186: #endif
                    187:        if (SESS_LEADER(p)) {
                    188:                struct session *sp = p->p_session;
                    189:
                    190:                if (sp->s_ttyvp) {
                    191:                        /*
                    192:                         * Controlling process.
                    193:                         * Signal foreground pgrp,
                    194:                         * drain controlling terminal
                    195:                         * and revoke access to controlling terminal.
                    196:                         */
                    197:                        if (sp->s_ttyp->t_session == sp) {
                    198:                                if (sp->s_ttyp->t_pgrp)
                    199:                                        pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
                    200:                                (void) ttywait(sp->s_ttyp);
                    201:                                /*
                    202:                                 * The tty could have been revoked
                    203:                                 * if we blocked.
                    204:                                 */
                    205:                                if (sp->s_ttyvp)
                    206:                                        VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
                    207:                        }
                    208:                        if (sp->s_ttyvp)
                    209:                                vrele(sp->s_ttyvp);
                    210:                        sp->s_ttyvp = NULL;
                    211:                        /*
                    212:                         * s_ttyp is not zero'd; we use this to indicate
                    213:                         * that the session once had a controlling terminal.
                    214:                         * (for logging and informational purposes)
                    215:                         */
                    216:                }
                    217:                sp->s_leader = NULL;
                    218:        }
                    219:        fixjobc(p, p->p_pgrp, 0);
                    220: #ifdef ACCOUNTING
                    221:        (void)acct_process(p);
                    222: #endif
                    223: #ifdef KTRACE
                    224:        /*
                    225:         * release trace file
                    226:         */
                    227:        p->p_traceflag = 0;     /* don't trace the vrele() */
                    228:        if (p->p_tracep)
                    229:                ktrsettracevnode(p, NULL);
                    230: #endif
                    231: #if NSYSTRACE > 0
                    232:        if (ISSET(p->p_flag, P_SYSTRACE))
                    233:                systrace_exit(p);
                    234: #endif
                    235:        /*
                    236:         * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
                    237:         */
                    238:        p->p_stat = SDEAD;
                    239:
                    240:         /*
                    241:          * Remove proc from pidhash chain so looking it up won't
                    242:          * work.  Move it from allproc to zombproc, but do not yet
                    243:          * wake up the reaper.  We will put the proc on the
                    244:          * deadproc list later (using the p_hash member), and
                    245:          * wake up the reaper when we do.
                    246:          */
                    247:        LIST_REMOVE(p, p_hash);
                    248:        LIST_REMOVE(p, p_list);
                    249:        LIST_INSERT_HEAD(&zombproc, p, p_list);
                    250:
                    251:        /*
                    252:         * Give orphaned children to init(8).
                    253:         */
                    254:        q = LIST_FIRST(&p->p_children);
                    255:        if (q)          /* only need this if any child is S_ZOMB */
                    256:                wakeup(initproc);
                    257:        for (; q != 0; q = nq) {
                    258:                nq = LIST_NEXT(q, p_sibling);
                    259:                proc_reparent(q, initproc);
                    260:                /*
                    261:                 * Traced processes are killed
                    262:                 * since their existence means someone is screwing up.
                    263:                 */
                    264:                if (q->p_flag & P_TRACED) {
                    265:                        atomic_clearbits_int(&q->p_flag, P_TRACED);
                    266:                        psignal(q, SIGKILL);
                    267:                }
                    268:        }
                    269:
                    270:
                    271:        /*
                    272:         * Save exit status and final rusage info, adding in child rusage
                    273:         * info and self times.
                    274:         */
                    275:        if (!(p->p_flag & P_IGNEXITRV))
                    276:                p->p_xstat = rv;
                    277:        *p->p_ru = p->p_stats->p_ru;
                    278:        calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL);
                    279:        ruadd(p->p_ru, &p->p_stats->p_cru);
                    280:
                    281:        /*
                    282:         * clear %cpu usage during swap
                    283:         */
                    284:        p->p_pctcpu = 0;
                    285:
                    286:        /*
                    287:         * notify interested parties of our demise.
                    288:         */
                    289:        KNOTE(&p->p_klist, NOTE_EXIT);
                    290:
                    291:        /*
                    292:         * Notify parent that we're gone.  If we have P_NOZOMBIE or parent has
                    293:         * the P_NOCLDWAIT flag set, notify process 1 instead (and hope it
                    294:         * will handle this situation).
                    295:         */
                    296:        if ((p->p_flag & P_NOZOMBIE) || (p->p_pptr->p_flag & P_NOCLDWAIT)) {
                    297:                struct proc *pp = p->p_pptr;
                    298:                proc_reparent(p, initproc);
                    299:                /*
                    300:                 * If this was the last child of our parent, notify
                    301:                 * parent, so in case he was wait(2)ing, he will
                    302:                 * continue.
                    303:                 */
                    304:                if (LIST_EMPTY(&pp->p_children))
                    305:                        wakeup(pp);
                    306:        }
                    307:
                    308:        if (p->p_exitsig != 0)
                    309:                psignal(p->p_pptr, P_EXITSIG(p));
                    310:        wakeup(p->p_pptr);
                    311:
                    312:        /*
                    313:         * Release the process's signal state.
                    314:         */
                    315:        sigactsfree(p);
                    316:
                    317:        /*
                    318:         * Clear curproc after we've done all operations
                    319:         * that could block, and before tearing down the rest
                    320:         * of the process state that might be used from clock, etc.
                    321:         * Also, can't clear curproc while we're still runnable,
                    322:         * as we're not on a run queue (we are current, just not
                    323:         * a proper proc any longer!).
                    324:         *
                    325:         * Other substructures are freed from wait().
                    326:         */
                    327:        curproc = NULL;
                    328:
                    329:        /*
                    330:         * If emulation has process exit hook, call it now.
                    331:         */
                    332:        if (p->p_emul->e_proc_exit)
                    333:                (*p->p_emul->e_proc_exit)(p);
                    334:
                    335:        /* This process no longer needs to hold the kernel lock. */
                    336:        KERNEL_PROC_UNLOCK(p);
                    337:
                    338:        /*
                    339:         * Finally, call machine-dependent code to switch to a new
                    340:         * context (possibly the idle context).  Once we are no longer
                    341:         * using the dead process's vmspace and stack, exit2() will be
                    342:         * called to schedule those resources to be released by the
                    343:         * reaper thread.
                    344:         *
                    345:         * Note that cpu_exit() will end with a call equivalent to
                    346:         * cpu_switch(), finishing our execution (pun intended).
                    347:         */
                    348:        uvmexp.swtch++;
                    349:        cpu_exit(p);
                    350: }
                    351:
                    352: /*
                    353:  * Locking of this proclist is special; it's accessed in a
                    354:  * critical section of process exit, and thus locking it can't
                    355:  * modify interrupt state.  We use a simple spin lock for this
                    356:  * proclist.  Processes on this proclist are also on zombproc;
                    357:  * we use the p_hash member to linkup to deadproc.
                    358:  */
                    359: struct mutex deadproc_mutex = MUTEX_INITIALIZER(IPL_NONE);
                    360: struct proclist deadproc = LIST_HEAD_INITIALIZER(deadproc);
                    361:
                    362: /*
                    363:  * We are called from cpu_exit() once it is safe to schedule the
                    364:  * dead process's resources to be freed.
                    365:  *
                    366:  * NOTE: One must be careful with locking in this routine.  It's
                    367:  * called from a critical section in machine-dependent code, so
                    368:  * we should refrain from changing any interrupt state.
                    369:  *
                    370:  * We lock the deadproc list, place the proc on that list (using
                    371:  * the p_hash member), and wake up the reaper.
                    372:  */
                    373: void
                    374: exit2(struct proc *p)
                    375: {
                    376:        int s;
                    377:
                    378:        mtx_enter(&deadproc_mutex);
                    379:        LIST_INSERT_HEAD(&deadproc, p, p_hash);
                    380:        mtx_leave(&deadproc_mutex);
                    381:
                    382:        wakeup(&deadproc);
                    383:
                    384:        SCHED_LOCK(s);
                    385: }
                    386:
                    387: /*
                    388:  * Process reaper.  This is run by a kernel thread to free the resources
                    389:  * of a dead process.  Once the resources are free, the process becomes
                    390:  * a zombie, and the parent is allowed to read the undead's status.
                    391:  */
                    392: void
                    393: reaper(void)
                    394: {
                    395:        struct proc *p;
                    396:
                    397:        KERNEL_PROC_UNLOCK(curproc);
                    398:
                    399:        for (;;) {
                    400:                mtx_enter(&deadproc_mutex);
                    401:                p = LIST_FIRST(&deadproc);
                    402:                if (p == NULL) {
                    403:                        /* No work for us; go to sleep until someone exits. */
                    404:                        mtx_leave(&deadproc_mutex);
                    405:                        (void) tsleep(&deadproc, PVM, "reaper", 0);
                    406:                        continue;
                    407:                }
                    408:
                    409:                /* Remove us from the deadproc list. */
                    410:                LIST_REMOVE(p, p_hash);
                    411:                mtx_leave(&deadproc_mutex);
                    412:                KERNEL_PROC_LOCK(curproc);
                    413:
                    414:                /*
                    415:                 * Give machine-dependent code a chance to free any
                    416:                 * resources it couldn't free while still running on
                    417:                 * that process's context.  This must be done before
                    418:                 * uvm_exit(), in case these resources are in the PCB.
                    419:                 */
                    420:                cpu_wait(p);
                    421:
                    422:                /*
                    423:                 * Free the VM resources we're still holding on to.
                    424:                 * We must do this from a valid thread because doing
                    425:                 * so may block.
                    426:                 */
                    427:                uvm_exit(p);
                    428:
                    429:                /* Process is now a true zombie. */
                    430:                if ((p->p_flag & P_NOZOMBIE) == 0) {
                    431:                        p->p_stat = SZOMB;
                    432:
                    433:                        /* Wake up the parent so it can get exit status. */
                    434:                        psignal(p->p_pptr, SIGCHLD);
                    435:                        wakeup(p->p_pptr);
                    436:                } else {
                    437:                        /* Noone will wait for us. Just zap the process now */
                    438:                        proc_zap(p);
                    439:                }
                    440:
                    441:                KERNEL_PROC_UNLOCK(curproc);
                    442:        }
                    443: }
                    444:
                    445: pid_t
                    446: sys_wait4(struct proc *q, void *v, register_t *retval)
                    447: {
                    448:        struct sys_wait4_args /* {
                    449:                syscallarg(pid_t) pid;
                    450:                syscallarg(int *) status;
                    451:                syscallarg(int) options;
                    452:                syscallarg(struct rusage *) rusage;
                    453:        } */ *uap = v;
                    454:        int nfound;
                    455:        struct proc *p, *t;
                    456:        int status, error;
                    457:
                    458:        if (SCARG(uap, pid) == 0)
                    459:                SCARG(uap, pid) = -q->p_pgid;
                    460:        if (SCARG(uap, options) &~ (WUNTRACED|WNOHANG|WALTSIG|WCONTINUED))
                    461:                return (EINVAL);
                    462:
                    463: loop:
                    464:        nfound = 0;
                    465:        LIST_FOREACH(p, &q->p_children, p_sibling) {
                    466:                if ((p->p_flag & P_NOZOMBIE) ||
                    467:                    (SCARG(uap, pid) != WAIT_ANY &&
                    468:                    p->p_pid != SCARG(uap, pid) &&
                    469:                    p->p_pgid != -SCARG(uap, pid)))
                    470:                        continue;
                    471:
                    472:                /*
                    473:                 * Wait for processes with p_exitsig != SIGCHLD processes only
                    474:                 * if WALTSIG is set; wait for processes with pexitsig ==
                    475:                 * SIGCHLD only if WALTSIG is clear.
                    476:                 */
                    477:                if ((SCARG(uap, options) & WALTSIG) ?
                    478:                    (p->p_exitsig == SIGCHLD) : (P_EXITSIG(p) != SIGCHLD))
                    479:                        continue;
                    480:
                    481:                nfound++;
                    482:                if (p->p_stat == SZOMB) {
                    483:                        retval[0] = p->p_pid;
                    484:
                    485:                        if (SCARG(uap, status)) {
                    486:                                status = p->p_xstat;    /* convert to int */
                    487:                                error = copyout(&status,
                    488:                                    SCARG(uap, status), sizeof(status));
                    489:                                if (error)
                    490:                                        return (error);
                    491:                        }
                    492:                        if (SCARG(uap, rusage) &&
                    493:                            (error = copyout(p->p_ru,
                    494:                            SCARG(uap, rusage), sizeof(struct rusage))))
                    495:                                return (error);
                    496:
                    497:                        /*
                    498:                         * If we got the child via a ptrace 'attach',
                    499:                         * we need to give it back to the old parent.
                    500:                         */
                    501:                        if (p->p_oppid && (t = pfind(p->p_oppid))) {
                    502:                                p->p_oppid = 0;
                    503:                                proc_reparent(p, t);
                    504:                                if (p->p_exitsig != 0)
                    505:                                        psignal(t, P_EXITSIG(p));
                    506:                                wakeup(t);
                    507:                                return (0);
                    508:                        }
                    509:
                    510:                        scheduler_wait_hook(q, p);
                    511:                        p->p_xstat = 0;
                    512:                        ruadd(&q->p_stats->p_cru, p->p_ru);
                    513:
                    514:                        proc_zap(p);
                    515:
                    516:                        return (0);
                    517:                }
                    518:                if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
                    519:                    (p->p_flag & P_TRACED || SCARG(uap, options) & WUNTRACED)) {
                    520:                        atomic_setbits_int(&p->p_flag, P_WAITED);
                    521:                        retval[0] = p->p_pid;
                    522:
                    523:                        if (SCARG(uap, status)) {
                    524:                                status = W_STOPCODE(p->p_xstat);
                    525:                                error = copyout(&status, SCARG(uap, status),
                    526:                                    sizeof(status));
                    527:                        } else
                    528:                                error = 0;
                    529:                        return (error);
                    530:                }
                    531:                if ((SCARG(uap, options) & WCONTINUED) && (p->p_flag & P_CONTINUED)) {
                    532:                        atomic_clearbits_int(&p->p_flag, P_CONTINUED);
                    533:                        retval[0] = p->p_pid;
                    534:
                    535:                        if (SCARG(uap, status)) {
                    536:                                status = _WCONTINUED;
                    537:                                error = copyout(&status, SCARG(uap, status),
                    538:                                    sizeof(status));
                    539:                        } else
                    540:                                error = 0;
                    541:                        return (error);
                    542:                }
                    543:        }
                    544:        if (nfound == 0)
                    545:                return (ECHILD);
                    546:        if (SCARG(uap, options) & WNOHANG) {
                    547:                retval[0] = 0;
                    548:                return (0);
                    549:        }
                    550:        if ((error = tsleep(q, PWAIT | PCATCH, "wait", 0)) != 0)
                    551:                return (error);
                    552:        goto loop;
                    553: }
                    554:
                    555: /*
                    556:  * make process 'parent' the new parent of process 'child'.
                    557:  */
                    558: void
                    559: proc_reparent(struct proc *child, struct proc *parent)
                    560: {
                    561:
                    562:        if (child->p_pptr == parent)
                    563:                return;
                    564:
                    565:        if (parent == initproc)
                    566:                child->p_exitsig = SIGCHLD;
                    567:
                    568:        LIST_REMOVE(child, p_sibling);
                    569:        LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
                    570:        child->p_pptr = parent;
                    571: }
                    572:
                    573: void
                    574: proc_zap(struct proc *p)
                    575: {
                    576:        pool_put(&rusage_pool, p->p_ru);
                    577:        if (p->p_ptstat)
                    578:                free(p->p_ptstat, M_SUBPROC);
                    579:
                    580:        /*
                    581:         * Finally finished with old proc entry.
                    582:         * Unlink it from its process group and free it.
                    583:         */
                    584:        leavepgrp(p);
                    585:        LIST_REMOVE(p, p_list); /* off zombproc */
                    586:        LIST_REMOVE(p, p_sibling);
                    587:
                    588:        /*
                    589:         * Decrement the count of procs running with this uid.
                    590:         */
                    591:        (void)chgproccnt(p->p_cred->p_ruid, -1);
                    592:
                    593:        /*
                    594:         * Release reference to text vnode
                    595:         */
                    596:        if (p->p_textvp)
                    597:                vrele(p->p_textvp);
                    598:
                    599:        /*
                    600:         * Remove us from our process list, possibly killing the process
                    601:         * in the process (pun intended).
                    602:         */
                    603: #if 0
                    604:        TAILQ_REMOVE(&p->p_p->ps_threads, p, p_thr_link);
                    605: #endif
                    606:        if (TAILQ_EMPTY(&p->p_p->ps_threads)) {
                    607:                limfree(p->p_p->ps_limit);
                    608:                if (--p->p_p->ps_cred->p_refcnt == 0) {
                    609:                        crfree(p->p_p->ps_cred->pc_ucred);
                    610:                        pool_put(&pcred_pool, p->p_p->ps_cred);
                    611:                }
                    612:                pool_put(&process_pool, p->p_p);
                    613:        }
                    614:
                    615:        pool_put(&proc_pool, p);
                    616:        nprocs--;
                    617: }
                    618:

CVSweb