123369Smckusick /* 2*63442Sbostic * Copyright (c) 1982, 1986, 1989, 1991, 1993 3*63442Sbostic * The Regents of the University of California. All rights reserved. 423369Smckusick * 544433Sbostic * %sccs.include.redist.c% 637728Smckusick * 7*63442Sbostic * @(#)kern_exit.c 8.1 (Berkeley) 06/14/93 823369Smckusick */ 912790Ssam 1056517Sbostic #include <sys/param.h> 1156517Sbostic #include <sys/systm.h> 1256517Sbostic #include <sys/map.h> 1356517Sbostic #include <sys/ioctl.h> 1456517Sbostic #include <sys/proc.h> 1556517Sbostic #include <sys/tty.h> 1656517Sbostic #include <sys/time.h> 1756517Sbostic #include <sys/resource.h> 1856517Sbostic #include <sys/kernel.h> 1956517Sbostic #include <sys/buf.h> 2056517Sbostic #include <sys/wait.h> 2156517Sbostic #include <sys/file.h> 2256517Sbostic #include <sys/vnode.h> 2356517Sbostic #include <sys/syslog.h> 2456517Sbostic #include <sys/malloc.h> 2556517Sbostic #include <sys/resourcevar.h> 2656517Sbostic #include <sys/ptrace.h> 2712790Ssam 2856517Sbostic #include <machine/cpu.h> 2947540Skarels #ifdef COMPAT_43 3056517Sbostic #include <machine/reg.h> 3156517Sbostic #include <machine/psl.h> 3237328Skarels #endif 3337328Skarels 3456517Sbostic #include <vm/vm.h> 3556517Sbostic #include <vm/vm_kern.h> 3645739Smckusick 3763441Sbostic __dead void cpu_exit __P((struct proc *)); 3863441Sbostic __dead void exit1 __P((struct proc *, int)); 3963441Sbostic 4012790Ssam /* 4163426Sbostic * exit -- 4263426Sbostic * Death of process. 4312790Ssam */ 4454921Storek struct rexit_args { 4554921Storek int rval; 4654921Storek }; 4763441Sbostic __dead void 4863426Sbostic exit(p, uap, retval) 4942927Smckusick struct proc *p; 5054921Storek struct rexit_args *uap; 5142927Smckusick int *retval; 5242927Smckusick { 5312790Ssam 5457864Sralph exit1(p, W_EXITCODE(uap->rval, 0)); 5545157Skarels /* NOTREACHED */ 5612790Ssam } 5712790Ssam 5812790Ssam /* 5963426Sbostic * Exit: deallocate address space and other resources, change proc state 6063426Sbostic * to zombie, and unlink proc from allproc and parent's lists. Save exit 6163426Sbostic * status and rusage for wait(). Check for child processes and orphan them. 6212790Ssam */ 6363441Sbostic __dead void 6457864Sralph exit1(p, rv) 6547540Skarels register struct proc *p; 6638930Skarels int rv; 6712790Ssam { 6842927Smckusick register struct proc *q, *nq; 6940670Skarels register struct proc **pp; 7052491Smckusick register struct vmspace *vm; 7147540Skarels int s; 7212790Ssam 7354338Smckusick if (p->p_pid == 1) 7454338Smckusick panic("init died (signal %d, exit %d)", 7554338Smckusick WTERMSIG(rv), WEXITSTATUS(rv)); 7612790Ssam #ifdef PGINPROF 7712790Ssam vmsizmon(); 7812790Ssam #endif 7954133Smckusick if (p->p_flag & SPROFIL) 8054133Smckusick stopprofclock(p); 8132018Smckusick MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage), 8232018Smckusick M_ZOMBIE, M_WAITOK); 8347540Skarels /* 8447540Skarels * If parent is waiting for us to exit or exec, 8547540Skarels * SPPWAIT is set; we will wakeup the parent below. 8647540Skarels */ 8748403Skarels p->p_flag &= ~(STRC|SPPWAIT); 8812790Ssam p->p_flag |= SWEXIT; 8912882Ssam p->p_sigignore = ~0; 9039410Skarels p->p_sig = 0; 9112790Ssam untimeout(realitexpire, (caddr_t)p); 9247540Skarels 9347540Skarels /* 9447540Skarels * Close open files and release open-file table. 9547540Skarels * This may block! 9647540Skarels */ 9747540Skarels fdfree(p); 9850200Skarels 9950200Skarels /* The next two chunks should probably be moved to vmspace_exit. */ 10052491Smckusick vm = p->p_vmspace; 10145739Smckusick #ifdef SYSVSHM 10252491Smckusick if (vm->vm_shm) 10345739Smckusick shmexit(p); 10445739Smckusick #endif 10550200Skarels /* 10650200Skarels * Release user portion of address space. 10750200Skarels * This releases references to vnodes, 10850200Skarels * which could cause I/O if the file has been unlinked. 10950200Skarels * Need to do this early enough that we can still sleep. 11050200Skarels * Can't free the entire vmspace as the kernel stack 11150200Skarels * may be mapped within that space also. 11250200Skarels */ 11352491Smckusick if (vm->vm_refcnt == 1) 11452491Smckusick (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, 11550200Skarels VM_MAXUSER_ADDRESS); 11647540Skarels 11737328Skarels if (SESS_LEADER(p)) { 11842897Smarc register struct session *sp = p->p_session; 11942897Smarc 12042897Smarc if (sp->s_ttyvp) { 12140809Smarc /* 12242897Smarc * Controlling process. 12349087Skarels * Signal foreground pgrp, 12449087Skarels * drain controlling terminal 12549087Skarels * and revoke access to controlling terminal. 12642897Smarc */ 12749087Skarels if (sp->s_ttyp->t_session == sp) { 12849087Skarels if (sp->s_ttyp->t_pgrp) 12949087Skarels pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1); 13049087Skarels (void) ttywait(sp->s_ttyp); 13149087Skarels vgoneall(sp->s_ttyvp); 13249087Skarels } 13342897Smarc vrele(sp->s_ttyvp); 13442897Smarc sp->s_ttyvp = NULL; 13542897Smarc /* 13640809Smarc * s_ttyp is not zero'd; we use this to indicate 13740809Smarc * that the session once had a controlling terminal. 13842897Smarc * (for logging and informational purposes) 13940809Smarc */ 14037328Skarels } 14149087Skarels sp->s_leader = NULL; 14237328Skarels } 14347540Skarels fixjobc(p, p->p_pgrp, 0); 14447540Skarels p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; 14563430Sbostic (void)acct_process(p); 14637328Skarels #ifdef KTRACE 14737328Skarels /* 14837328Skarels * release trace file 14937328Skarels */ 15052202Smarc p->p_traceflag = 0; /* don't trace the vrele() */ 15137328Skarels if (p->p_tracep) 15237728Smckusick vrele(p->p_tracep); 15337328Skarels #endif 15451014Skarels /* 15547540Skarels * Remove proc from allproc queue and pidhash chain. 15647540Skarels * Place onto zombproc. Unlink from parent's child list. 15747540Skarels */ 15847540Skarels if (*p->p_prev = p->p_nxt) 15916527Skarels p->p_nxt->p_prev = p->p_prev; 16047540Skarels if (p->p_nxt = zombproc) 16116527Skarels p->p_nxt->p_prev = &p->p_nxt; 16216527Skarels p->p_prev = &zombproc; 16316527Skarels zombproc = p; 16412790Ssam p->p_stat = SZOMB; 16552484Smckusick 16640670Skarels for (pp = &pidhash[PIDHASH(p->p_pid)]; *pp; pp = &(*pp)->p_hash) 16740670Skarels if (*pp == p) { 16840670Skarels *pp = p->p_hash; 16940670Skarels goto done; 17040670Skarels } 17140670Skarels panic("exit"); 17240670Skarels done: 17347540Skarels 17416527Skarels if (p->p_cptr) /* only need this if any child is S_ZOMB */ 17547540Skarels wakeup((caddr_t) initproc); 17616527Skarels for (q = p->p_cptr; q != NULL; q = nq) { 17716527Skarels nq = q->p_osptr; 17816527Skarels if (nq != NULL) 17916527Skarels nq->p_ysptr = NULL; 18047540Skarels if (initproc->p_cptr) 18147540Skarels initproc->p_cptr->p_ysptr = q; 18247540Skarels q->p_osptr = initproc->p_cptr; 18316527Skarels q->p_ysptr = NULL; 18447540Skarels initproc->p_cptr = q; 18512790Ssam 18647540Skarels q->p_pptr = initproc; 18716527Skarels /* 18816527Skarels * Traced processes are killed 18916527Skarels * since their existence means someone is screwing up. 19016527Skarels */ 19116527Skarels if (q->p_flag&STRC) { 19216527Skarels q->p_flag &= ~STRC; 19316527Skarels psignal(q, SIGKILL); 19412790Ssam } 19516527Skarels } 19617540Skarels p->p_cptr = NULL; 19747540Skarels 19847540Skarels /* 19954785Storek * Save exit status and final rusage info, adding in child rusage 20054816Storek * info and self times. 20147540Skarels */ 20247540Skarels p->p_xstat = rv; 20347540Skarels *p->p_ru = p->p_stats->p_ru; 20454785Storek calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL); 20547540Skarels ruadd(p->p_ru, &p->p_stats->p_cru); 20647540Skarels 20747540Skarels /* 20847540Skarels * Notify parent that we're gone. 20947540Skarels */ 21012790Ssam psignal(p->p_pptr, SIGCHLD); 21112790Ssam wakeup((caddr_t)p->p_pptr); 21229946Skarels #if defined(tahoe) 21349087Skarels /* move this to cpu_exit */ 21449087Skarels p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL; 21529946Skarels #endif 21647540Skarels /* 21752484Smckusick * Clear curproc after we've done all operations 21852484Smckusick * that could block, and before tearing down the rest 21952484Smckusick * of the process state that might be used from clock, etc. 22052484Smckusick * Also, can't clear curproc while we're still runnable, 22152484Smckusick * as we're not on a run queue (we are current, just not 22252484Smckusick * a proper proc any longer!). 22352484Smckusick * 22452484Smckusick * Other substructures are freed from wait(). 22552484Smckusick */ 22652484Smckusick curproc = NULL; 22752484Smckusick if (--p->p_limit->p_refcnt == 0) 22852484Smckusick FREE(p->p_limit, M_SUBPROC); 22952484Smckusick 23052484Smckusick /* 23149087Skarels * Finally, call machine-dependent code to release the remaining 23249087Skarels * resources including address space, the kernel stack and pcb. 23349087Skarels * The address space is released by "vmspace_free(p->p_vmspace)"; 23449087Skarels * This is machine-dependent, as we may have to change stacks 23549087Skarels * or ensure that the current one isn't reallocated before we 23654785Storek * finish. cpu_exit will end with a call to cpu_swtch(), finishing 23749087Skarels * our execution (pun intended). 23847540Skarels */ 23949087Skarels cpu_exit(p); 24012790Ssam } 24112790Ssam 24254921Storek struct wait_args { 24354921Storek int pid; 24454921Storek int *status; 24554921Storek int options; 24654921Storek struct rusage *rusage; 24737328Skarels #ifdef COMPAT_43 24854921Storek int compat; /* pseudo */ 24954921Storek #endif 25054921Storek }; 25154921Storek 25254921Storek #ifdef COMPAT_43 25359934Sakito #if defined(hp300) || defined(luna68k) 25457306Shibler #include <machine/frame.h> 25557306Shibler #define GETPS(rp) ((struct frame *)(rp))->f_sr 25657306Shibler #else 25757306Shibler #define GETPS(rp) (rp)[PS] 25857306Shibler #endif 25957306Shibler 26042927Smckusick owait(p, uap, retval) 26142927Smckusick struct proc *p; 26254921Storek register struct wait_args *uap; 26342927Smckusick int *retval; 26442927Smckusick { 26512790Ssam 26651015Sralph #ifdef PSL_ALLCC 26757306Shibler if ((GETPS(p->p_md.md_regs) & PSL_ALLCC) != PSL_ALLCC) { 26838930Skarels uap->options = 0; 26954921Storek uap->rusage = NULL; 27037328Skarels } else { 27152480Smckusick uap->options = p->p_md.md_regs[R0]; 27252480Smckusick uap->rusage = (struct rusage *)p->p_md.md_regs[R1]; 27312790Ssam } 27451015Sralph #else 27551015Sralph uap->options = 0; 27654921Storek uap->rusage = NULL; 27751015Sralph #endif 27837328Skarels uap->pid = WAIT_ANY; 27954921Storek uap->status = NULL; 28039410Skarels uap->compat = 1; 28144404Skarels return (wait1(p, uap, retval)); 28212790Ssam } 28312790Ssam 28442927Smckusick wait4(p, uap, retval) 28542927Smckusick struct proc *p; 28654921Storek struct wait_args *uap; 28742927Smckusick int *retval; 28842927Smckusick { 28939410Skarels 29039410Skarels uap->compat = 0; 29144404Skarels return (wait1(p, uap, retval)); 29237328Skarels } 29339410Skarels #else 29439410Skarels #define wait1 wait4 29537328Skarels #endif 29637328Skarels 29712790Ssam /* 29847540Skarels * Wait: check child processes to see if any have exited, 29947540Skarels * stopped under trace, or (optionally) stopped by a signal. 30047540Skarels * Pass back status and deallocate exited child's proc structure. 30112790Ssam */ 30242927Smckusick wait1(q, uap, retval) 30342927Smckusick register struct proc *q; 30454921Storek register struct wait_args *uap; 30542927Smckusick int retval[]; 30642927Smckusick { 30747540Skarels register int nfound; 30854338Smckusick register struct proc *p, *t; 30939410Skarels int status, error; 31012790Ssam 31137328Skarels if (uap->pid == 0) 31237328Skarels uap->pid = -q->p_pgid; 31338930Skarels #ifdef notyet 31439410Skarels if (uap->options &~ (WUNTRACED|WNOHANG)) 31544404Skarels return (EINVAL); 31638930Skarels #endif 31712790Ssam loop: 31847540Skarels nfound = 0; 31916527Skarels for (p = q->p_cptr; p; p = p->p_osptr) { 32037328Skarels if (uap->pid != WAIT_ANY && 32137328Skarels p->p_pid != uap->pid && p->p_pgid != -uap->pid) 32237328Skarels continue; 32347540Skarels nfound++; 32412790Ssam if (p->p_stat == SZOMB) { 32542927Smckusick retval[0] = p->p_pid; 32637328Skarels #ifdef COMPAT_43 32739410Skarels if (uap->compat) 32842927Smckusick retval[1] = p->p_xstat; 32937328Skarels else 33037328Skarels #endif 33137328Skarels if (uap->status) { 33239410Skarels status = p->p_xstat; /* convert to int */ 33339410Skarels if (error = copyout((caddr_t)&status, 33437328Skarels (caddr_t)uap->status, sizeof(status))) 33544404Skarels return (error); 33637328Skarels } 33739410Skarels if (uap->rusage && (error = copyout((caddr_t)p->p_ru, 33839410Skarels (caddr_t)uap->rusage, sizeof (struct rusage)))) 33944404Skarels return (error); 34054338Smckusick /* 34154338Smckusick * If we got the child via a ptrace 'attach', 34254338Smckusick * we need to give it back to the old parent. 34354338Smckusick */ 34454338Smckusick if (p->p_oppid && (t = pfind(p->p_oppid))) { 34554338Smckusick p->p_oppid = 0; 34654338Smckusick proc_reparent(p, t); 34754338Smckusick psignal(t, SIGCHLD); 34854338Smckusick wakeup((caddr_t)t); 34954338Smckusick return (0); 35054338Smckusick } 35112790Ssam p->p_xstat = 0; 35247540Skarels ruadd(&q->p_stats->p_cru, p->p_ru); 35337328Skarels FREE(p->p_ru, M_ZOMBIE); 35455405Smckusick 35555405Smckusick /* 35655405Smckusick * Decrement the count of procs running with this uid. 35755405Smckusick */ 35855405Smckusick (void)chgproccnt(p->p_cred->p_ruid, -1); 35955405Smckusick 36055405Smckusick /* 36155405Smckusick * Free up credentials. 36255405Smckusick */ 36350200Skarels if (--p->p_cred->p_refcnt == 0) { 36450200Skarels crfree(p->p_cred->pc_ucred); 36550200Skarels FREE(p->p_cred, M_SUBPROC); 36650200Skarels } 36747540Skarels 36847540Skarels /* 36947540Skarels * Finally finished with old proc entry. 37047540Skarels * Unlink it from its process group and free it. 37147540Skarels */ 37247540Skarels leavepgrp(p); 37316527Skarels if (*p->p_prev = p->p_nxt) /* off zombproc */ 37416527Skarels p->p_nxt->p_prev = p->p_prev; 37512790Ssam if (q = p->p_ysptr) 37612790Ssam q->p_osptr = p->p_osptr; 37712790Ssam if (q = p->p_osptr) 37812790Ssam q->p_ysptr = p->p_ysptr; 37912790Ssam if ((q = p->p_pptr)->p_cptr == p) 38012790Ssam q->p_cptr = p->p_osptr; 38149690Swilliam 38250200Skarels /* 38350200Skarels * Give machine-dependent layer a chance 38450200Skarels * to free anything that cpu_exit couldn't 38550200Skarels * release while still running in process context. 38650200Skarels */ 38750200Skarels cpu_wait(p); 38847540Skarels FREE(p, M_PROC); 38947540Skarels nprocs--; 39044404Skarels return (0); 39112790Ssam } 39237328Skarels if (p->p_stat == SSTOP && (p->p_flag & SWTED) == 0 && 39337328Skarels (p->p_flag & STRC || uap->options & WUNTRACED)) { 39412790Ssam p->p_flag |= SWTED; 39542927Smckusick retval[0] = p->p_pid; 39637328Skarels #ifdef COMPAT_43 39739737Smckusick if (uap->compat) { 39843895Skarels retval[1] = W_STOPCODE(p->p_xstat); 39939737Smckusick error = 0; 40039737Smckusick } else 40137328Skarels #endif 40237328Skarels if (uap->status) { 40343895Skarels status = W_STOPCODE(p->p_xstat); 40439410Skarels error = copyout((caddr_t)&status, 40551015Sralph (caddr_t)uap->status, sizeof(status)); 40639410Skarels } else 40739410Skarels error = 0; 40844404Skarels return (error); 40912790Ssam } 41012790Ssam } 41147540Skarels if (nfound == 0) 41244404Skarels return (ECHILD); 41337328Skarels if (uap->options & WNOHANG) { 41442927Smckusick retval[0] = 0; 41544404Skarels return (0); 41612790Ssam } 41742927Smckusick if (error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)) 41844404Skarels return (error); 41912790Ssam goto loop; 42012790Ssam } 42154338Smckusick 42254338Smckusick /* 42354338Smckusick * make process 'parent' the new parent of process 'child'. 42454338Smckusick */ 42554338Smckusick void 42654338Smckusick proc_reparent(child, parent) 42754338Smckusick register struct proc *child; 42854338Smckusick register struct proc *parent; 42954338Smckusick { 43054338Smckusick register struct proc *o; 43154338Smckusick register struct proc *y; 43254338Smckusick 43354338Smckusick if (child->p_pptr == parent) 43454338Smckusick return; 43554338Smckusick 43654338Smckusick /* fix up the child linkage for the old parent */ 43754338Smckusick o = child->p_osptr; 43854338Smckusick y = child->p_ysptr; 43954338Smckusick if (y) 44054338Smckusick y->p_osptr = o; 44154338Smckusick if (o) 44254338Smckusick o->p_ysptr = y; 44354338Smckusick if (child->p_pptr->p_cptr == child) 44454338Smckusick child->p_pptr->p_cptr = o; 44554338Smckusick 44654338Smckusick /* fix up child linkage for new parent */ 44754338Smckusick o = parent->p_cptr; 44854338Smckusick if (o) 44954338Smckusick o->p_ysptr = child; 45054338Smckusick child->p_osptr = o; 45154338Smckusick child->p_ysptr = NULL; 45254338Smckusick parent->p_cptr = child; 45354338Smckusick child->p_pptr = parent; 45454338Smckusick } 455