1996c772fSJohn Dyson /* 2df8bae1dSRodney W. Grimes * Copyright (c) 1982, 1986, 1989, 1991, 1993 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * (c) UNIX System Laboratories, Inc. 5df8bae1dSRodney W. Grimes * All or some portions of this file are derived from material licensed 6df8bae1dSRodney W. Grimes * to the University of California by American Telephone and Telegraph 7df8bae1dSRodney W. Grimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8df8bae1dSRodney W. Grimes * the permission of UNIX System Laboratories, Inc. 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 19df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 20df8bae1dSRodney W. Grimes * without specific prior written permission. 21df8bae1dSRodney W. Grimes * 22df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32df8bae1dSRodney W. Grimes * SUCH DAMAGE. 33df8bae1dSRodney W. Grimes * 34df8bae1dSRodney W. Grimes * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 35df8bae1dSRodney W. Grimes */ 36df8bae1dSRodney W. Grimes 37677b542eSDavid E. O'Brien #include <sys/cdefs.h> 38677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 39677b542eSDavid E. O'Brien 405591b823SEivind Eklund #include "opt_compat.h" 41db6a20e2SGarrett Wollman #include "opt_ktrace.h" 422555374cSRobert Watson #include "opt_mac.h" 43db6a20e2SGarrett Wollman 44df8bae1dSRodney W. Grimes #include <sys/param.h> 45df8bae1dSRodney W. Grimes #include <sys/systm.h> 465fdb8324SBruce Evans #include <sys/sysproto.h> 4775b8b3b2SJohn Baldwin #include <sys/eventhandler.h> 481c5bb3eaSPeter Wemm #include <sys/kernel.h> 49a1c995b6SPoul-Henning Kamp #include <sys/malloc.h> 50f34fa851SJohn Baldwin #include <sys/lock.h> 5135e0e5b3SJohn Baldwin #include <sys/mutex.h> 52df8bae1dSRodney W. Grimes #include <sys/proc.h> 532a024a2bSSean Eric Fagan #include <sys/pioctl.h> 54df8bae1dSRodney W. Grimes #include <sys/tty.h> 55df8bae1dSRodney W. Grimes #include <sys/wait.h> 56eb30c1c0SPeter Wemm #include <sys/vmmeter.h> 577a6b989bSJohn Baldwin #include <sys/vnode.h> 58df8bae1dSRodney W. Grimes #include <sys/resourcevar.h> 59797f2d22SPoul-Henning Kamp #include <sys/signalvar.h> 60b43179fbSJeff Roberson #include <sys/sched.h> 611005a129SJohn Baldwin #include <sys/sx.h> 62df8bae1dSRodney W. Grimes #include <sys/ptrace.h> 637c409b8aSJeffrey Hsu #include <sys/acct.h> /* for acct_process() function prototype */ 64797f2d22SPoul-Henning Kamp #include <sys/filedesc.h> 652555374cSRobert Watson #include <sys/mac.h> 66780dc5a8SPeter Wemm #include <sys/shm.h> 67780dc5a8SPeter Wemm #include <sys/sem.h> 686c84de02SJohn Baldwin #ifdef KTRACE 696c84de02SJohn Baldwin #include <sys/ktrace.h> 706c84de02SJohn Baldwin #endif 71780dc5a8SPeter Wemm 72df8bae1dSRodney W. Grimes #include <vm/vm.h> 73eb30c1c0SPeter Wemm #include <vm/vm_extern.h> 747a6b989bSJohn Baldwin #include <vm/vm_param.h> 75efeaf95aSDavid Greenman #include <vm/pmap.h> 76efeaf95aSDavid Greenman #include <vm/vm_map.h> 772d21129dSAlan Cox #include <vm/vm_page.h> 78c897b813SJeff Roberson #include <vm/uma.h> 79dc9c271aSJulian Elischer #include <sys/user.h> 80df8bae1dSRodney W. Grimes 81ba198b1cSMark Newton /* Required to be non-static for SysVR4 emulator */ 8269a6f20bSMark Newton MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status"); 8355166637SPoul-Henning Kamp 84df8bae1dSRodney W. Grimes /* 85df8bae1dSRodney W. Grimes * exit -- 86df8bae1dSRodney W. Grimes * Death of process. 87234216efSMatthew Dillon * 88234216efSMatthew Dillon * MPSAFE 89df8bae1dSRodney W. Grimes */ 90fc0b1dbfSBruce Evans void 91830c3153SDag-Erling Smørgrav sys_exit(struct thread *td, struct sys_exit_args *uap) 92df8bae1dSRodney W. Grimes { 93b40ce416SJulian Elischer 94b40ce416SJulian Elischer exit1(td, W_EXITCODE(uap->rval, 0)); 95df8bae1dSRodney W. Grimes /* NOTREACHED */ 96df8bae1dSRodney W. Grimes } 97df8bae1dSRodney W. Grimes 98df8bae1dSRodney W. Grimes /* 99df8bae1dSRodney W. Grimes * Exit: deallocate address space and other resources, change proc state 100df8bae1dSRodney W. Grimes * to zombie, and unlink proc from allproc and parent's lists. Save exit 101df8bae1dSRodney W. Grimes * status and rusage for wait(). Check for child processes and orphan them. 102df8bae1dSRodney W. Grimes */ 103fc0b1dbfSBruce Evans void 104830c3153SDag-Erling Smørgrav exit1(struct thread *td, int rv) 105df8bae1dSRodney W. Grimes { 106871684b8SBruce Evans struct bintime new_switchtime; 107276c5169SJohn Baldwin struct proc *p, *nq, *q; 108276c5169SJohn Baldwin struct tty *tp; 109276c5169SJohn Baldwin struct vnode *ttyvp; 110830c3153SDag-Erling Smørgrav struct vmspace *vm; 11179deba82SMatthew Dillon struct vnode *vtmp; 112d7aadbf9SJohn Baldwin #ifdef KTRACE 113d7aadbf9SJohn Baldwin struct vnode *tracevp; 114a5881ea5SJohn Baldwin struct ucred *tracecred; 115d7aadbf9SJohn Baldwin #endif 11691d5354aSJohn Baldwin struct plimit *plim; 1171a276a3fSAlan Cox int refcnt; 118df8bae1dSRodney W. Grimes 1194ae89b95SJohn Baldwin /* 1204ae89b95SJohn Baldwin * Drop Giant if caller has it. Eventually we should warn about 1214ae89b95SJohn Baldwin * being called with Giant held. 1224ae89b95SJohn Baldwin */ 1234ae89b95SJohn Baldwin while (mtx_owned(&Giant)) 1244ae89b95SJohn Baldwin mtx_unlock(&Giant); 1250cddd8f0SMatthew Dillon 126276c5169SJohn Baldwin p = td->td_proc; 127e746d950SJohn Baldwin if (p == initproc) { 1285f7bd355SPoul-Henning Kamp printf("init died (signal %d, exit %d)\n", 129df8bae1dSRodney W. Grimes WTERMSIG(rv), WEXITSTATUS(rv)); 1305f7bd355SPoul-Henning Kamp panic("Going nowhere without my init!"); 1315f7bd355SPoul-Henning Kamp } 1322c1011f7SJohn Dyson 1337a6b989bSJohn Baldwin /* 1342c10d16aSJeff Roberson * MUST abort all other threads before proceeding past here. 1357a6b989bSJohn Baldwin */ 136e602ba25SJulian Elischer PROC_LOCK(p); 137ed062c8dSJulian Elischer if (p->p_flag & P_HADTHREADS) { 1380aabef65SDavid Xu retry: 139e602ba25SJulian Elischer /* 140e602ba25SJulian Elischer * First check if some other thread got here before us.. 141e602ba25SJulian Elischer * if so, act apropriatly, (exit or suspend); 142e602ba25SJulian Elischer */ 143e602ba25SJulian Elischer thread_suspend_check(0); 144e602ba25SJulian Elischer 145e602ba25SJulian Elischer /* 146e602ba25SJulian Elischer * Kill off the other threads. This requires 1476111dcd2SJohn Baldwin * some co-operation from other parts of the kernel 1486111dcd2SJohn Baldwin * so it may not be instantaneous. With this state set 1496111dcd2SJohn Baldwin * any thread entering the kernel from userspace will 150e602ba25SJulian Elischer * thread_exit() in trap(). Any thread attempting to 1516111dcd2SJohn Baldwin * sleep will return immediately with EINTR or EWOULDBLOCK 1526111dcd2SJohn Baldwin * which will hopefully force them to back out to userland 1536111dcd2SJohn Baldwin * freeing resources as they go. Any thread attempting 154b3248998SJulian Elischer * to return to userland will thread_exit() from userret(). 1556111dcd2SJohn Baldwin * thread_exit() will unsuspend us when the last of the 1566111dcd2SJohn Baldwin * other threads exits. 157b370279eSDavid Xu * If there is already a thread singler after resumption, 1586111dcd2SJohn Baldwin * calling thread_single will fail; in that case, we just 159b370279eSDavid Xu * re-check all suspension request, the thread should 160b370279eSDavid Xu * either be suspended there or exit. 161e602ba25SJulian Elischer */ 16237814395SPeter Wemm if (thread_single(SINGLE_EXIT)) 1630aabef65SDavid Xu goto retry; 1646111dcd2SJohn Baldwin 165e602ba25SJulian Elischer /* 166e602ba25SJulian Elischer * All other activity in this process is now stopped. 167ed062c8dSJulian Elischer * Threading support has been turned off. 168e602ba25SJulian Elischer */ 169e602ba25SJulian Elischer } 170e602ba25SJulian Elischer 171e602ba25SJulian Elischer p->p_flag |= P_WEXIT; 172e602ba25SJulian Elischer PROC_UNLOCK(p); 173b40ce416SJulian Elischer 1747a6b989bSJohn Baldwin /* Are we a task leader? */ 1752c1011f7SJohn Dyson if (p == p->p_leader) { 176c6544064SJohn Baldwin mtx_lock(&ppeers_lock); 1772c1011f7SJohn Dyson q = p->p_peers; 178776e0b36SJohn Baldwin while (q != NULL) { 179776e0b36SJohn Baldwin PROC_LOCK(q); 180776e0b36SJohn Baldwin psignal(q, SIGKILL); 181776e0b36SJohn Baldwin PROC_UNLOCK(q); 1822c1011f7SJohn Dyson q = q->p_peers; 1832c1011f7SJohn Dyson } 184c6544064SJohn Baldwin while (p->p_peers != NULL) 185c6544064SJohn Baldwin msleep(p, &ppeers_lock, PWAIT, "exit1", 0); 186c6544064SJohn Baldwin mtx_unlock(&ppeers_lock); 1872c1011f7SJohn Dyson } 1882c1011f7SJohn Dyson 1894ae89b95SJohn Baldwin PROC_LOCK(p); 1904ae89b95SJohn Baldwin _STOPEVENT(p, S_EXIT, rv); 19189361835SSean Eric Fagan wakeup(&p->p_stype); /* Wakeup anyone in procfs' PIOCWAIT */ 1924ae89b95SJohn Baldwin PROC_UNLOCK(p); 1932a024a2bSSean Eric Fagan 194fed06968SJulian Elischer /* 195e9189611SPeter Wemm * Check if any loadable modules need anything done at process exit. 1966111dcd2SJohn Baldwin * E.g. SYSV IPC stuff 197fed06968SJulian Elischer * XXX what if one of these generates an error? 198fed06968SJulian Elischer */ 19975b8b3b2SJohn Baldwin EVENTHANDLER_INVOKE(process_exit, p); 200a914fb6bSJohn Baldwin 201df8bae1dSRodney W. Grimes MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage), 202a163d034SWarner Losh M_ZOMBIE, M_WAITOK); 203df8bae1dSRodney W. Grimes /* 204df8bae1dSRodney W. Grimes * If parent is waiting for us to exit or exec, 205df8bae1dSRodney W. Grimes * P_PPWAIT is set; we will wakeup the parent below. 206df8bae1dSRodney W. Grimes */ 207a914fb6bSJohn Baldwin PROC_LOCK(p); 208a282253aSJulian Elischer stopprofclock(p); 209df8bae1dSRodney W. Grimes p->p_flag &= ~(P_TRACED | P_PPWAIT); 2101d9c5696SJuli Mallett SIGEMPTYSET(p->p_siglist); 2114093529dSJeff Roberson SIGEMPTYSET(td->td_siglist); 2125499ea01SJohn Baldwin 2135499ea01SJohn Baldwin /* 2145499ea01SJohn Baldwin * Stop the real interval timer. If the handler is currently 2155499ea01SJohn Baldwin * executing, prevent it from rearming itself and let it finish. 2165499ea01SJohn Baldwin */ 2175499ea01SJohn Baldwin if (timevalisset(&p->p_realtimer.it_value) && 2185499ea01SJohn Baldwin callout_stop(&p->p_itcallout) == 0) { 2195499ea01SJohn Baldwin timevalclear(&p->p_realtimer.it_interval); 2205499ea01SJohn Baldwin msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0); 2215499ea01SJohn Baldwin KASSERT(!timevalisset(&p->p_realtimer.it_value), 2225499ea01SJohn Baldwin ("realtime timer is still armed")); 2235499ea01SJohn Baldwin } 22496d7f8efSTim J. Robbins PROC_UNLOCK(p); 225df8bae1dSRodney W. Grimes 226df8bae1dSRodney W. Grimes /* 227831d27a9SDon Lewis * Reset any sigio structures pointing to us as a result of 228831d27a9SDon Lewis * F_SETOWN with our pid. 229831d27a9SDon Lewis */ 2304ae89b95SJohn Baldwin mtx_lock(&Giant); /* XXX: not sure if needed */ 231831d27a9SDon Lewis funsetownlst(&p->p_sigiolst); 232831d27a9SDon Lewis 233831d27a9SDon Lewis /* 234df8bae1dSRodney W. Grimes * Close open files and release open-file table. 235df8bae1dSRodney W. Grimes * This may block! 236df8bae1dSRodney W. Grimes */ 237edf6699aSAlfred Perlstein fdfree(td); 2384ae89b95SJohn Baldwin mtx_unlock(&Giant); 239df8bae1dSRodney W. Grimes 240a914fb6bSJohn Baldwin /* 241a914fb6bSJohn Baldwin * Remove ourself from our leader's peer list and wake our leader. 242a914fb6bSJohn Baldwin */ 243c6544064SJohn Baldwin mtx_lock(&ppeers_lock); 24479fc0bf4SMike Smith if (p->p_leader->p_peers) { 24579fc0bf4SMike Smith q = p->p_leader; 24679fc0bf4SMike Smith while (q->p_peers != p) 24779fc0bf4SMike Smith q = q->p_peers; 24879fc0bf4SMike Smith q->p_peers = p->p_peers; 2497f05b035SAlfred Perlstein wakeup(p->p_leader); 25079fc0bf4SMike Smith } 251c6544064SJohn Baldwin mtx_unlock(&ppeers_lock); 25279fc0bf4SMike Smith 253df8bae1dSRodney W. Grimes /* The next two chunks should probably be moved to vmspace_exit. */ 254df8bae1dSRodney W. Grimes vm = p->p_vmspace; 255df8bae1dSRodney W. Grimes /* 256df8bae1dSRodney W. Grimes * Release user portion of address space. 257df8bae1dSRodney W. Grimes * This releases references to vnodes, 258df8bae1dSRodney W. Grimes * which could cause I/O if the file has been unlinked. 259df8bae1dSRodney W. Grimes * Need to do this early enough that we can still sleep. 260df8bae1dSRodney W. Grimes * Can't free the entire vmspace as the kernel stack 261df8bae1dSRodney W. Grimes * may be mapped within that space also. 262389d2b6eSMatthew Dillon * 263389d2b6eSMatthew Dillon * Processes sharing the same vmspace may exit in one order, and 264389d2b6eSMatthew Dillon * get cleaned up by vmspace_exit() in a different order. The 265389d2b6eSMatthew Dillon * last exiting process to reach this point releases as much of 266389d2b6eSMatthew Dillon * the environment as it can, and the last process cleaned up 267389d2b6eSMatthew Dillon * by vmspace_exit() (which decrements exitingcnt) cleans up the 268389d2b6eSMatthew Dillon * remainder. 269df8bae1dSRodney W. Grimes */ 2701a276a3fSAlan Cox atomic_add_int(&vm->vm_exitingcnt, 1); 2711a276a3fSAlan Cox do 2721a276a3fSAlan Cox refcnt = vm->vm_refcnt; 2731a276a3fSAlan Cox while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1)); 2741a276a3fSAlan Cox if (refcnt == 1) { 2753db161e0SMatthew Dillon shmexit(vm); 27605ba50f5SJake Burkholder pmap_remove_pages(vmspace_pmap(vm), vm_map_min(&vm->vm_map), 27705ba50f5SJake Burkholder vm_map_max(&vm->vm_map)); 27805ba50f5SJake Burkholder (void) vm_map_remove(&vm->vm_map, vm_map_min(&vm->vm_map), 27905ba50f5SJake Burkholder vm_map_max(&vm->vm_map)); 2809d3fbbb5SJohn Dyson } 281df8bae1dSRodney W. Grimes 2821a276a3fSAlan Cox mtx_lock(&Giant); 283ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 284df8bae1dSRodney W. Grimes if (SESS_LEADER(p)) { 285830c3153SDag-Erling Smørgrav struct session *sp; 286df8bae1dSRodney W. Grimes 287f591779bSSeigo Tanimura sp = p->p_session; 288df8bae1dSRodney W. Grimes if (sp->s_ttyvp) { 289df8bae1dSRodney W. Grimes /* 290df8bae1dSRodney W. Grimes * Controlling process. 291df8bae1dSRodney W. Grimes * Signal foreground pgrp, 292df8bae1dSRodney W. Grimes * drain controlling terminal 293df8bae1dSRodney W. Grimes * and revoke access to controlling terminal. 294df8bae1dSRodney W. Grimes */ 295dd45d8adSJulian Elischer if (sp->s_ttyp && (sp->s_ttyp->t_session == sp)) { 296f591779bSSeigo Tanimura tp = sp->s_ttyp; 297f591779bSSeigo Tanimura if (sp->s_ttyp->t_pgrp) { 298f591779bSSeigo Tanimura PGRP_LOCK(sp->s_ttyp->t_pgrp); 299df8bae1dSRodney W. Grimes pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1); 300f591779bSSeigo Tanimura PGRP_UNLOCK(sp->s_ttyp->t_pgrp); 301f591779bSSeigo Tanimura } 302f591779bSSeigo Tanimura /* XXX tp should be locked. */ 303ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 304f591779bSSeigo Tanimura (void) ttywait(tp); 305ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 306df8bae1dSRodney W. Grimes /* 307df8bae1dSRodney W. Grimes * The tty could have been revoked 308df8bae1dSRodney W. Grimes * if we blocked. 309df8bae1dSRodney W. Grimes */ 310f591779bSSeigo Tanimura if (sp->s_ttyvp) { 311f591779bSSeigo Tanimura ttyvp = sp->s_ttyvp; 312f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 313df8bae1dSRodney W. Grimes sp->s_ttyvp = NULL; 314f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 315ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 316f591779bSSeigo Tanimura VOP_REVOKE(ttyvp, REVOKEALL); 317f591779bSSeigo Tanimura vrele(ttyvp); 318ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 319f591779bSSeigo Tanimura } 320f591779bSSeigo Tanimura } 321f591779bSSeigo Tanimura if (sp->s_ttyvp) { 322f591779bSSeigo Tanimura ttyvp = sp->s_ttyvp; 323f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 324f591779bSSeigo Tanimura sp->s_ttyvp = NULL; 325f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 326f591779bSSeigo Tanimura vrele(ttyvp); 327f591779bSSeigo Tanimura } 328df8bae1dSRodney W. Grimes /* 329df8bae1dSRodney W. Grimes * s_ttyp is not zero'd; we use this to indicate 330df8bae1dSRodney W. Grimes * that the session once had a controlling terminal. 331df8bae1dSRodney W. Grimes * (for logging and informational purposes) 332df8bae1dSRodney W. Grimes */ 333df8bae1dSRodney W. Grimes } 334f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 335df8bae1dSRodney W. Grimes sp->s_leader = NULL; 336f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 337f591779bSSeigo Tanimura } 338df8bae1dSRodney W. Grimes fixjobc(p, p->p_pgrp, 0); 339ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 340b40ce416SJulian Elischer (void)acct_process(td); 3414ae89b95SJohn Baldwin mtx_unlock(&Giant); 342df8bae1dSRodney W. Grimes #ifdef KTRACE 343df8bae1dSRodney W. Grimes /* 344df8bae1dSRodney W. Grimes * release trace file 345df8bae1dSRodney W. Grimes */ 346d7aadbf9SJohn Baldwin PROC_LOCK(p); 3476c84de02SJohn Baldwin mtx_lock(&ktrace_mtx); 348df8bae1dSRodney W. Grimes p->p_traceflag = 0; /* don't trace the vrele() */ 349a5881ea5SJohn Baldwin tracevp = p->p_tracevp; 350a5881ea5SJohn Baldwin p->p_tracevp = NULL; 351a5881ea5SJohn Baldwin tracecred = p->p_tracecred; 352a5881ea5SJohn Baldwin p->p_tracecred = NULL; 3536c84de02SJohn Baldwin mtx_unlock(&ktrace_mtx); 354d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 35515088317SBrian Feldman if (tracevp != NULL) { 35615088317SBrian Feldman mtx_lock(&Giant); 357d7aadbf9SJohn Baldwin vrele(tracevp); 35815088317SBrian Feldman mtx_unlock(&Giant); 35915088317SBrian Feldman } 360a5881ea5SJohn Baldwin if (tracecred != NULL) 361a5881ea5SJohn Baldwin crfree(tracecred); 362df8bae1dSRodney W. Grimes #endif 363df8bae1dSRodney W. Grimes /* 364ee42d0a9SDavid Malone * Release reference to text vnode 365ee42d0a9SDavid Malone */ 366ee42d0a9SDavid Malone if ((vtmp = p->p_textvp) != NULL) { 367ee42d0a9SDavid Malone p->p_textvp = NULL; 3684ae89b95SJohn Baldwin mtx_lock(&Giant); 369ee42d0a9SDavid Malone vrele(vtmp); 3704ae89b95SJohn Baldwin mtx_unlock(&Giant); 371ee42d0a9SDavid Malone } 372ee42d0a9SDavid Malone 373ee42d0a9SDavid Malone /* 374d7aadbf9SJohn Baldwin * Release our limits structure. 375d7aadbf9SJohn Baldwin */ 37691d5354aSJohn Baldwin PROC_LOCK(p); 37791d5354aSJohn Baldwin plim = p->p_limit; 378d7aadbf9SJohn Baldwin p->p_limit = NULL; 37991d5354aSJohn Baldwin PROC_UNLOCK(p); 38091d5354aSJohn Baldwin lim_free(plim); 381d7aadbf9SJohn Baldwin 382d7aadbf9SJohn Baldwin /* 383df8bae1dSRodney W. Grimes * Remove proc from allproc queue and pidhash chain. 384df8bae1dSRodney W. Grimes * Place onto zombproc. Unlink from parent's child list. 385df8bae1dSRodney W. Grimes */ 3861005a129SJohn Baldwin sx_xlock(&allproc_lock); 387b75356e1SJeffrey Hsu LIST_REMOVE(p, p_list); 388b75356e1SJeffrey Hsu LIST_INSERT_HEAD(&zombproc, p, p_list); 389b75356e1SJeffrey Hsu LIST_REMOVE(p, p_hash); 3901005a129SJohn Baldwin sx_xunlock(&allproc_lock); 391df8bae1dSRodney W. Grimes 3921005a129SJohn Baldwin sx_xlock(&proctree_lock); 3932e3c8fcbSPoul-Henning Kamp q = LIST_FIRST(&p->p_children); 394a914fb6bSJohn Baldwin if (q != NULL) /* only need this if any child is S_ZOMB */ 3957f05b035SAlfred Perlstein wakeup(initproc); 396a914fb6bSJohn Baldwin for (; q != NULL; q = nq) { 3972e3c8fcbSPoul-Henning Kamp nq = LIST_NEXT(q, p_sibling); 398a914fb6bSJohn Baldwin PROC_LOCK(q); 399c65437a3SJohn Baldwin proc_reparent(q, initproc); 4004ac9ae70SJulian Elischer q->p_sigparent = SIGCHLD; 401df8bae1dSRodney W. Grimes /* 402df8bae1dSRodney W. Grimes * Traced processes are killed 403df8bae1dSRodney W. Grimes * since their existence means someone is screwing up. 404df8bae1dSRodney W. Grimes */ 405df8bae1dSRodney W. Grimes if (q->p_flag & P_TRACED) { 406df8bae1dSRodney W. Grimes q->p_flag &= ~P_TRACED; 407df8bae1dSRodney W. Grimes psignal(q, SIGKILL); 408c65437a3SJohn Baldwin } 409a914fb6bSJohn Baldwin PROC_UNLOCK(q); 410df8bae1dSRodney W. Grimes } 411df8bae1dSRodney W. Grimes 412df8bae1dSRodney W. Grimes /* 413df8bae1dSRodney W. Grimes * Save exit status and final rusage info, adding in child rusage 414df8bae1dSRodney W. Grimes * info and self times. 415df8bae1dSRodney W. Grimes */ 4164ae89b95SJohn Baldwin mtx_lock(&Giant); 417d7aadbf9SJohn Baldwin PROC_LOCK(p); 418df8bae1dSRodney W. Grimes p->p_xstat = rv; 419cbf4e354SDavid Xu p->p_xthread = td; 420df8bae1dSRodney W. Grimes *p->p_ru = p->p_stats->p_ru; 4219ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 422df8bae1dSRodney W. Grimes calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL); 4239ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 424df8bae1dSRodney W. Grimes ruadd(p->p_ru, &p->p_stats->p_cru); 425df8bae1dSRodney W. Grimes 426ad3b9257SJohn-Mark Gurney mtx_unlock(&Giant); 427df8bae1dSRodney W. Grimes /* 4287a6b989bSJohn Baldwin * Notify interested parties of our demise. 429cb679c38SJonathan Lemon */ 430ad3b9257SJohn-Mark Gurney KNOTE_LOCKED(&p->p_klist, NOTE_EXIT); 4317eaec467SJohn Baldwin 4321a29c806SOlivier Houchard /* 4331a29c806SOlivier Houchard * Just delete all entries in the p_klist. At this point we won't 4341a29c806SOlivier Houchard * report any more events, and there are nasty race conditions that 4351a29c806SOlivier Houchard * can beat us if we don't. 4361a29c806SOlivier Houchard */ 437ad3b9257SJohn-Mark Gurney knlist_clear(&p->p_klist, 1); 438cb679c38SJonathan Lemon 439cb679c38SJonathan Lemon /* 440645682fdSLuoqi Chen * Notify parent that we're gone. If parent has the PS_NOCLDWAIT 441ba1551caSIan Dowse * flag set, or if the handler is set to SIG_IGN, notify process 442ba1551caSIan Dowse * 1 instead (and hope it will handle this situation). 443df8bae1dSRodney W. Grimes */ 444d7aadbf9SJohn Baldwin PROC_LOCK(p->p_pptr); 44590af4afaSJohn Baldwin mtx_lock(&p->p_pptr->p_sigacts->ps_mtx); 44690af4afaSJohn Baldwin if (p->p_pptr->p_sigacts->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) { 447276c5169SJohn Baldwin struct proc *pp; 448276c5169SJohn Baldwin 44990af4afaSJohn Baldwin mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); 450276c5169SJohn Baldwin pp = p->p_pptr; 451f591779bSSeigo Tanimura PROC_UNLOCK(pp); 452245f17d4SJoerg Wunsch proc_reparent(p, initproc); 45355b5f2a2SDon Lewis p->p_sigparent = SIGCHLD; 454f591779bSSeigo Tanimura PROC_LOCK(p->p_pptr); 455245f17d4SJoerg Wunsch /* 456245f17d4SJoerg Wunsch * If this was the last child of our parent, notify 457245f17d4SJoerg Wunsch * parent, so in case he was wait(2)ing, he will 458245f17d4SJoerg Wunsch * continue. 459245f17d4SJoerg Wunsch */ 460245f17d4SJoerg Wunsch if (LIST_EMPTY(&pp->p_children)) 4617f05b035SAlfred Perlstein wakeup(pp); 46290af4afaSJohn Baldwin } else 46390af4afaSJohn Baldwin mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); 464245f17d4SJoerg Wunsch 4656567eef7SDon Lewis if (p->p_pptr == initproc) 4666626c604SJulian Elischer psignal(p->p_pptr, SIGCHLD); 4676567eef7SDon Lewis else if (p->p_sigparent != 0) 4686567eef7SDon Lewis psignal(p->p_pptr, p->p_sigparent); 469c65437a3SJohn Baldwin PROC_UNLOCK(p->p_pptr); 470776e0b36SJohn Baldwin 471776e0b36SJohn Baldwin /* 472776e0b36SJohn Baldwin * If this is a kthread, then wakeup anyone waiting for it to exit. 473776e0b36SJohn Baldwin */ 474776e0b36SJohn Baldwin if (p->p_flag & P_KTHREAD) 4757f05b035SAlfred Perlstein wakeup(p); 476c65437a3SJohn Baldwin PROC_UNLOCK(p); 4778e2e767bSJohn Baldwin 4788e2e767bSJohn Baldwin /* 479df8bae1dSRodney W. Grimes * Finally, call machine-dependent code to release the remaining 480696058c3SJulian Elischer * resources including address space. 481582ec34cSAlfred Perlstein * The address space is released by "vmspace_exitfree(p)" in 482582ec34cSAlfred Perlstein * vm_waitproc(). 483df8bae1dSRodney W. Grimes */ 484b40ce416SJulian Elischer cpu_exit(td); 485eb30c1c0SPeter Wemm 486eb30c1c0SPeter Wemm PROC_LOCK(p); 487d7aadbf9SJohn Baldwin PROC_LOCK(p->p_pptr); 488d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 489696058c3SJulian Elischer 490eb30c1c0SPeter Wemm while (mtx_owned(&Giant)) 491c86b6ff5SJohn Baldwin mtx_unlock(&Giant); 492eb30c1c0SPeter Wemm 493eb30c1c0SPeter Wemm /* 494462f31bfSJohn Baldwin * We have to wait until after acquiring all locks before 495a9a64385SJohn Baldwin * changing p_state. We need to avoid all possible context 496a9a64385SJohn Baldwin * switches (including ones from blocking on a mutex) while 497a9a64385SJohn Baldwin * marked as a zombie. 498eb30c1c0SPeter Wemm */ 499e5bb601dSJohn Baldwin mtx_lock_spin(&sched_lock); 500e602ba25SJulian Elischer p->p_state = PRS_ZOMBIE; 501a9a64385SJohn Baldwin 502e5bb601dSJohn Baldwin critical_enter(); 503e5bb601dSJohn Baldwin mtx_unlock_spin(&sched_lock); 504eb30c1c0SPeter Wemm wakeup(p->p_pptr); 505d7aadbf9SJohn Baldwin PROC_UNLOCK(p->p_pptr); 506e5bb601dSJohn Baldwin mtx_lock_spin(&sched_lock); 507e5bb601dSJohn Baldwin critical_exit(); 508871684b8SBruce Evans 509871684b8SBruce Evans /* Do the same timestamp bookkeeping that mi_switch() would do. */ 510871684b8SBruce Evans binuptime(&new_switchtime); 511871684b8SBruce Evans bintime_add(&p->p_runtime, &new_switchtime); 512871684b8SBruce Evans bintime_sub(&p->p_runtime, PCPU_PTR(switchtime)); 513871684b8SBruce Evans PCPU_SET(switchtime, new_switchtime); 514d7aadbf9SJohn Baldwin PCPU_SET(switchticks, ticks); 515871684b8SBruce Evans cnt.v_swtch++; 516a9a64385SJohn Baldwin 51755d44f79SJulian Elischer sched_exit(p->p_pptr, td); 518f6f230feSJeff Roberson 519f6f230feSJeff Roberson /* 5207eaec467SJohn Baldwin * Hopefully no one will try to deliver a signal to the process this 521ad3b9257SJohn-Mark Gurney * late in the game. 522ad3b9257SJohn-Mark Gurney */ 523ad3b9257SJohn-Mark Gurney knlist_destroy(&p->p_klist); 524ad3b9257SJohn-Mark Gurney 525ad3b9257SJohn-Mark Gurney /* 526696058c3SJulian Elischer * Make sure the scheduler takes this thread out of its tables etc. 527e602ba25SJulian Elischer * This will also release this thread's reference to the ucred. 528696058c3SJulian Elischer * Other thread parts to release include pcb bits and such. 529e602ba25SJulian Elischer */ 530e602ba25SJulian Elischer thread_exit(); 531df8bae1dSRodney W. Grimes } 532df8bae1dSRodney W. Grimes 533b2f9e8b1SBruce Evans #ifdef COMPAT_43 534234216efSMatthew Dillon /* 535a9a64385SJohn Baldwin * The dirty work is handled by kern_wait(). 536a9a64385SJohn Baldwin * 537a9a64385SJohn Baldwin * MPSAFE. 538234216efSMatthew Dillon */ 53926f9a767SRodney W. Grimes int 540830c3153SDag-Erling Smørgrav owait(struct thread *td, struct owait_args *uap __unused) 541df8bae1dSRodney W. Grimes { 542b7e23e82SJohn Baldwin int error, status; 543df8bae1dSRodney W. Grimes 544b7e23e82SJohn Baldwin error = kern_wait(td, WAIT_ANY, &status, 0, NULL); 545b7e23e82SJohn Baldwin if (error == 0) 546b7e23e82SJohn Baldwin td->td_retval[1] = status; 547b7e23e82SJohn Baldwin return (error); 548df8bae1dSRodney W. Grimes } 549b2f9e8b1SBruce Evans #endif /* COMPAT_43 */ 550df8bae1dSRodney W. Grimes 551234216efSMatthew Dillon /* 552a9a64385SJohn Baldwin * The dirty work is handled by kern_wait(). 553a9a64385SJohn Baldwin * 554a9a64385SJohn Baldwin * MPSAFE. 555234216efSMatthew Dillon */ 55626f9a767SRodney W. Grimes int 557830c3153SDag-Erling Smørgrav wait4(struct thread *td, struct wait_args *uap) 558df8bae1dSRodney W. Grimes { 559b7e23e82SJohn Baldwin struct rusage ru; 560b7e23e82SJohn Baldwin int error, status; 561b40ce416SJulian Elischer 562b7e23e82SJohn Baldwin error = kern_wait(td, uap->pid, &status, uap->options, &ru); 563b7e23e82SJohn Baldwin if (uap->status != NULL && error == 0) 564b7e23e82SJohn Baldwin error = copyout(&status, uap->status, sizeof(status)); 565b7e23e82SJohn Baldwin if (uap->rusage != NULL && error == 0) 566b7e23e82SJohn Baldwin error = copyout(&ru, uap->rusage, sizeof(struct rusage)); 567b7e23e82SJohn Baldwin return (error); 568df8bae1dSRodney W. Grimes } 569df8bae1dSRodney W. Grimes 570b7e23e82SJohn Baldwin int 5717eaec467SJohn Baldwin kern_wait(struct thread *td, pid_t pid, int *status, int options, 5727eaec467SJohn Baldwin struct rusage *rusage) 573df8bae1dSRodney W. Grimes { 57448bfcdddSJulian Elischer struct proc *p, *q, *t; 575a9a64385SJohn Baldwin int error, nfound; 576df8bae1dSRodney W. Grimes 577b40ce416SJulian Elischer q = td->td_proc; 578b7e23e82SJohn Baldwin if (pid == 0) { 579f591779bSSeigo Tanimura PROC_LOCK(q); 580b7e23e82SJohn Baldwin pid = -q->p_pgid; 581f591779bSSeigo Tanimura PROC_UNLOCK(q); 582f591779bSSeigo Tanimura } 583b7e23e82SJohn Baldwin if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE)) 5846dc958b9SJohn Baldwin return (EINVAL); 585df8bae1dSRodney W. Grimes loop: 586df8bae1dSRodney W. Grimes nfound = 0; 587d7aadbf9SJohn Baldwin sx_xlock(&proctree_lock); 5882e3c8fcbSPoul-Henning Kamp LIST_FOREACH(p, &q->p_children, p_sibling) { 589f591779bSSeigo Tanimura PROC_LOCK(p); 590b7e23e82SJohn Baldwin if (pid != WAIT_ANY && 591b7e23e82SJohn Baldwin p->p_pid != pid && p->p_pgid != -pid) { 592f591779bSSeigo Tanimura PROC_UNLOCK(p); 593df8bae1dSRodney W. Grimes continue; 594f591779bSSeigo Tanimura } 5954ac9ae70SJulian Elischer 5961156bc4dSJake Burkholder /* 5971156bc4dSJake Burkholder * This special case handles a kthread spawned by linux_clone 5981156bc4dSJake Burkholder * (see linux_misc.c). The linux_wait4 and linux_waitpid 5991156bc4dSJake Burkholder * functions need to be able to distinguish between waiting 6001156bc4dSJake Burkholder * on a process and waiting on a thread. It is a thread if 6011156bc4dSJake Burkholder * p_sigparent is not SIGCHLD, and the WLINUXCLONE option 6021156bc4dSJake Burkholder * signifies we want to wait for threads and not processes. 6034ac9ae70SJulian Elischer */ 6041156bc4dSJake Burkholder if ((p->p_sigparent != SIGCHLD) ^ 605b7e23e82SJohn Baldwin ((options & WLINUXCLONE) != 0)) { 606a914fb6bSJohn Baldwin PROC_UNLOCK(p); 6074ac9ae70SJulian Elischer continue; 608a914fb6bSJohn Baldwin } 6094ac9ae70SJulian Elischer 610df8bae1dSRodney W. Grimes nfound++; 611e602ba25SJulian Elischer if (p->p_state == PRS_ZOMBIE) { 612b40ce416SJulian Elischer td->td_retval[0] = p->p_pid; 613b7e23e82SJohn Baldwin if (status) 614b7e23e82SJohn Baldwin *status = p->p_xstat; /* convert to int */ 615b7e23e82SJohn Baldwin if (rusage) 616b7e23e82SJohn Baldwin bcopy(p->p_ru, rusage, sizeof(struct rusage)); 617b7e23e82SJohn Baldwin 618df8bae1dSRodney W. Grimes /* 619df8bae1dSRodney W. Grimes * If we got the child via a ptrace 'attach', 620df8bae1dSRodney W. Grimes * we need to give it back to the old parent. 621df8bae1dSRodney W. Grimes */ 622b7e23e82SJohn Baldwin PROC_UNLOCK(p); 623d7aadbf9SJohn Baldwin if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) { 624c65437a3SJohn Baldwin PROC_LOCK(p); 625df8bae1dSRodney W. Grimes p->p_oppid = 0; 626df8bae1dSRodney W. Grimes proc_reparent(p, t); 627c65437a3SJohn Baldwin PROC_UNLOCK(p); 628df8bae1dSRodney W. Grimes psignal(t, SIGCHLD); 6297f05b035SAlfred Perlstein wakeup(t); 630c65437a3SJohn Baldwin PROC_UNLOCK(t); 6311005a129SJohn Baldwin sx_xunlock(&proctree_lock); 632d7aadbf9SJohn Baldwin return (0); 633df8bae1dSRodney W. Grimes } 634ebdc3f1dSSeigo Tanimura 6353890793eSTim J. Robbins /* 6363890793eSTim J. Robbins * Remove other references to this process to ensure 6373890793eSTim J. Robbins * we have an exclusive reference. 6383890793eSTim J. Robbins */ 6396ec62361STim J. Robbins sx_xlock(&allproc_lock); 6406ec62361STim J. Robbins LIST_REMOVE(p, p_list); /* off zombproc */ 6416ec62361STim J. Robbins sx_xunlock(&allproc_lock); 6426ec62361STim J. Robbins LIST_REMOVE(p, p_sibling); 6433890793eSTim J. Robbins leavepgrp(p); 644ebdc3f1dSSeigo Tanimura sx_xunlock(&proctree_lock); 645ebdc3f1dSSeigo Tanimura 646ebdc3f1dSSeigo Tanimura /* 647d7aadbf9SJohn Baldwin * As a side effect of this lock, we know that 648d7aadbf9SJohn Baldwin * all other writes to this proc are visible now, so 649d7aadbf9SJohn Baldwin * no more locking is needed for p. 650d7aadbf9SJohn Baldwin */ 6514ae89b95SJohn Baldwin mtx_lock(&Giant); 652d7aadbf9SJohn Baldwin PROC_LOCK(p); 653d7aadbf9SJohn Baldwin p->p_xstat = 0; /* XXX: why? */ 654d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 655d7aadbf9SJohn Baldwin PROC_LOCK(q); 656d7aadbf9SJohn Baldwin ruadd(&q->p_stats->p_cru, p->p_ru); 657d7aadbf9SJohn Baldwin PROC_UNLOCK(q); 658d7aadbf9SJohn Baldwin FREE(p->p_ru, M_ZOMBIE); 659d7aadbf9SJohn Baldwin p->p_ru = NULL; 6604ae89b95SJohn Baldwin mtx_unlock(&Giant); 661d7aadbf9SJohn Baldwin 662d7aadbf9SJohn Baldwin /* 663d7aadbf9SJohn Baldwin * Decrement the count of procs running with this uid. 664d7aadbf9SJohn Baldwin */ 665d7aadbf9SJohn Baldwin (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); 666d7aadbf9SJohn Baldwin 667d7aadbf9SJohn Baldwin /* 668a9a64385SJohn Baldwin * Free credentials, arguments, and sigacts. 669df8bae1dSRodney W. Grimes */ 670da654d90SPoul-Henning Kamp crfree(p->p_ucred); 67190af4afaSJohn Baldwin p->p_ucred = NULL; 672d7aadbf9SJohn Baldwin pargs_drop(p->p_args); 673d7aadbf9SJohn Baldwin p->p_args = NULL; 67490af4afaSJohn Baldwin sigacts_free(p->p_sigacts); 67590af4afaSJohn Baldwin p->p_sigacts = NULL; 67688c5ea45SJulian Elischer 677df8bae1dSRodney W. Grimes /* 678a9a64385SJohn Baldwin * Do any thread-system specific cleanups. 679e602ba25SJulian Elischer */ 680696058c3SJulian Elischer thread_wait(p); 681e602ba25SJulian Elischer 682e602ba25SJulian Elischer /* 683eb30c1c0SPeter Wemm * Give vm and machine-dependent layer a chance 684df8bae1dSRodney W. Grimes * to free anything that cpu_exit couldn't 685df8bae1dSRodney W. Grimes * release while still running in process context. 686df8bae1dSRodney W. Grimes */ 687eb30c1c0SPeter Wemm vm_waitproc(p); 6882555374cSRobert Watson #ifdef MAC 6892555374cSRobert Watson mac_destroy_proc(p); 6902555374cSRobert Watson #endif 6911faf202eSJulian Elischer KASSERT(FIRST_THREAD_IN_PROC(p), 692b7e23e82SJohn Baldwin ("kern_wait: no residual thread!")); 693c897b813SJeff Roberson uma_zfree(proc_zone, p); 694d7aadbf9SJohn Baldwin sx_xlock(&allproc_lock); 695df8bae1dSRodney W. Grimes nprocs--; 696d7aadbf9SJohn Baldwin sx_xunlock(&allproc_lock); 697d7aadbf9SJohn Baldwin return (0); 698df8bae1dSRodney W. Grimes } 699112afcb2SJohn Baldwin mtx_lock_spin(&sched_lock); 700a9a64385SJohn Baldwin if (P_SHOULDSTOP(p) && p->p_suspcount == p->p_numthreads && 701a9a64385SJohn Baldwin (p->p_flag & P_WAITED) == 0 && 702b7e23e82SJohn Baldwin (p->p_flag & P_TRACED || options & WUNTRACED)) { 703112afcb2SJohn Baldwin mtx_unlock_spin(&sched_lock); 704df8bae1dSRodney W. Grimes p->p_flag |= P_WAITED; 705d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 706b40ce416SJulian Elischer td->td_retval[0] = p->p_pid; 707b7e23e82SJohn Baldwin if (status) 708b7e23e82SJohn Baldwin *status = W_STOPCODE(p->p_xstat); 709d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 710b7e23e82SJohn Baldwin return (0); 711df8bae1dSRodney W. Grimes } 712112afcb2SJohn Baldwin mtx_unlock_spin(&sched_lock); 713b7e23e82SJohn Baldwin if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) { 7146ee093fbSMike Barcroft sx_xunlock(&proctree_lock); 7156ee093fbSMike Barcroft td->td_retval[0] = p->p_pid; 7166ee093fbSMike Barcroft p->p_flag &= ~P_CONTINUED; 7176ee093fbSMike Barcroft PROC_UNLOCK(p); 7186ee093fbSMike Barcroft 719b7e23e82SJohn Baldwin if (status) 720b7e23e82SJohn Baldwin *status = SIGCONT; 721b7e23e82SJohn Baldwin return (0); 7226ee093fbSMike Barcroft } 723d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 724d7aadbf9SJohn Baldwin } 725d7aadbf9SJohn Baldwin if (nfound == 0) { 726d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 727d7aadbf9SJohn Baldwin return (ECHILD); 728d7aadbf9SJohn Baldwin } 729b7e23e82SJohn Baldwin if (options & WNOHANG) { 730d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 731d7aadbf9SJohn Baldwin td->td_retval[0] = 0; 732d7aadbf9SJohn Baldwin return (0); 733d7aadbf9SJohn Baldwin } 734d7aadbf9SJohn Baldwin PROC_LOCK(q); 735d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 7367f05b035SAlfred Perlstein error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0); 737d7aadbf9SJohn Baldwin PROC_UNLOCK(q); 7384ae89b95SJohn Baldwin if (error) 739d7aadbf9SJohn Baldwin return (error); 740d7aadbf9SJohn Baldwin goto loop; 741d7aadbf9SJohn Baldwin } 742df8bae1dSRodney W. Grimes 743df8bae1dSRodney W. Grimes /* 74498f03f90SJake Burkholder * Make process 'parent' the new parent of process 'child'. 74598f03f90SJake Burkholder * Must be called with an exclusive hold of proctree lock. 746df8bae1dSRodney W. Grimes */ 747df8bae1dSRodney W. Grimes void 748830c3153SDag-Erling Smørgrav proc_reparent(struct proc *child, struct proc *parent) 749df8bae1dSRodney W. Grimes { 750df8bae1dSRodney W. Grimes 7514e5e677bSJohn Baldwin sx_assert(&proctree_lock, SX_XLOCKED); 752c65437a3SJohn Baldwin PROC_LOCK_ASSERT(child, MA_OWNED); 753df8bae1dSRodney W. Grimes if (child->p_pptr == parent) 754df8bae1dSRodney W. Grimes return; 755df8bae1dSRodney W. Grimes 756b75356e1SJeffrey Hsu LIST_REMOVE(child, p_sibling); 757b75356e1SJeffrey Hsu LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); 758df8bae1dSRodney W. Grimes child->p_pptr = parent; 759df8bae1dSRodney W. Grimes } 760