1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kern_exit.c 7.44 (Berkeley) 06/20/92 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "map.h" 13 #include "ioctl.h" 14 #include "proc.h" 15 #include "tty.h" 16 #include "time.h" 17 #include "resource.h" 18 #include "kernel.h" 19 #include "buf.h" 20 #include "wait.h" 21 #include "file.h" 22 #include "vnode.h" 23 #include "syslog.h" 24 #include "malloc.h" 25 #include "resourcevar.h" 26 27 #include "machine/cpu.h" 28 #ifdef COMPAT_43 29 #include "machine/reg.h" 30 #include "machine/psl.h" 31 #endif 32 33 #include "vm/vm.h" 34 #include "vm/vm_kern.h" 35 36 /* 37 * Exit system call: pass back caller's arg 38 */ 39 /* ARGSUSED */ 40 rexit(p, uap, retval) 41 struct proc *p; 42 struct args { 43 int rval; 44 } *uap; 45 int *retval; 46 { 47 48 exit(p, W_EXITCODE(uap->rval, 0)); 49 /* NOTREACHED */ 50 } 51 52 /* 53 * Exit: deallocate address space and other resources, 54 * change proc state to zombie, and unlink proc from allproc 55 * and parent's lists. Save exit status and rusage for wait(). 56 * Check for child processes and orphan them. 57 */ 58 exit(p, rv) 59 register struct proc *p; 60 int rv; 61 { 62 register struct proc *q, *nq; 63 register struct proc **pp; 64 register struct vmspace *vm; 65 int s; 66 67 #ifdef PGINPROF 68 vmsizmon(); 69 #endif 70 if (p->p_flag & SPROFIL) 71 stopprofclock(p); 72 MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage), 73 M_ZOMBIE, M_WAITOK); 74 /* 75 * If parent is waiting for us to exit or exec, 76 * SPPWAIT is set; we will wakeup the parent below. 77 */ 78 p->p_flag &= ~(STRC|SPPWAIT); 79 p->p_flag |= SWEXIT; 80 p->p_sigignore = ~0; 81 p->p_sig = 0; 82 untimeout(realitexpire, (caddr_t)p); 83 84 /* 85 * Close open files and release open-file table. 86 * This may block! 87 */ 88 fdfree(p); 89 90 /* The next two chunks should probably be moved to vmspace_exit. */ 91 vm = p->p_vmspace; 92 #ifdef SYSVSHM 93 if (vm->vm_shm) 94 shmexit(p); 95 #endif 96 /* 97 * Release user portion of address space. 98 * This releases references to vnodes, 99 * which could cause I/O if the file has been unlinked. 100 * Need to do this early enough that we can still sleep. 101 * Can't free the entire vmspace as the kernel stack 102 * may be mapped within that space also. 103 */ 104 if (vm->vm_refcnt == 1) 105 (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, 106 VM_MAXUSER_ADDRESS); 107 108 if (p->p_pid == 1) 109 panic("init died"); 110 if (SESS_LEADER(p)) { 111 register struct session *sp = p->p_session; 112 113 if (sp->s_ttyvp) { 114 /* 115 * Controlling process. 116 * Signal foreground pgrp, 117 * drain controlling terminal 118 * and revoke access to controlling terminal. 119 */ 120 if (sp->s_ttyp->t_session == sp) { 121 if (sp->s_ttyp->t_pgrp) 122 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1); 123 (void) ttywait(sp->s_ttyp); 124 vgoneall(sp->s_ttyvp); 125 } 126 vrele(sp->s_ttyvp); 127 sp->s_ttyvp = NULL; 128 /* 129 * s_ttyp is not zero'd; we use this to indicate 130 * that the session once had a controlling terminal. 131 * (for logging and informational purposes) 132 */ 133 } 134 sp->s_leader = NULL; 135 } 136 fixjobc(p, p->p_pgrp, 0); 137 p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; 138 (void) acct(p); 139 #ifdef KTRACE 140 /* 141 * release trace file 142 */ 143 p->p_traceflag = 0; /* don't trace the vrele() */ 144 if (p->p_tracep) 145 vrele(p->p_tracep); 146 #endif 147 /* 148 * Remove proc from allproc queue and pidhash chain. 149 * Place onto zombproc. Unlink from parent's child list. 150 */ 151 if (*p->p_prev = p->p_nxt) 152 p->p_nxt->p_prev = p->p_prev; 153 if (p->p_nxt = zombproc) 154 p->p_nxt->p_prev = &p->p_nxt; 155 p->p_prev = &zombproc; 156 zombproc = p; 157 p->p_stat = SZOMB; 158 159 for (pp = &pidhash[PIDHASH(p->p_pid)]; *pp; pp = &(*pp)->p_hash) 160 if (*pp == p) { 161 *pp = p->p_hash; 162 goto done; 163 } 164 panic("exit"); 165 done: 166 167 if (p->p_cptr) /* only need this if any child is S_ZOMB */ 168 wakeup((caddr_t) initproc); 169 for (q = p->p_cptr; q != NULL; q = nq) { 170 nq = q->p_osptr; 171 if (nq != NULL) 172 nq->p_ysptr = NULL; 173 if (initproc->p_cptr) 174 initproc->p_cptr->p_ysptr = q; 175 q->p_osptr = initproc->p_cptr; 176 q->p_ysptr = NULL; 177 initproc->p_cptr = q; 178 179 q->p_pptr = initproc; 180 /* 181 * Traced processes are killed 182 * since their existence means someone is screwing up. 183 */ 184 if (q->p_flag&STRC) { 185 q->p_flag &= ~STRC; 186 psignal(q, SIGKILL); 187 } 188 } 189 p->p_cptr = NULL; 190 191 /* 192 * Save exit status and final rusage info, 193 * adding in child rusage info and self times. 194 */ 195 p->p_xstat = rv; 196 *p->p_ru = p->p_stats->p_ru; 197 p->p_ru->ru_stime = p->p_stime; 198 p->p_ru->ru_utime = p->p_utime; 199 ruadd(p->p_ru, &p->p_stats->p_cru); 200 201 /* 202 * Notify parent that we're gone. 203 */ 204 psignal(p->p_pptr, SIGCHLD); 205 wakeup((caddr_t)p->p_pptr); 206 #if defined(tahoe) 207 /* move this to cpu_exit */ 208 p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL; 209 #endif 210 /* 211 * Clear curproc after we've done all operations 212 * that could block, and before tearing down the rest 213 * of the process state that might be used from clock, etc. 214 * Also, can't clear curproc while we're still runnable, 215 * as we're not on a run queue (we are current, just not 216 * a proper proc any longer!). 217 * 218 * Other substructures are freed from wait(). 219 */ 220 curproc = NULL; 221 if (--p->p_limit->p_refcnt == 0) 222 FREE(p->p_limit, M_SUBPROC); 223 224 /* 225 * Finally, call machine-dependent code to release the remaining 226 * resources including address space, the kernel stack and pcb. 227 * The address space is released by "vmspace_free(p->p_vmspace)"; 228 * This is machine-dependent, as we may have to change stacks 229 * or ensure that the current one isn't reallocated before we 230 * finish. cpu_exit will end with a call to swtch(), finishing 231 * our execution (pun intended). 232 */ 233 cpu_exit(p); 234 /* NOTREACHED */ 235 } 236 237 #ifdef COMPAT_43 238 owait(p, uap, retval) 239 struct proc *p; 240 register struct args { 241 int pid; 242 int *status; 243 int options; 244 struct rusage *rusage; 245 int compat; 246 } *uap; 247 int *retval; 248 { 249 250 #ifdef PSL_ALLCC 251 if ((p->p_md.md_regs[PS] & PSL_ALLCC) != PSL_ALLCC) { 252 uap->options = 0; 253 uap->rusage = 0; 254 } else { 255 uap->options = p->p_md.md_regs[R0]; 256 uap->rusage = (struct rusage *)p->p_md.md_regs[R1]; 257 } 258 #else 259 uap->options = 0; 260 uap->rusage = 0; 261 #endif 262 uap->pid = WAIT_ANY; 263 uap->status = 0; 264 uap->compat = 1; 265 return (wait1(p, uap, retval)); 266 } 267 268 wait4(p, uap, retval) 269 struct proc *p; 270 struct args { 271 int pid; 272 int *status; 273 int options; 274 struct rusage *rusage; 275 int compat; 276 } *uap; 277 int *retval; 278 { 279 280 uap->compat = 0; 281 return (wait1(p, uap, retval)); 282 } 283 #else 284 #define wait1 wait4 285 #endif 286 287 /* 288 * Wait: check child processes to see if any have exited, 289 * stopped under trace, or (optionally) stopped by a signal. 290 * Pass back status and deallocate exited child's proc structure. 291 */ 292 wait1(q, uap, retval) 293 register struct proc *q; 294 register struct args { 295 int pid; 296 int *status; 297 int options; 298 struct rusage *rusage; 299 #ifdef COMPAT_43 300 int compat; 301 #endif 302 } *uap; 303 int retval[]; 304 { 305 register int nfound; 306 register struct proc *p; 307 int status, error; 308 309 if (uap->pid == 0) 310 uap->pid = -q->p_pgid; 311 #ifdef notyet 312 if (uap->options &~ (WUNTRACED|WNOHANG)) 313 return (EINVAL); 314 #endif 315 loop: 316 nfound = 0; 317 for (p = q->p_cptr; p; p = p->p_osptr) { 318 if (uap->pid != WAIT_ANY && 319 p->p_pid != uap->pid && p->p_pgid != -uap->pid) 320 continue; 321 nfound++; 322 if (p->p_stat == SZOMB) { 323 retval[0] = p->p_pid; 324 #ifdef COMPAT_43 325 if (uap->compat) 326 retval[1] = p->p_xstat; 327 else 328 #endif 329 if (uap->status) { 330 status = p->p_xstat; /* convert to int */ 331 if (error = copyout((caddr_t)&status, 332 (caddr_t)uap->status, sizeof(status))) 333 return (error); 334 } 335 if (uap->rusage && (error = copyout((caddr_t)p->p_ru, 336 (caddr_t)uap->rusage, sizeof (struct rusage)))) 337 return (error); 338 p->p_xstat = 0; 339 ruadd(&q->p_stats->p_cru, p->p_ru); 340 FREE(p->p_ru, M_ZOMBIE); 341 if (--p->p_cred->p_refcnt == 0) { 342 crfree(p->p_cred->pc_ucred); 343 FREE(p->p_cred, M_SUBPROC); 344 } 345 346 /* 347 * Finally finished with old proc entry. 348 * Unlink it from its process group and free it. 349 */ 350 leavepgrp(p); 351 if (*p->p_prev = p->p_nxt) /* off zombproc */ 352 p->p_nxt->p_prev = p->p_prev; 353 if (q = p->p_ysptr) 354 q->p_osptr = p->p_osptr; 355 if (q = p->p_osptr) 356 q->p_ysptr = p->p_ysptr; 357 if ((q = p->p_pptr)->p_cptr == p) 358 q->p_cptr = p->p_osptr; 359 360 /* 361 * Give machine-dependent layer a chance 362 * to free anything that cpu_exit couldn't 363 * release while still running in process context. 364 */ 365 cpu_wait(p); 366 FREE(p, M_PROC); 367 nprocs--; 368 return (0); 369 } 370 if (p->p_stat == SSTOP && (p->p_flag & SWTED) == 0 && 371 (p->p_flag & STRC || uap->options & WUNTRACED)) { 372 p->p_flag |= SWTED; 373 retval[0] = p->p_pid; 374 #ifdef COMPAT_43 375 if (uap->compat) { 376 retval[1] = W_STOPCODE(p->p_xstat); 377 error = 0; 378 } else 379 #endif 380 if (uap->status) { 381 status = W_STOPCODE(p->p_xstat); 382 error = copyout((caddr_t)&status, 383 (caddr_t)uap->status, sizeof(status)); 384 } else 385 error = 0; 386 return (error); 387 } 388 } 389 if (nfound == 0) 390 return (ECHILD); 391 if (uap->options & WNOHANG) { 392 retval[0] = 0; 393 return (0); 394 } 395 if (error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)) 396 return (error); 397 goto loop; 398 } 399