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; 117df8bae1dSRodney W. Grimes 1184ae89b95SJohn Baldwin /* 1194ae89b95SJohn Baldwin * Drop Giant if caller has it. Eventually we should warn about 1204ae89b95SJohn Baldwin * being called with Giant held. 1214ae89b95SJohn Baldwin */ 1224ae89b95SJohn Baldwin while (mtx_owned(&Giant)) 1234ae89b95SJohn Baldwin mtx_unlock(&Giant); 1240cddd8f0SMatthew Dillon 125276c5169SJohn Baldwin p = td->td_proc; 126e746d950SJohn Baldwin if (p == initproc) { 1275f7bd355SPoul-Henning Kamp printf("init died (signal %d, exit %d)\n", 128df8bae1dSRodney W. Grimes WTERMSIG(rv), WEXITSTATUS(rv)); 1295f7bd355SPoul-Henning Kamp panic("Going nowhere without my init!"); 1305f7bd355SPoul-Henning Kamp } 1312c1011f7SJohn Dyson 1327a6b989bSJohn Baldwin /* 1332c10d16aSJeff Roberson * MUST abort all other threads before proceeding past here. 1347a6b989bSJohn Baldwin */ 135e602ba25SJulian Elischer PROC_LOCK(p); 1360e2a4d3aSDavid Xu if (p->p_flag & P_SA || p->p_numthreads > 1) { 1370aabef65SDavid Xu retry: 138e602ba25SJulian Elischer /* 139e602ba25SJulian Elischer * First check if some other thread got here before us.. 140e602ba25SJulian Elischer * if so, act apropriatly, (exit or suspend); 141e602ba25SJulian Elischer */ 142e602ba25SJulian Elischer thread_suspend_check(0); 143e602ba25SJulian Elischer 144e602ba25SJulian Elischer /* 145e602ba25SJulian Elischer * Kill off the other threads. This requires 146e602ba25SJulian Elischer * Some co-operation from other parts of the kernel 147e602ba25SJulian Elischer * so it may not be instant. 148e602ba25SJulian Elischer * With this state set: 149e602ba25SJulian Elischer * Any thread entering the kernel from userspace will 150e602ba25SJulian Elischer * thread_exit() in trap(). Any thread attempting to 151b3248998SJulian Elischer * sleep will return immediatly with EINTR or EWOULDBLOCK, 152b3248998SJulian Elischer * which will hopefully force them to back out to userland, 153b3248998SJulian Elischer * freeing resources as they go, and anything attempting 154b3248998SJulian Elischer * to return to userland will thread_exit() from userret(). 155b3248998SJulian Elischer * thread_exit() will unsuspend us when the last other 156b3248998SJulian Elischer * thread exits. 157b370279eSDavid Xu * If there is already a thread singler after resumption, 158b370279eSDavid Xu * calling thread_single will fail, in the 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; 164e602ba25SJulian Elischer /* 165e602ba25SJulian Elischer * All other activity in this process is now stopped. 166e602ba25SJulian Elischer * Remove excess KSEs and KSEGRPS. XXXKSE (when we have them) 167e602ba25SJulian Elischer * ... 168e602ba25SJulian Elischer * Turn off threading support. 169e602ba25SJulian Elischer */ 1700e2a4d3aSDavid Xu p->p_flag &= ~P_SA; 171aa0aa7a1STim J. Robbins td->td_pflags &= ~TDP_SA; 172e602ba25SJulian Elischer thread_single_end(); /* Don't need this any more. */ 173e602ba25SJulian Elischer } 174e602ba25SJulian Elischer 175e602ba25SJulian Elischer p->p_flag |= P_WEXIT; 176e602ba25SJulian Elischer PROC_UNLOCK(p); 177b40ce416SJulian Elischer 1787a6b989bSJohn Baldwin /* Are we a task leader? */ 1792c1011f7SJohn Dyson if (p == p->p_leader) { 180c6544064SJohn Baldwin mtx_lock(&ppeers_lock); 1812c1011f7SJohn Dyson q = p->p_peers; 182776e0b36SJohn Baldwin while (q != NULL) { 183776e0b36SJohn Baldwin PROC_LOCK(q); 184776e0b36SJohn Baldwin psignal(q, SIGKILL); 185776e0b36SJohn Baldwin PROC_UNLOCK(q); 1862c1011f7SJohn Dyson q = q->p_peers; 1872c1011f7SJohn Dyson } 188c6544064SJohn Baldwin while (p->p_peers != NULL) 189c6544064SJohn Baldwin msleep(p, &ppeers_lock, PWAIT, "exit1", 0); 190c6544064SJohn Baldwin mtx_unlock(&ppeers_lock); 1912c1011f7SJohn Dyson } 1922c1011f7SJohn Dyson 1934ae89b95SJohn Baldwin PROC_LOCK(p); 1944ae89b95SJohn Baldwin _STOPEVENT(p, S_EXIT, rv); 19589361835SSean Eric Fagan wakeup(&p->p_stype); /* Wakeup anyone in procfs' PIOCWAIT */ 1964ae89b95SJohn Baldwin PROC_UNLOCK(p); 1972a024a2bSSean Eric Fagan 198fed06968SJulian Elischer /* 199e9189611SPeter Wemm * Check if any loadable modules need anything done at process exit. 200fed06968SJulian Elischer * e.g. SYSV IPC stuff 201fed06968SJulian Elischer * XXX what if one of these generates an error? 202fed06968SJulian Elischer */ 20375b8b3b2SJohn Baldwin EVENTHANDLER_INVOKE(process_exit, p); 204a914fb6bSJohn Baldwin 205df8bae1dSRodney W. Grimes MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage), 206a163d034SWarner Losh M_ZOMBIE, M_WAITOK); 207df8bae1dSRodney W. Grimes /* 208df8bae1dSRodney W. Grimes * If parent is waiting for us to exit or exec, 209df8bae1dSRodney W. Grimes * P_PPWAIT is set; we will wakeup the parent below. 210df8bae1dSRodney W. Grimes */ 211a914fb6bSJohn Baldwin PROC_LOCK(p); 212a282253aSJulian Elischer stopprofclock(p); 213df8bae1dSRodney W. Grimes p->p_flag &= ~(P_TRACED | P_PPWAIT); 2141d9c5696SJuli Mallett SIGEMPTYSET(p->p_siglist); 2154093529dSJeff Roberson SIGEMPTYSET(td->td_siglist); 2165499ea01SJohn Baldwin 2175499ea01SJohn Baldwin /* 2185499ea01SJohn Baldwin * Stop the real interval timer. If the handler is currently 2195499ea01SJohn Baldwin * executing, prevent it from rearming itself and let it finish. 2205499ea01SJohn Baldwin */ 2215499ea01SJohn Baldwin if (timevalisset(&p->p_realtimer.it_value) && 2225499ea01SJohn Baldwin callout_stop(&p->p_itcallout) == 0) { 2235499ea01SJohn Baldwin timevalclear(&p->p_realtimer.it_interval); 2245499ea01SJohn Baldwin msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0); 2255499ea01SJohn Baldwin KASSERT(!timevalisset(&p->p_realtimer.it_value), 2265499ea01SJohn Baldwin ("realtime timer is still armed")); 2275499ea01SJohn Baldwin } 22896d7f8efSTim J. Robbins PROC_UNLOCK(p); 229df8bae1dSRodney W. Grimes 230df8bae1dSRodney W. Grimes /* 231831d27a9SDon Lewis * Reset any sigio structures pointing to us as a result of 232831d27a9SDon Lewis * F_SETOWN with our pid. 233831d27a9SDon Lewis */ 2344ae89b95SJohn Baldwin mtx_lock(&Giant); /* XXX: not sure if needed */ 235831d27a9SDon Lewis funsetownlst(&p->p_sigiolst); 236831d27a9SDon Lewis 237831d27a9SDon Lewis /* 238df8bae1dSRodney W. Grimes * Close open files and release open-file table. 239df8bae1dSRodney W. Grimes * This may block! 240df8bae1dSRodney W. Grimes */ 241edf6699aSAlfred Perlstein fdfree(td); 2424ae89b95SJohn Baldwin mtx_unlock(&Giant); 243df8bae1dSRodney W. Grimes 244a914fb6bSJohn Baldwin /* 245a914fb6bSJohn Baldwin * Remove ourself from our leader's peer list and wake our leader. 246a914fb6bSJohn Baldwin */ 247c6544064SJohn Baldwin mtx_lock(&ppeers_lock); 24879fc0bf4SMike Smith if (p->p_leader->p_peers) { 24979fc0bf4SMike Smith q = p->p_leader; 25079fc0bf4SMike Smith while (q->p_peers != p) 25179fc0bf4SMike Smith q = q->p_peers; 25279fc0bf4SMike Smith q->p_peers = p->p_peers; 2537f05b035SAlfred Perlstein wakeup(p->p_leader); 25479fc0bf4SMike Smith } 255c6544064SJohn Baldwin mtx_unlock(&ppeers_lock); 25679fc0bf4SMike Smith 2574ae89b95SJohn Baldwin mtx_lock(&Giant); 258df8bae1dSRodney W. Grimes /* The next two chunks should probably be moved to vmspace_exit. */ 259df8bae1dSRodney W. Grimes vm = p->p_vmspace; 260df8bae1dSRodney W. Grimes /* 261df8bae1dSRodney W. Grimes * Release user portion of address space. 262df8bae1dSRodney W. Grimes * This releases references to vnodes, 263df8bae1dSRodney W. Grimes * which could cause I/O if the file has been unlinked. 264df8bae1dSRodney W. Grimes * Need to do this early enough that we can still sleep. 265df8bae1dSRodney W. Grimes * Can't free the entire vmspace as the kernel stack 266df8bae1dSRodney W. Grimes * may be mapped within that space also. 267389d2b6eSMatthew Dillon * 268389d2b6eSMatthew Dillon * Processes sharing the same vmspace may exit in one order, and 269389d2b6eSMatthew Dillon * get cleaned up by vmspace_exit() in a different order. The 270389d2b6eSMatthew Dillon * last exiting process to reach this point releases as much of 271389d2b6eSMatthew Dillon * the environment as it can, and the last process cleaned up 272389d2b6eSMatthew Dillon * by vmspace_exit() (which decrements exitingcnt) cleans up the 273389d2b6eSMatthew Dillon * remainder. 274df8bae1dSRodney W. Grimes */ 275389d2b6eSMatthew Dillon ++vm->vm_exitingcnt; 276582ec34cSAlfred Perlstein if (--vm->vm_refcnt == 0) { 2773db161e0SMatthew Dillon shmexit(vm); 27805ba50f5SJake Burkholder pmap_remove_pages(vmspace_pmap(vm), vm_map_min(&vm->vm_map), 27905ba50f5SJake Burkholder vm_map_max(&vm->vm_map)); 28005ba50f5SJake Burkholder (void) vm_map_remove(&vm->vm_map, vm_map_min(&vm->vm_map), 28105ba50f5SJake Burkholder vm_map_max(&vm->vm_map)); 2829d3fbbb5SJohn Dyson } 283df8bae1dSRodney W. Grimes 284ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 285df8bae1dSRodney W. Grimes if (SESS_LEADER(p)) { 286830c3153SDag-Erling Smørgrav struct session *sp; 287df8bae1dSRodney W. Grimes 288f591779bSSeigo Tanimura sp = p->p_session; 289df8bae1dSRodney W. Grimes if (sp->s_ttyvp) { 290df8bae1dSRodney W. Grimes /* 291df8bae1dSRodney W. Grimes * Controlling process. 292df8bae1dSRodney W. Grimes * Signal foreground pgrp, 293df8bae1dSRodney W. Grimes * drain controlling terminal 294df8bae1dSRodney W. Grimes * and revoke access to controlling terminal. 295df8bae1dSRodney W. Grimes */ 296dd45d8adSJulian Elischer if (sp->s_ttyp && (sp->s_ttyp->t_session == sp)) { 297f591779bSSeigo Tanimura tp = sp->s_ttyp; 298f591779bSSeigo Tanimura if (sp->s_ttyp->t_pgrp) { 299f591779bSSeigo Tanimura PGRP_LOCK(sp->s_ttyp->t_pgrp); 300df8bae1dSRodney W. Grimes pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1); 301f591779bSSeigo Tanimura PGRP_UNLOCK(sp->s_ttyp->t_pgrp); 302f591779bSSeigo Tanimura } 303f591779bSSeigo Tanimura /* XXX tp should be locked. */ 304ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 305f591779bSSeigo Tanimura (void) ttywait(tp); 306ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 307df8bae1dSRodney W. Grimes /* 308df8bae1dSRodney W. Grimes * The tty could have been revoked 309df8bae1dSRodney W. Grimes * if we blocked. 310df8bae1dSRodney W. Grimes */ 311f591779bSSeigo Tanimura if (sp->s_ttyvp) { 312f591779bSSeigo Tanimura ttyvp = sp->s_ttyvp; 313f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 314df8bae1dSRodney W. Grimes sp->s_ttyvp = NULL; 315f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 316ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 317f591779bSSeigo Tanimura VOP_REVOKE(ttyvp, REVOKEALL); 318f591779bSSeigo Tanimura vrele(ttyvp); 319ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 320f591779bSSeigo Tanimura } 321f591779bSSeigo Tanimura } 322f591779bSSeigo Tanimura if (sp->s_ttyvp) { 323f591779bSSeigo Tanimura ttyvp = sp->s_ttyvp; 324f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 325f591779bSSeigo Tanimura sp->s_ttyvp = NULL; 326f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 327f591779bSSeigo Tanimura vrele(ttyvp); 328f591779bSSeigo Tanimura } 329df8bae1dSRodney W. Grimes /* 330df8bae1dSRodney W. Grimes * s_ttyp is not zero'd; we use this to indicate 331df8bae1dSRodney W. Grimes * that the session once had a controlling terminal. 332df8bae1dSRodney W. Grimes * (for logging and informational purposes) 333df8bae1dSRodney W. Grimes */ 334df8bae1dSRodney W. Grimes } 335f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 336df8bae1dSRodney W. Grimes sp->s_leader = NULL; 337f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 338f591779bSSeigo Tanimura } 339df8bae1dSRodney W. Grimes fixjobc(p, p->p_pgrp, 0); 340ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 341b40ce416SJulian Elischer (void)acct_process(td); 3424ae89b95SJohn Baldwin mtx_unlock(&Giant); 343df8bae1dSRodney W. Grimes #ifdef KTRACE 344df8bae1dSRodney W. Grimes /* 345df8bae1dSRodney W. Grimes * release trace file 346df8bae1dSRodney W. Grimes */ 347d7aadbf9SJohn Baldwin PROC_LOCK(p); 3486c84de02SJohn Baldwin mtx_lock(&ktrace_mtx); 349df8bae1dSRodney W. Grimes p->p_traceflag = 0; /* don't trace the vrele() */ 350a5881ea5SJohn Baldwin tracevp = p->p_tracevp; 351a5881ea5SJohn Baldwin p->p_tracevp = NULL; 352a5881ea5SJohn Baldwin tracecred = p->p_tracecred; 353a5881ea5SJohn Baldwin p->p_tracecred = NULL; 3546c84de02SJohn Baldwin mtx_unlock(&ktrace_mtx); 355d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 35615088317SBrian Feldman if (tracevp != NULL) { 35715088317SBrian Feldman mtx_lock(&Giant); 358d7aadbf9SJohn Baldwin vrele(tracevp); 35915088317SBrian Feldman mtx_unlock(&Giant); 36015088317SBrian Feldman } 361a5881ea5SJohn Baldwin if (tracecred != NULL) 362a5881ea5SJohn Baldwin crfree(tracecred); 363df8bae1dSRodney W. Grimes #endif 364df8bae1dSRodney W. Grimes /* 365ee42d0a9SDavid Malone * Release reference to text vnode 366ee42d0a9SDavid Malone */ 367ee42d0a9SDavid Malone if ((vtmp = p->p_textvp) != NULL) { 368ee42d0a9SDavid Malone p->p_textvp = NULL; 3694ae89b95SJohn Baldwin mtx_lock(&Giant); 370ee42d0a9SDavid Malone vrele(vtmp); 3714ae89b95SJohn Baldwin mtx_unlock(&Giant); 372ee42d0a9SDavid Malone } 373ee42d0a9SDavid Malone 374ee42d0a9SDavid Malone /* 375d7aadbf9SJohn Baldwin * Release our limits structure. 376d7aadbf9SJohn Baldwin */ 37791d5354aSJohn Baldwin PROC_LOCK(p); 37891d5354aSJohn Baldwin plim = p->p_limit; 379d7aadbf9SJohn Baldwin p->p_limit = NULL; 38091d5354aSJohn Baldwin PROC_UNLOCK(p); 38191d5354aSJohn Baldwin lim_free(plim); 382d7aadbf9SJohn Baldwin 383d7aadbf9SJohn Baldwin /* 384d7aadbf9SJohn Baldwin * Release this thread's reference to the ucred. The actual proc 385d7aadbf9SJohn Baldwin * reference will stay around until the proc is harvested by 386d7aadbf9SJohn Baldwin * wait(). At this point the ucred is immutable (no other threads 387d7aadbf9SJohn Baldwin * from this proc are around that can change it) so we leave the 388d7aadbf9SJohn Baldwin * per-thread ucred pointer intact in case it is needed although 389d7aadbf9SJohn Baldwin * in theory nothing should be using it at this point. 390d7aadbf9SJohn Baldwin */ 391d7aadbf9SJohn Baldwin crfree(td->td_ucred); 392d7aadbf9SJohn Baldwin 393d7aadbf9SJohn Baldwin /* 394df8bae1dSRodney W. Grimes * Remove proc from allproc queue and pidhash chain. 395df8bae1dSRodney W. Grimes * Place onto zombproc. Unlink from parent's child list. 396df8bae1dSRodney W. Grimes */ 3971005a129SJohn Baldwin sx_xlock(&allproc_lock); 398b75356e1SJeffrey Hsu LIST_REMOVE(p, p_list); 399b75356e1SJeffrey Hsu LIST_INSERT_HEAD(&zombproc, p, p_list); 400b75356e1SJeffrey Hsu LIST_REMOVE(p, p_hash); 4011005a129SJohn Baldwin sx_xunlock(&allproc_lock); 402df8bae1dSRodney W. Grimes 4031005a129SJohn Baldwin sx_xlock(&proctree_lock); 4042e3c8fcbSPoul-Henning Kamp q = LIST_FIRST(&p->p_children); 405a914fb6bSJohn Baldwin if (q != NULL) /* only need this if any child is S_ZOMB */ 4067f05b035SAlfred Perlstein wakeup(initproc); 407a914fb6bSJohn Baldwin for (; q != NULL; q = nq) { 4082e3c8fcbSPoul-Henning Kamp nq = LIST_NEXT(q, p_sibling); 409a914fb6bSJohn Baldwin PROC_LOCK(q); 410c65437a3SJohn Baldwin proc_reparent(q, initproc); 4114ac9ae70SJulian Elischer q->p_sigparent = SIGCHLD; 412df8bae1dSRodney W. Grimes /* 413df8bae1dSRodney W. Grimes * Traced processes are killed 414df8bae1dSRodney W. Grimes * since their existence means someone is screwing up. 415df8bae1dSRodney W. Grimes */ 416df8bae1dSRodney W. Grimes if (q->p_flag & P_TRACED) { 417df8bae1dSRodney W. Grimes q->p_flag &= ~P_TRACED; 418df8bae1dSRodney W. Grimes psignal(q, SIGKILL); 419c65437a3SJohn Baldwin } 420a914fb6bSJohn Baldwin PROC_UNLOCK(q); 421df8bae1dSRodney W. Grimes } 422df8bae1dSRodney W. Grimes 423df8bae1dSRodney W. Grimes /* 424df8bae1dSRodney W. Grimes * Save exit status and final rusage info, adding in child rusage 425df8bae1dSRodney W. Grimes * info and self times. 426df8bae1dSRodney W. Grimes */ 4274ae89b95SJohn Baldwin mtx_lock(&Giant); 428d7aadbf9SJohn Baldwin PROC_LOCK(p); 429df8bae1dSRodney W. Grimes p->p_xstat = rv; 430cbf4e354SDavid Xu p->p_xthread = td; 431df8bae1dSRodney W. Grimes *p->p_ru = p->p_stats->p_ru; 4329ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 433df8bae1dSRodney W. Grimes calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL); 4349ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 435df8bae1dSRodney W. Grimes ruadd(p->p_ru, &p->p_stats->p_cru); 436df8bae1dSRodney W. Grimes 437df8bae1dSRodney W. Grimes /* 4387a6b989bSJohn Baldwin * Notify interested parties of our demise. 439cb679c38SJonathan Lemon */ 440a274d19bSBrian Feldman KNOTE(&p->p_klist, NOTE_EXIT); 4414ae89b95SJohn Baldwin mtx_unlock(&Giant); 4421a29c806SOlivier Houchard /* 4431a29c806SOlivier Houchard * Just delete all entries in the p_klist. At this point we won't 4441a29c806SOlivier Houchard * report any more events, and there are nasty race conditions that 4451a29c806SOlivier Houchard * can beat us if we don't. 4461a29c806SOlivier Houchard */ 4471a29c806SOlivier Houchard while (SLIST_FIRST(&p->p_klist)) 4481a29c806SOlivier Houchard SLIST_REMOVE_HEAD(&p->p_klist, kn_selnext); 449cb679c38SJonathan Lemon 450cb679c38SJonathan Lemon /* 451645682fdSLuoqi Chen * Notify parent that we're gone. If parent has the PS_NOCLDWAIT 452ba1551caSIan Dowse * flag set, or if the handler is set to SIG_IGN, notify process 453ba1551caSIan Dowse * 1 instead (and hope it will handle this situation). 454df8bae1dSRodney W. Grimes */ 455d7aadbf9SJohn Baldwin PROC_LOCK(p->p_pptr); 45690af4afaSJohn Baldwin mtx_lock(&p->p_pptr->p_sigacts->ps_mtx); 45790af4afaSJohn Baldwin if (p->p_pptr->p_sigacts->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) { 458276c5169SJohn Baldwin struct proc *pp; 459276c5169SJohn Baldwin 46090af4afaSJohn Baldwin mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); 461276c5169SJohn Baldwin pp = p->p_pptr; 462f591779bSSeigo Tanimura PROC_UNLOCK(pp); 463245f17d4SJoerg Wunsch proc_reparent(p, initproc); 46455b5f2a2SDon Lewis p->p_sigparent = SIGCHLD; 465f591779bSSeigo Tanimura PROC_LOCK(p->p_pptr); 466245f17d4SJoerg Wunsch /* 467245f17d4SJoerg Wunsch * If this was the last child of our parent, notify 468245f17d4SJoerg Wunsch * parent, so in case he was wait(2)ing, he will 469245f17d4SJoerg Wunsch * continue. 470245f17d4SJoerg Wunsch */ 471245f17d4SJoerg Wunsch if (LIST_EMPTY(&pp->p_children)) 4727f05b035SAlfred Perlstein wakeup(pp); 47390af4afaSJohn Baldwin } else 47490af4afaSJohn Baldwin mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); 475245f17d4SJoerg Wunsch 4766567eef7SDon Lewis if (p->p_pptr == initproc) 4776626c604SJulian Elischer psignal(p->p_pptr, SIGCHLD); 4786567eef7SDon Lewis else if (p->p_sigparent != 0) 4796567eef7SDon Lewis psignal(p->p_pptr, p->p_sigparent); 480c65437a3SJohn Baldwin PROC_UNLOCK(p->p_pptr); 481776e0b36SJohn Baldwin 482776e0b36SJohn Baldwin /* 483776e0b36SJohn Baldwin * If this is a kthread, then wakeup anyone waiting for it to exit. 484776e0b36SJohn Baldwin */ 485776e0b36SJohn Baldwin if (p->p_flag & P_KTHREAD) 4867f05b035SAlfred Perlstein wakeup(p); 487c65437a3SJohn Baldwin PROC_UNLOCK(p); 4888e2e767bSJohn Baldwin 4898e2e767bSJohn Baldwin /* 490df8bae1dSRodney W. Grimes * Finally, call machine-dependent code to release the remaining 491696058c3SJulian Elischer * resources including address space. 492582ec34cSAlfred Perlstein * The address space is released by "vmspace_exitfree(p)" in 493582ec34cSAlfred Perlstein * vm_waitproc(). 494df8bae1dSRodney W. Grimes */ 495b40ce416SJulian Elischer cpu_exit(td); 496eb30c1c0SPeter Wemm 497eb30c1c0SPeter Wemm PROC_LOCK(p); 498d7aadbf9SJohn Baldwin PROC_LOCK(p->p_pptr); 499d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 500696058c3SJulian Elischer 501eb30c1c0SPeter Wemm while (mtx_owned(&Giant)) 502c86b6ff5SJohn Baldwin mtx_unlock(&Giant); 503eb30c1c0SPeter Wemm 504eb30c1c0SPeter Wemm /* 505462f31bfSJohn Baldwin * We have to wait until after acquiring all locks before 506e5bb601dSJohn Baldwin * changing p_state. We need to avoid any possibly context 507e5bb601dSJohn Baldwin * switches while marked as a zombie including blocking on 508e5bb601dSJohn Baldwin * a mutex. 509eb30c1c0SPeter Wemm */ 510e5bb601dSJohn Baldwin mtx_lock_spin(&sched_lock); 511e602ba25SJulian Elischer p->p_state = PRS_ZOMBIE; 512e5bb601dSJohn Baldwin critical_enter(); 513e5bb601dSJohn Baldwin mtx_unlock_spin(&sched_lock); 514eb30c1c0SPeter Wemm 515eb30c1c0SPeter Wemm wakeup(p->p_pptr); 516d7aadbf9SJohn Baldwin PROC_UNLOCK(p->p_pptr); 517e5bb601dSJohn Baldwin 518e5bb601dSJohn Baldwin mtx_lock_spin(&sched_lock); 519e5bb601dSJohn Baldwin critical_exit(); 520871684b8SBruce Evans 521871684b8SBruce Evans /* Do the same timestamp bookkeeping that mi_switch() would do. */ 522871684b8SBruce Evans binuptime(&new_switchtime); 523871684b8SBruce Evans bintime_add(&p->p_runtime, &new_switchtime); 524871684b8SBruce Evans bintime_sub(&p->p_runtime, PCPU_PTR(switchtime)); 525871684b8SBruce Evans PCPU_SET(switchtime, new_switchtime); 526d7aadbf9SJohn Baldwin PCPU_SET(switchticks, ticks); 527d7aadbf9SJohn Baldwin 528871684b8SBruce Evans cnt.v_swtch++; 529f6f230feSJeff Roberson sched_exit(p->p_pptr, p); 530f6f230feSJeff Roberson 531f6f230feSJeff Roberson /* 532696058c3SJulian Elischer * Make sure the scheduler takes this thread out of its tables etc. 533e602ba25SJulian Elischer * This will also release this thread's reference to the ucred. 534696058c3SJulian Elischer * Other thread parts to release include pcb bits and such. 535e602ba25SJulian Elischer */ 536e602ba25SJulian Elischer thread_exit(); 537df8bae1dSRodney W. Grimes } 538df8bae1dSRodney W. Grimes 539b2f9e8b1SBruce Evans #ifdef COMPAT_43 540234216efSMatthew Dillon /* 541b7e23e82SJohn Baldwin * MPSAFE. The dirty work is handled by kern_wait(). 542234216efSMatthew Dillon */ 54326f9a767SRodney W. Grimes int 544830c3153SDag-Erling Smørgrav owait(struct thread *td, struct owait_args *uap __unused) 545df8bae1dSRodney W. Grimes { 546b7e23e82SJohn Baldwin int error, status; 547df8bae1dSRodney W. Grimes 548b7e23e82SJohn Baldwin error = kern_wait(td, WAIT_ANY, &status, 0, NULL); 549b7e23e82SJohn Baldwin if (error == 0) 550b7e23e82SJohn Baldwin td->td_retval[1] = status; 551b7e23e82SJohn Baldwin return (error); 552df8bae1dSRodney W. Grimes } 553b2f9e8b1SBruce Evans #endif /* COMPAT_43 */ 554df8bae1dSRodney W. Grimes 555234216efSMatthew Dillon /* 556b7e23e82SJohn Baldwin * MPSAFE. The dirty work is handled by kern_wait(). 557234216efSMatthew Dillon */ 55826f9a767SRodney W. Grimes int 559830c3153SDag-Erling Smørgrav wait4(struct thread *td, struct wait_args *uap) 560df8bae1dSRodney W. Grimes { 561b7e23e82SJohn Baldwin struct rusage ru; 562b7e23e82SJohn Baldwin int error, status; 563b40ce416SJulian Elischer 564b7e23e82SJohn Baldwin error = kern_wait(td, uap->pid, &status, uap->options, &ru); 565b7e23e82SJohn Baldwin if (uap->status != NULL && error == 0) 566b7e23e82SJohn Baldwin error = copyout(&status, uap->status, sizeof(status)); 567b7e23e82SJohn Baldwin if (uap->rusage != NULL && error == 0) 568b7e23e82SJohn Baldwin error = copyout(&ru, uap->rusage, sizeof(struct rusage)); 569b7e23e82SJohn Baldwin return (error); 570df8bae1dSRodney W. Grimes } 571df8bae1dSRodney W. Grimes 572b7e23e82SJohn Baldwin int 573b7e23e82SJohn Baldwin kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rusage) 574df8bae1dSRodney W. Grimes { 57548bfcdddSJulian Elischer int nfound; 57648bfcdddSJulian Elischer struct proc *p, *q, *t; 577b7e23e82SJohn Baldwin int error; 578df8bae1dSRodney W. Grimes 579b40ce416SJulian Elischer q = td->td_proc; 580b7e23e82SJohn Baldwin if (pid == 0) { 581f591779bSSeigo Tanimura PROC_LOCK(q); 582b7e23e82SJohn Baldwin pid = -q->p_pgid; 583f591779bSSeigo Tanimura PROC_UNLOCK(q); 584f591779bSSeigo Tanimura } 585b7e23e82SJohn Baldwin if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE)) 5866dc958b9SJohn Baldwin return (EINVAL); 587df8bae1dSRodney W. Grimes loop: 588df8bae1dSRodney W. Grimes nfound = 0; 589d7aadbf9SJohn Baldwin sx_xlock(&proctree_lock); 5902e3c8fcbSPoul-Henning Kamp LIST_FOREACH(p, &q->p_children, p_sibling) { 591f591779bSSeigo Tanimura PROC_LOCK(p); 592b7e23e82SJohn Baldwin if (pid != WAIT_ANY && 593b7e23e82SJohn Baldwin p->p_pid != pid && p->p_pgid != -pid) { 594f591779bSSeigo Tanimura PROC_UNLOCK(p); 595df8bae1dSRodney W. Grimes continue; 596f591779bSSeigo Tanimura } 5974ac9ae70SJulian Elischer 5981156bc4dSJake Burkholder /* 5991156bc4dSJake Burkholder * This special case handles a kthread spawned by linux_clone 6001156bc4dSJake Burkholder * (see linux_misc.c). The linux_wait4 and linux_waitpid 6011156bc4dSJake Burkholder * functions need to be able to distinguish between waiting 6021156bc4dSJake Burkholder * on a process and waiting on a thread. It is a thread if 6031156bc4dSJake Burkholder * p_sigparent is not SIGCHLD, and the WLINUXCLONE option 6041156bc4dSJake Burkholder * signifies we want to wait for threads and not processes. 6054ac9ae70SJulian Elischer */ 6061156bc4dSJake Burkholder if ((p->p_sigparent != SIGCHLD) ^ 607b7e23e82SJohn Baldwin ((options & WLINUXCLONE) != 0)) { 608a914fb6bSJohn Baldwin PROC_UNLOCK(p); 6094ac9ae70SJulian Elischer continue; 610a914fb6bSJohn Baldwin } 6114ac9ae70SJulian Elischer 612df8bae1dSRodney W. Grimes nfound++; 613e602ba25SJulian Elischer if (p->p_state == PRS_ZOMBIE) { 614b40ce416SJulian Elischer td->td_retval[0] = p->p_pid; 615b7e23e82SJohn Baldwin if (status) 616b7e23e82SJohn Baldwin *status = p->p_xstat; /* convert to int */ 617b7e23e82SJohn Baldwin if (rusage) 618b7e23e82SJohn Baldwin bcopy(p->p_ru, rusage, sizeof(struct rusage)); 619b7e23e82SJohn Baldwin 620df8bae1dSRodney W. Grimes /* 621df8bae1dSRodney W. Grimes * If we got the child via a ptrace 'attach', 622df8bae1dSRodney W. Grimes * we need to give it back to the old parent. 623df8bae1dSRodney W. Grimes */ 624b7e23e82SJohn Baldwin PROC_UNLOCK(p); 625d7aadbf9SJohn Baldwin if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) { 626c65437a3SJohn Baldwin PROC_LOCK(p); 627df8bae1dSRodney W. Grimes p->p_oppid = 0; 628df8bae1dSRodney W. Grimes proc_reparent(p, t); 629c65437a3SJohn Baldwin PROC_UNLOCK(p); 630df8bae1dSRodney W. Grimes psignal(t, SIGCHLD); 6317f05b035SAlfred Perlstein wakeup(t); 632c65437a3SJohn Baldwin PROC_UNLOCK(t); 6331005a129SJohn Baldwin sx_xunlock(&proctree_lock); 634d7aadbf9SJohn Baldwin return (0); 635df8bae1dSRodney W. Grimes } 636ebdc3f1dSSeigo Tanimura 6373890793eSTim J. Robbins /* 6383890793eSTim J. Robbins * Remove other references to this process to ensure 6393890793eSTim J. Robbins * we have an exclusive reference. 6403890793eSTim J. Robbins */ 6416ec62361STim J. Robbins sx_xlock(&allproc_lock); 6426ec62361STim J. Robbins LIST_REMOVE(p, p_list); /* off zombproc */ 6436ec62361STim J. Robbins sx_xunlock(&allproc_lock); 6446ec62361STim J. Robbins LIST_REMOVE(p, p_sibling); 6453890793eSTim J. Robbins leavepgrp(p); 646ebdc3f1dSSeigo Tanimura sx_xunlock(&proctree_lock); 647ebdc3f1dSSeigo Tanimura 648ebdc3f1dSSeigo Tanimura /* 649d7aadbf9SJohn Baldwin * As a side effect of this lock, we know that 650d7aadbf9SJohn Baldwin * all other writes to this proc are visible now, so 651d7aadbf9SJohn Baldwin * no more locking is needed for p. 652d7aadbf9SJohn Baldwin */ 6534ae89b95SJohn Baldwin mtx_lock(&Giant); 654d7aadbf9SJohn Baldwin PROC_LOCK(p); 655d7aadbf9SJohn Baldwin p->p_xstat = 0; /* XXX: why? */ 656d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 657d7aadbf9SJohn Baldwin PROC_LOCK(q); 658d7aadbf9SJohn Baldwin ruadd(&q->p_stats->p_cru, p->p_ru); 659d7aadbf9SJohn Baldwin PROC_UNLOCK(q); 660d7aadbf9SJohn Baldwin FREE(p->p_ru, M_ZOMBIE); 661d7aadbf9SJohn Baldwin p->p_ru = NULL; 6624ae89b95SJohn Baldwin mtx_unlock(&Giant); 663d7aadbf9SJohn Baldwin 664d7aadbf9SJohn Baldwin /* 665d7aadbf9SJohn Baldwin * Decrement the count of procs running with this uid. 666d7aadbf9SJohn Baldwin */ 667d7aadbf9SJohn Baldwin (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); 668d7aadbf9SJohn Baldwin 669d7aadbf9SJohn Baldwin /* 67090af4afaSJohn Baldwin * Free credentials, arguments, and sigacts 671df8bae1dSRodney W. Grimes */ 672da654d90SPoul-Henning Kamp crfree(p->p_ucred); 67390af4afaSJohn Baldwin p->p_ucred = NULL; 674d7aadbf9SJohn Baldwin pargs_drop(p->p_args); 675d7aadbf9SJohn Baldwin p->p_args = NULL; 67690af4afaSJohn Baldwin sigacts_free(p->p_sigacts); 67790af4afaSJohn Baldwin p->p_sigacts = NULL; 67888c5ea45SJulian Elischer 679df8bae1dSRodney W. Grimes /* 680696058c3SJulian Elischer * do any thread-system specific cleanups 681e602ba25SJulian Elischer */ 682696058c3SJulian Elischer thread_wait(p); 683e602ba25SJulian Elischer 684e602ba25SJulian Elischer /* 685eb30c1c0SPeter Wemm * Give vm and machine-dependent layer a chance 686df8bae1dSRodney W. Grimes * to free anything that cpu_exit couldn't 687df8bae1dSRodney W. Grimes * release while still running in process context. 688df8bae1dSRodney W. Grimes */ 68937814395SPeter Wemm mtx_lock(&Giant); 690eb30c1c0SPeter Wemm vm_waitproc(p); 6914ae89b95SJohn Baldwin mtx_unlock(&Giant); 6922555374cSRobert Watson #ifdef MAC 6932555374cSRobert Watson mac_destroy_proc(p); 6942555374cSRobert Watson #endif 6951faf202eSJulian Elischer KASSERT(FIRST_THREAD_IN_PROC(p), 696b7e23e82SJohn Baldwin ("kern_wait: no residual thread!")); 697c897b813SJeff Roberson uma_zfree(proc_zone, p); 698d7aadbf9SJohn Baldwin sx_xlock(&allproc_lock); 699df8bae1dSRodney W. Grimes nprocs--; 700d7aadbf9SJohn Baldwin sx_xunlock(&allproc_lock); 701d7aadbf9SJohn Baldwin return (0); 702df8bae1dSRodney W. Grimes } 703112afcb2SJohn Baldwin mtx_lock_spin(&sched_lock); 704e574e444SDavid Xu if (P_SHOULDSTOP(p) && (p->p_suspcount == p->p_numthreads) && 705e574e444SDavid Xu ((p->p_flag & P_WAITED) == 0) && 706b7e23e82SJohn Baldwin (p->p_flag & P_TRACED || options & WUNTRACED)) { 707112afcb2SJohn Baldwin mtx_unlock_spin(&sched_lock); 708df8bae1dSRodney W. Grimes p->p_flag |= P_WAITED; 709d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 710b40ce416SJulian Elischer td->td_retval[0] = p->p_pid; 711b7e23e82SJohn Baldwin if (status) 712b7e23e82SJohn Baldwin *status = W_STOPCODE(p->p_xstat); 713d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 714b7e23e82SJohn Baldwin return (0); 715df8bae1dSRodney W. Grimes } 716112afcb2SJohn Baldwin mtx_unlock_spin(&sched_lock); 717b7e23e82SJohn Baldwin if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) { 7186ee093fbSMike Barcroft sx_xunlock(&proctree_lock); 7196ee093fbSMike Barcroft td->td_retval[0] = p->p_pid; 7206ee093fbSMike Barcroft p->p_flag &= ~P_CONTINUED; 7216ee093fbSMike Barcroft PROC_UNLOCK(p); 7226ee093fbSMike Barcroft 723b7e23e82SJohn Baldwin if (status) 724b7e23e82SJohn Baldwin *status = SIGCONT; 725b7e23e82SJohn Baldwin return (0); 7266ee093fbSMike Barcroft } 727d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 728d7aadbf9SJohn Baldwin } 729d7aadbf9SJohn Baldwin if (nfound == 0) { 730d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 731d7aadbf9SJohn Baldwin return (ECHILD); 732d7aadbf9SJohn Baldwin } 733b7e23e82SJohn Baldwin if (options & WNOHANG) { 734d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 735d7aadbf9SJohn Baldwin td->td_retval[0] = 0; 736d7aadbf9SJohn Baldwin return (0); 737d7aadbf9SJohn Baldwin } 738d7aadbf9SJohn Baldwin PROC_LOCK(q); 739d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 7407f05b035SAlfred Perlstein error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0); 741d7aadbf9SJohn Baldwin PROC_UNLOCK(q); 7424ae89b95SJohn Baldwin if (error) 743d7aadbf9SJohn Baldwin return (error); 744d7aadbf9SJohn Baldwin goto loop; 745d7aadbf9SJohn Baldwin } 746df8bae1dSRodney W. Grimes 747df8bae1dSRodney W. Grimes /* 74898f03f90SJake Burkholder * Make process 'parent' the new parent of process 'child'. 74998f03f90SJake Burkholder * Must be called with an exclusive hold of proctree lock. 750df8bae1dSRodney W. Grimes */ 751df8bae1dSRodney W. Grimes void 752830c3153SDag-Erling Smørgrav proc_reparent(struct proc *child, struct proc *parent) 753df8bae1dSRodney W. Grimes { 754df8bae1dSRodney W. Grimes 7554e5e677bSJohn Baldwin sx_assert(&proctree_lock, SX_XLOCKED); 756c65437a3SJohn Baldwin PROC_LOCK_ASSERT(child, MA_OWNED); 757df8bae1dSRodney W. Grimes if (child->p_pptr == parent) 758df8bae1dSRodney W. Grimes return; 759df8bae1dSRodney W. Grimes 760b75356e1SJeffrey Hsu LIST_REMOVE(child, p_sibling); 761b75356e1SJeffrey Hsu LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); 762df8bae1dSRodney W. Grimes child->p_pptr = parent; 763df8bae1dSRodney W. Grimes } 764