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