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