LCOV - code coverage report
Current view: top level - kern - kern_exit.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 258 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: kern_exit.c,v 1.169 2018/08/25 15:38:07 anton 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/sysctl.h>
      49             : #include <sys/wait.h>
      50             : #include <sys/vnode.h>
      51             : #include <sys/syslog.h>
      52             : #include <sys/malloc.h>
      53             : #include <sys/resourcevar.h>
      54             : #include <sys/ptrace.h>
      55             : #include <sys/acct.h>
      56             : #include <sys/filedesc.h>
      57             : #include <sys/signalvar.h>
      58             : #include <sys/sched.h>
      59             : #include <sys/ktrace.h>
      60             : #include <sys/pool.h>
      61             : #include <sys/mutex.h>
      62             : #include <sys/pledge.h>
      63             : #ifdef SYSVSEM
      64             : #include <sys/sem.h>
      65             : #endif
      66             : #include <sys/witness.h>
      67             : 
      68             : #include <sys/mount.h>
      69             : #include <sys/syscallargs.h>
      70             : 
      71             : #include <uvm/uvm_extern.h>
      72             : 
      73             : #include "kcov.h"
      74             : #if NKCOV > 0
      75             : #include <sys/kcov.h>
      76             : #endif
      77             : 
      78             : void    proc_finish_wait(struct proc *, struct proc *);
      79             : void    process_zap(struct process *);
      80             : void    proc_free(struct proc *);
      81             : void    unveil_destroy(struct process *ps);
      82             : 
      83             : /*
      84             :  * exit --
      85             :  *      Death of process.
      86             :  */
      87             : int
      88           0 : sys_exit(struct proc *p, void *v, register_t *retval)
      89             : {
      90             :         struct sys_exit_args /* {
      91             :                 syscallarg(int) rval;
      92           0 :         } */ *uap = v;
      93             : 
      94           0 :         exit1(p, W_EXITCODE(SCARG(uap, rval), 0), EXIT_NORMAL);
      95             :         /* NOTREACHED */
      96           0 :         return (0);
      97             : }
      98             : 
      99             : int
     100           0 : sys___threxit(struct proc *p, void *v, register_t *retval)
     101             : {
     102             :         struct sys___threxit_args /* {
     103             :                 syscallarg(pid_t *) notdead;
     104           0 :         } */ *uap = v;
     105             : 
     106           0 :         if (SCARG(uap, notdead) != NULL) {
     107           0 :                 pid_t zero = 0;
     108           0 :                 if (copyout(&zero, SCARG(uap, notdead), sizeof(zero)))
     109           0 :                         psignal(p, SIGSEGV);
     110           0 :         }
     111           0 :         exit1(p, 0, EXIT_THREAD);
     112             : 
     113           0 :         return (0);
     114             : }
     115             : 
     116             : /*
     117             :  * Exit: deallocate address space and other resources, change proc state
     118             :  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
     119             :  * status and rusage for wait().  Check for child processes and orphan them.
     120             :  */
     121             : void
     122           0 : exit1(struct proc *p, int rv, int flags)
     123             : {
     124             :         struct process *pr, *qr, *nqr;
     125             :         struct rusage *rup;
     126             : 
     127           0 :         atomic_setbits_int(&p->p_flag, P_WEXIT);
     128             : 
     129           0 :         pr = p->p_p;
     130             : 
     131             :         /* single-threaded? */
     132           0 :         if (!P_HASSIBLING(p)) {
     133             :                 flags = EXIT_NORMAL;
     134           0 :         } else {
     135             :                 /* nope, multi-threaded */
     136           0 :                 if (flags == EXIT_NORMAL)
     137           0 :                         single_thread_set(p, SINGLE_EXIT, 0);
     138           0 :                 else if (flags == EXIT_THREAD)
     139           0 :                         single_thread_check(p, 0);
     140             :         }
     141             : 
     142           0 :         if (flags == EXIT_NORMAL) {
     143           0 :                 if (pr->ps_pid == 1)
     144           0 :                         panic("init died (signal %d, exit %d)",
     145           0 :                             WTERMSIG(rv), WEXITSTATUS(rv));
     146             : 
     147           0 :                 atomic_setbits_int(&pr->ps_flags, PS_EXITING);
     148           0 :                 pr->ps_mainproc->p_xstat = rv;
     149             : 
     150             :                 /*
     151             :                  * If parent is waiting for us to exit or exec, PS_PPWAIT
     152             :                  * is set; we wake up the parent early to avoid deadlock.
     153             :                  */
     154           0 :                 if (pr->ps_flags & PS_PPWAIT) {
     155           0 :                         atomic_clearbits_int(&pr->ps_flags, PS_PPWAIT);
     156           0 :                         atomic_clearbits_int(&pr->ps_pptr->ps_flags,
     157             :                             PS_ISPWAIT);
     158           0 :                         wakeup(pr->ps_pptr);
     159           0 :                 }
     160             :         }
     161             : 
     162             :         /* unlink ourselves from the active threads */
     163           0 :         TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link);
     164           0 :         if ((p->p_flag & P_THREAD) == 0) {
     165             :                 /* main thread gotta wait because it has the pid, et al */
     166           0 :                 while (pr->ps_refcnt > 1)
     167           0 :                         tsleep(&pr->ps_threads, PUSER, "thrdeath", 0);
     168           0 :                 if (pr->ps_flags & PS_PROFIL)
     169           0 :                         stopprofclock(pr);
     170             :         }
     171             : 
     172           0 :         rup = pr->ps_ru;
     173           0 :         if (rup == NULL) {
     174           0 :                 rup = pool_get(&rusage_pool, PR_WAITOK | PR_ZERO);
     175           0 :                 if (pr->ps_ru == NULL) {
     176           0 :                         pr->ps_ru = rup;
     177           0 :                 } else {
     178           0 :                         pool_put(&rusage_pool, rup);
     179           0 :                         rup = pr->ps_ru;
     180             :                 }
     181             :         }
     182           0 :         p->p_siglist = 0;
     183             : 
     184             : #if NKCOV > 0
     185           0 :         kcov_exit(p);
     186             : #endif
     187             : 
     188           0 :         if ((p->p_flag & P_THREAD) == 0) {
     189             :                 /* close open files and release open-file table */
     190           0 :                 fdfree(p);
     191             : 
     192           0 :                 timeout_del(&pr->ps_realit_to);
     193             : #ifdef SYSVSEM
     194           0 :                 semexit(pr);
     195             : #endif
     196           0 :                 killjobc(pr);
     197             : #ifdef ACCOUNTING
     198           0 :                 acct_process(p);
     199             : #endif
     200             : 
     201             : #ifdef KTRACE
     202             :                 /* release trace file */
     203           0 :                 if (pr->ps_tracevp)
     204           0 :                         ktrcleartrace(pr);
     205             : #endif
     206             : 
     207             :                 /*
     208             :                  * If parent has the SAS_NOCLDWAIT flag set, we're not
     209             :                  * going to become a zombie.
     210             :                  */
     211           0 :                 if (pr->ps_pptr->ps_sigacts->ps_flags & SAS_NOCLDWAIT)
     212           0 :                         atomic_setbits_int(&pr->ps_flags, PS_NOZOMBIE);
     213             :         }
     214             : 
     215           0 :         p->p_fd = NULL;              /* zap the thread's copy */
     216             : 
     217             :         /*
     218             :          * Remove proc from pidhash chain and allproc so looking
     219             :          * it up won't work.  We will put the proc on the
     220             :          * deadproc list later (using the p_hash member), and
     221             :          * wake up the reaper when we do.  If this is the last
     222             :          * thread of a process that isn't PS_NOZOMBIE, we'll put
     223             :          * the process on the zombprocess list below.
     224             :          */
     225             :         /*
     226             :          * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
     227             :          */
     228           0 :         p->p_stat = SDEAD;
     229             : 
     230           0 :         LIST_REMOVE(p, p_hash);
     231           0 :         LIST_REMOVE(p, p_list);
     232             : 
     233           0 :         if ((p->p_flag & P_THREAD) == 0) {
     234           0 :                 LIST_REMOVE(pr, ps_hash);
     235           0 :                 LIST_REMOVE(pr, ps_list);
     236             : 
     237           0 :                 if ((pr->ps_flags & PS_NOZOMBIE) == 0)
     238           0 :                         LIST_INSERT_HEAD(&zombprocess, pr, ps_list);
     239             :                 else {
     240             :                         /*
     241             :                          * Not going to be a zombie, so it's now off all
     242             :                          * the lists scanned by ispidtaken(), so block
     243             :                          * fast reuse of the pid now.
     244             :                          */
     245           0 :                         freepid(pr->ps_pid);
     246             :                 }
     247             : 
     248             :                 /*
     249             :                  * Give orphaned children to init(8).
     250             :                  */
     251           0 :                 qr = LIST_FIRST(&pr->ps_children);
     252           0 :                 if (qr)         /* only need this if any child is S_ZOMB */
     253           0 :                         wakeup(initprocess);
     254           0 :                 for (; qr != 0; qr = nqr) {
     255           0 :                         nqr = LIST_NEXT(qr, ps_sibling);
     256           0 :                         proc_reparent(qr, initprocess);
     257             :                         /*
     258             :                          * Traced processes are killed since their
     259             :                          * existence means someone is screwing up.
     260             :                          */
     261           0 :                         if (qr->ps_flags & PS_TRACED &&
     262           0 :                             !(qr->ps_flags & PS_EXITING)) {
     263           0 :                                 atomic_clearbits_int(&qr->ps_flags, PS_TRACED);
     264             :                                 /*
     265             :                                  * If single threading is active,
     266             :                                  * direct the signal to the active
     267             :                                  * thread to avoid deadlock.
     268             :                                  */
     269           0 :                                 if (qr->ps_single)
     270           0 :                                         ptsignal(qr->ps_single, SIGKILL,
     271             :                                             STHREAD);
     272             :                                 else
     273           0 :                                         prsignal(qr, SIGKILL);
     274             :                         }
     275             :                 }
     276             :         }
     277             : 
     278             :         /* add thread's accumulated rusage into the process's total */
     279           0 :         ruadd(rup, &p->p_ru);
     280           0 :         tuagg(pr, p);
     281             : 
     282             :         /*
     283             :          * clear %cpu usage during swap
     284             :          */
     285           0 :         p->p_pctcpu = 0;
     286             : 
     287           0 :         if ((p->p_flag & P_THREAD) == 0) {
     288             :                 /*
     289             :                  * Final thread has died, so add on our children's rusage
     290             :                  * and calculate the total times
     291             :                  */
     292           0 :                 calcru(&pr->ps_tu, &rup->ru_utime, &rup->ru_stime, NULL);
     293           0 :                 ruadd(rup, &pr->ps_cru);
     294             : 
     295             :                 /* notify interested parties of our demise and clean up */
     296           0 :                 knote_processexit(p);
     297             : 
     298             :                 /*
     299             :                  * Notify parent that we're gone.  If we're not going to
     300             :                  * become a zombie, reparent to process 1 (init) so that
     301             :                  * we can wake our original parent to possibly unblock
     302             :                  * wait4() to return ECHILD.
     303             :                  */
     304           0 :                 if (pr->ps_flags & PS_NOZOMBIE) {
     305           0 :                         struct process *ppr = pr->ps_pptr;
     306           0 :                         proc_reparent(pr, initprocess);
     307           0 :                         wakeup(ppr);
     308           0 :                 }
     309             : 
     310             :                 /*
     311             :                  * Release the process's signal state.
     312             :                  */
     313           0 :                 sigactsfree(pr);
     314           0 :         }
     315             : 
     316             :         /* just a thread? detach it from its process */
     317           0 :         if (p->p_flag & P_THREAD) {
     318             :                 /* scheduler_wait_hook(pr->ps_mainproc, p); XXX */
     319           0 :                 if (--pr->ps_refcnt == 1)
     320           0 :                         wakeup(&pr->ps_threads);
     321           0 :                 KASSERT(pr->ps_refcnt > 0);
     322             :         }
     323             : 
     324             :         /*
     325             :          * Other substructures are freed from reaper and wait().
     326             :          */
     327             : 
     328             :         /*
     329             :          * Finally, call machine-dependent code to switch to a new
     330             :          * context (possibly the idle context).  Once we are no longer
     331             :          * using the dead process's vmspace and stack, exit2() will be
     332             :          * called to schedule those resources to be released by the
     333             :          * reaper thread.
     334             :          *
     335             :          * Note that cpu_exit() will end with a call equivalent to
     336             :          * cpu_switch(), finishing our execution (pun intended).
     337             :          */
     338           0 :         uvmexp.swtch++;
     339           0 :         cpu_exit(p);
     340           0 :         panic("cpu_exit returned");
     341             : }
     342             : 
     343             : /*
     344             :  * Locking of this proclist is special; it's accessed in a
     345             :  * critical section of process exit, and thus locking it can't
     346             :  * modify interrupt state.  We use a simple spin lock for this
     347             :  * proclist.  We use the p_hash member to linkup to deadproc.
     348             :  */
     349             : struct mutex deadproc_mutex =
     350             :     MUTEX_INITIALIZER_FLAGS(IPL_NONE, NULL, MTX_NOWITNESS);
     351             : struct proclist deadproc = LIST_HEAD_INITIALIZER(deadproc);
     352             : 
     353             : /*
     354             :  * We are called from cpu_exit() once it is safe to schedule the
     355             :  * dead process's resources to be freed.
     356             :  *
     357             :  * NOTE: One must be careful with locking in this routine.  It's
     358             :  * called from a critical section in machine-dependent code, so
     359             :  * we should refrain from changing any interrupt state.
     360             :  *
     361             :  * We lock the deadproc list, place the proc on that list (using
     362             :  * the p_hash member), and wake up the reaper.
     363             :  */
     364             : void
     365           0 : exit2(struct proc *p)
     366             : {
     367           0 :         mtx_enter(&deadproc_mutex);
     368           0 :         LIST_INSERT_HEAD(&deadproc, p, p_hash);
     369           0 :         mtx_leave(&deadproc_mutex);
     370             : 
     371           0 :         wakeup(&deadproc);
     372           0 : }
     373             : 
     374             : void
     375           0 : proc_free(struct proc *p)
     376             : {
     377           0 :         crfree(p->p_ucred);
     378           0 :         pool_put(&proc_pool, p);
     379           0 :         nthreads--;
     380           0 : }
     381             : 
     382             : /*
     383             :  * Process reaper.  This is run by a kernel thread to free the resources
     384             :  * of a dead process.  Once the resources are free, the process becomes
     385             :  * a zombie, and the parent is allowed to read the undead's status.
     386             :  */
     387             : void
     388           0 : reaper(void *arg)
     389             : {
     390             :         struct proc *p;
     391             : 
     392           0 :         KERNEL_UNLOCK();
     393             : 
     394           0 :         SCHED_ASSERT_UNLOCKED();
     395             : 
     396           0 :         for (;;) {
     397           0 :                 mtx_enter(&deadproc_mutex);
     398           0 :                 while ((p = LIST_FIRST(&deadproc)) == NULL)
     399           0 :                         msleep(&deadproc, &deadproc_mutex, PVM, "reaper", 0);
     400             : 
     401             :                 /* Remove us from the deadproc list. */
     402           0 :                 LIST_REMOVE(p, p_hash);
     403           0 :                 mtx_leave(&deadproc_mutex);
     404             : 
     405             :                 WITNESS_THREAD_EXIT(p);
     406             : 
     407           0 :                 KERNEL_LOCK();
     408             : 
     409             :                 /*
     410             :                  * Free the VM resources we're still holding on to.
     411             :                  * We must do this from a valid thread because doing
     412             :                  * so may block.
     413             :                  */
     414           0 :                 uvm_uarea_free(p);
     415           0 :                 p->p_vmspace = NULL;         /* zap the thread's copy */
     416             : 
     417           0 :                 if (p->p_flag & P_THREAD) {
     418             :                         /* Just a thread */
     419           0 :                         proc_free(p);
     420           0 :                 } else {
     421           0 :                         struct process *pr = p->p_p;
     422             : 
     423             :                         /* Release the rest of the process's vmspace */
     424           0 :                         uvm_exit(pr);
     425             : 
     426           0 :                         if ((pr->ps_flags & PS_NOZOMBIE) == 0) {
     427             :                                 /* Process is now a true zombie. */
     428           0 :                                 atomic_setbits_int(&pr->ps_flags, PS_ZOMBIE);
     429           0 :                                 prsignal(pr->ps_pptr, SIGCHLD);
     430             : 
     431             :                                 /* Wake up the parent so it can get exit status. */
     432           0 :                                 wakeup(pr->ps_pptr);
     433           0 :                         } else {
     434             :                                 /* No one will wait for us. Just zap the process now */
     435           0 :                                 process_zap(pr);
     436             :                         }
     437             :                 }
     438             : 
     439           0 :                 KERNEL_UNLOCK();
     440             :         }
     441             : }
     442             : 
     443             : int
     444           0 : sys_wait4(struct proc *q, void *v, register_t *retval)
     445             : {
     446             :         struct sys_wait4_args /* {
     447             :                 syscallarg(pid_t) pid;
     448             :                 syscallarg(int *) status;
     449             :                 syscallarg(int) options;
     450             :                 syscallarg(struct rusage *) rusage;
     451           0 :         } */ *uap = v;
     452           0 :         struct rusage ru;
     453           0 :         int status, error;
     454             : 
     455           0 :         error = dowait4(q, SCARG(uap, pid),
     456           0 :             SCARG(uap, status) ? &status : NULL,
     457           0 :             SCARG(uap, options), SCARG(uap, rusage) ? &ru : NULL, retval);
     458           0 :         if (error == 0 && retval[0] > 0 && SCARG(uap, status)) {
     459           0 :                 error = copyout(&status, SCARG(uap, status), sizeof(status));
     460           0 :         }
     461           0 :         if (error == 0 && retval[0] > 0 && SCARG(uap, rusage)) {
     462           0 :                 error = copyout(&ru, SCARG(uap, rusage), sizeof(ru));
     463             : #ifdef KTRACE
     464           0 :                 if (error == 0 && KTRPOINT(q, KTR_STRUCT))
     465           0 :                         ktrrusage(q, &ru);
     466             : #endif
     467             :         }
     468           0 :         return (error);
     469           0 : }
     470             : 
     471             : int
     472           0 : dowait4(struct proc *q, pid_t pid, int *statusp, int options,
     473             :     struct rusage *rusage, register_t *retval)
     474             : {
     475             :         int nfound;
     476             :         struct process *pr;
     477             :         struct proc *p;
     478             :         int error;
     479             : 
     480           0 :         if (pid == 0)
     481           0 :                 pid = -q->p_p->ps_pgid;
     482           0 :         if (options &~ (WUNTRACED|WNOHANG|WCONTINUED))
     483           0 :                 return (EINVAL);
     484             : 
     485             : loop:
     486             :         nfound = 0;
     487           0 :         LIST_FOREACH(pr, &q->p_p->ps_children, ps_sibling) {
     488           0 :                 if ((pr->ps_flags & PS_NOZOMBIE) ||
     489           0 :                     (pid != WAIT_ANY &&
     490           0 :                     pr->ps_pid != pid &&
     491           0 :                     pr->ps_pgid != -pid))
     492             :                         continue;
     493             : 
     494           0 :                 p = pr->ps_mainproc;
     495             : 
     496           0 :                 nfound++;
     497           0 :                 if (pr->ps_flags & PS_ZOMBIE) {
     498           0 :                         retval[0] = pr->ps_pid;
     499             : 
     500           0 :                         if (statusp != NULL)
     501           0 :                                 *statusp = p->p_xstat;       /* convert to int */
     502           0 :                         if (rusage != NULL)
     503           0 :                                 memcpy(rusage, pr->ps_ru, sizeof(*rusage));
     504           0 :                         proc_finish_wait(q, p);
     505           0 :                         return (0);
     506             :                 }
     507           0 :                 if (pr->ps_flags & PS_TRACED &&
     508           0 :                     (pr->ps_flags & PS_WAITED) == 0 && pr->ps_single &&
     509           0 :                     pr->ps_single->p_stat == SSTOP &&
     510           0 :                     (pr->ps_single->p_flag & P_SUSPSINGLE) == 0) {
     511           0 :                         single_thread_wait(pr);
     512             : 
     513           0 :                         atomic_setbits_int(&pr->ps_flags, PS_WAITED);
     514           0 :                         retval[0] = pr->ps_pid;
     515             : 
     516           0 :                         if (statusp != NULL)
     517           0 :                                 *statusp = W_STOPCODE(pr->ps_single->p_xstat);
     518           0 :                         if (rusage != NULL)
     519           0 :                                 memset(rusage, 0, sizeof(*rusage));
     520           0 :                         return (0);
     521             :                 }
     522           0 :                 if (p->p_stat == SSTOP &&
     523           0 :                     (pr->ps_flags & PS_WAITED) == 0 &&
     524           0 :                     (p->p_flag & P_SUSPSINGLE) == 0 &&
     525           0 :                     (pr->ps_flags & PS_TRACED ||
     526           0 :                     options & WUNTRACED)) {
     527           0 :                         atomic_setbits_int(&pr->ps_flags, PS_WAITED);
     528           0 :                         retval[0] = pr->ps_pid;
     529             : 
     530           0 :                         if (statusp != NULL)
     531           0 :                                 *statusp = W_STOPCODE(p->p_xstat);
     532           0 :                         if (rusage != NULL)
     533           0 :                                 memset(rusage, 0, sizeof(*rusage));
     534           0 :                         return (0);
     535             :                 }
     536           0 :                 if ((options & WCONTINUED) && (p->p_flag & P_CONTINUED)) {
     537           0 :                         atomic_clearbits_int(&p->p_flag, P_CONTINUED);
     538           0 :                         retval[0] = pr->ps_pid;
     539             : 
     540           0 :                         if (statusp != NULL)
     541           0 :                                 *statusp = _WCONTINUED;
     542           0 :                         if (rusage != NULL)
     543           0 :                                 memset(rusage, 0, sizeof(*rusage));
     544           0 :                         return (0);
     545             :                 }
     546             :         }
     547           0 :         if (nfound == 0)
     548           0 :                 return (ECHILD);
     549           0 :         if (options & WNOHANG) {
     550           0 :                 retval[0] = 0;
     551           0 :                 return (0);
     552             :         }
     553           0 :         if ((error = tsleep(q->p_p, PWAIT | PCATCH, "wait", 0)) != 0)
     554           0 :                 return (error);
     555           0 :         goto loop;
     556           0 : }
     557             : 
     558             : void
     559           0 : proc_finish_wait(struct proc *waiter, struct proc *p)
     560             : {
     561             :         struct process *pr, *tr;
     562             :         struct rusage *rup;
     563             : 
     564             :         /*
     565             :          * If we got the child via a ptrace 'attach',
     566             :          * we need to give it back to the old parent.
     567             :          */
     568           0 :         pr = p->p_p;
     569           0 :         if (pr->ps_oppid && (tr = prfind(pr->ps_oppid))) {
     570           0 :                 atomic_clearbits_int(&pr->ps_flags, PS_TRACED);
     571           0 :                 pr->ps_oppid = 0;
     572           0 :                 proc_reparent(pr, tr);
     573           0 :                 prsignal(tr, SIGCHLD);
     574           0 :                 wakeup(tr);
     575           0 :         } else {
     576           0 :                 scheduler_wait_hook(waiter, p);
     577           0 :                 p->p_xstat = 0;
     578           0 :                 rup = &waiter->p_p->ps_cru;
     579           0 :                 ruadd(rup, pr->ps_ru);
     580           0 :                 LIST_REMOVE(pr, ps_list);       /* off zombprocess */
     581           0 :                 freepid(pr->ps_pid);
     582           0 :                 process_zap(pr);
     583             :         }
     584           0 : }
     585             : 
     586             : /*
     587             :  * make process 'parent' the new parent of process 'child'.
     588             :  */
     589             : void
     590           0 : proc_reparent(struct process *child, struct process *parent)
     591             : {
     592             : 
     593           0 :         if (child->ps_pptr == parent)
     594             :                 return;
     595             : 
     596           0 :         LIST_REMOVE(child, ps_sibling);
     597           0 :         LIST_INSERT_HEAD(&parent->ps_children, child, ps_sibling);
     598           0 :         child->ps_pptr = parent;
     599           0 : }
     600             : 
     601             : void
     602           0 : process_zap(struct process *pr)
     603             : {
     604             :         struct vnode *otvp;
     605           0 :         struct proc *p = pr->ps_mainproc;
     606             : 
     607             :         /*
     608             :          * Finally finished with old proc entry.
     609             :          * Unlink it from its process group and free it.
     610             :          */
     611           0 :         leavepgrp(pr);
     612           0 :         LIST_REMOVE(pr, ps_sibling);
     613             : 
     614             :         /*
     615             :          * Decrement the count of procs running with this uid.
     616             :          */
     617           0 :         (void)chgproccnt(pr->ps_ucred->cr_ruid, -1);
     618             : 
     619           0 :         unveil_destroy(pr);
     620             : 
     621             :         /*
     622             :          * Release reference to text vnode
     623             :          */
     624           0 :         otvp = pr->ps_textvp;
     625           0 :         pr->ps_textvp = NULL;
     626           0 :         if (otvp)
     627           0 :                 vrele(otvp);
     628             : 
     629           0 :         KASSERT(pr->ps_refcnt == 1);
     630           0 :         if (pr->ps_ptstat != NULL)
     631           0 :                 free(pr->ps_ptstat, M_SUBPROC, sizeof(*pr->ps_ptstat));
     632           0 :         pool_put(&rusage_pool, pr->ps_ru);
     633           0 :         KASSERT(TAILQ_EMPTY(&pr->ps_threads));
     634           0 :         limfree(pr->ps_limit);
     635           0 :         crfree(pr->ps_ucred);
     636           0 :         pool_put(&process_pool, pr);
     637           0 :         nprocesses--;
     638             : 
     639           0 :         proc_free(p);
     640           0 : }

Generated by: LCOV version 1.13