1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kern_exit.c 7.29 (Berkeley) 12/05/90 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "map.h" 13 #include "ioctl.h" 14 #include "tty.h" 15 #include "user.h" 16 #include "kernel.h" 17 #include "proc.h" 18 #include "buf.h" 19 #include "wait.h" 20 #include "file.h" 21 #include "vnode.h" 22 #include "syslog.h" 23 #include "malloc.h" 24 25 #include "machine/reg.h" 26 #ifdef COMPAT_43 27 #include "machine/psl.h" 28 #endif 29 30 #include "../vm/vm_param.h" 31 #include "../vm/vm_map.h" 32 #include "../vm/vm_kern.h" 33 34 /* 35 * Exit system call: pass back caller's arg 36 */ 37 /* ARGSUSED */ 38 rexit(p, uap, retval) 39 struct proc *p; 40 struct args { 41 int rval; 42 } *uap; 43 int *retval; 44 { 45 46 exit(p, W_EXITCODE(uap->rval, 0)); 47 /* NOTREACHED */ 48 } 49 50 /* 51 * Release resources. 52 * Save u. area for parent to look at. 53 * Enter zombie state. 54 * Wake up parent and init processes, 55 * and dispose of children. 56 */ 57 exit(p, rv) 58 struct proc *p; 59 int rv; 60 { 61 register int i; 62 register struct proc *q, *nq; 63 register struct proc **pp; 64 65 #ifdef PGINPROF 66 vmsizmon(); 67 #endif 68 MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage), 69 M_ZOMBIE, M_WAITOK); 70 p->p_flag &= ~(STRC|SULOCK); 71 p->p_flag |= SWEXIT; 72 p->p_sigignore = ~0; 73 p->p_sig = 0; 74 p->p_cpticks = 0; 75 p->p_pctcpu = 0; 76 for (i = 0; i < NSIG; i++) 77 u.u_signal[i] = SIG_IGN; 78 untimeout(realitexpire, (caddr_t)p); 79 #ifdef SYSVSHM 80 if (p->p_shm) 81 shmexit(p); 82 #endif 83 vm_map_deallocate(p->p_map); 84 p->p_map = VM_MAP_NULL; 85 /* 86 * XXX preserve synchronization semantics of vfork 87 */ 88 if (p->p_flag & SVFORK) { 89 p->p_flag &= ~SVFORK; 90 wakeup((caddr_t)p); 91 while ((p->p_flag & SVFDONE) == 0) 92 sleep((caddr_t)p, PZERO - 1); 93 p->p_flag &= ~SVFDONE; 94 } 95 for (i = 0; i <= u.u_lastfile; i++) { 96 struct file *f; 97 98 f = u.u_ofile[i]; 99 if (f) { 100 u.u_ofile[i] = NULL; 101 u.u_pofile[i] = 0; 102 (void) closef(f); 103 } 104 } 105 if (SESS_LEADER(p)) { 106 register struct session *sp = p->p_session; 107 108 if (sp->s_ttyvp) { 109 /* 110 * Controlling process. 111 * Signal foreground pgrp and revoke access 112 * to controlling terminal. 113 */ 114 if (sp->s_ttyp->t_pgrp) 115 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1); 116 vgoneall(sp->s_ttyvp); 117 vrele(sp->s_ttyvp); 118 sp->s_ttyvp = NULL; 119 /* 120 * s_ttyp is not zero'd; we use this to indicate 121 * that the session once had a controlling terminal. 122 * (for logging and informational purposes) 123 */ 124 } 125 sp->s_leader = 0; 126 } 127 VOP_LOCK(u.u_cdir); 128 vput(u.u_cdir); 129 if (u.u_rdir) { 130 VOP_LOCK(u.u_rdir); 131 vput(u.u_rdir); 132 } 133 u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; 134 (void) acct(p); 135 crfree(u.u_cred); 136 #ifdef KTRACE 137 /* 138 * release trace file 139 */ 140 if (p->p_tracep) 141 vrele(p->p_tracep); 142 #endif 143 splimp(); 144 /* I don't think this will cause a sleep/realloc anywhere... */ 145 kmem_free(kernel_map, (vm_offset_t)p->p_addr, 146 round_page(ctob(UPAGES))); 147 if (*p->p_prev = p->p_nxt) /* off allproc queue */ 148 p->p_nxt->p_prev = p->p_prev; 149 if (p->p_nxt = zombproc) /* onto zombproc */ 150 p->p_nxt->p_prev = &p->p_nxt; 151 p->p_prev = &zombproc; 152 zombproc = p; 153 p->p_stat = SZOMB; 154 noproc = 1; 155 for (pp = &pidhash[PIDHASH(p->p_pid)]; *pp; pp = &(*pp)->p_hash) 156 if (*pp == p) { 157 *pp = p->p_hash; 158 goto done; 159 } 160 panic("exit"); 161 done: 162 if (p->p_pid == 1) 163 panic("init died"); 164 p->p_xstat = rv; 165 *p->p_ru = u.u_ru; 166 i = splclock(); 167 p->p_ru->ru_stime = p->p_stime; 168 p->p_ru->ru_utime = p->p_utime; 169 splx(i); 170 ruadd(p->p_ru, &u.u_cru); 171 if (p->p_cptr) /* only need this if any child is S_ZOMB */ 172 wakeup((caddr_t)&proc[1]); 173 fixjobc(p, p->p_pgrp, 0); 174 for (q = p->p_cptr; q != NULL; q = nq) { 175 nq = q->p_osptr; 176 if (nq != NULL) 177 nq->p_ysptr = NULL; 178 if (proc[1].p_cptr) 179 proc[1].p_cptr->p_ysptr = q; 180 q->p_osptr = proc[1].p_cptr; 181 q->p_ysptr = NULL; 182 proc[1].p_cptr = q; 183 184 q->p_pptr = &proc[1]; 185 q->p_ppid = 1; 186 /* 187 * Traced processes are killed 188 * since their existence means someone is screwing up. 189 */ 190 if (q->p_flag&STRC) { 191 q->p_flag &= ~STRC; 192 psignal(q, SIGKILL); 193 } 194 } 195 p->p_cptr = NULL; 196 psignal(p->p_pptr, SIGCHLD); 197 wakeup((caddr_t)p->p_pptr); 198 #if defined(tahoe) 199 dkeyrelease(p->p_dkey), p->p_dkey = 0; 200 ckeyrelease(p->p_ckey), p->p_ckey = 0; 201 u.u_pcb.pcb_savacc.faddr = (float *)NULL; 202 #endif 203 swtch(); 204 } 205 206 #ifdef COMPAT_43 207 owait(p, uap, retval) 208 struct proc *p; 209 register struct args { 210 int pid; 211 int *status; 212 int options; 213 struct rusage *rusage; 214 int compat; 215 } *uap; 216 int *retval; 217 { 218 219 if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) { 220 uap->options = 0; 221 uap->rusage = 0; 222 } else { 223 uap->options = u.u_ar0[R0]; 224 uap->rusage = (struct rusage *)u.u_ar0[R1]; 225 } 226 uap->pid = WAIT_ANY; 227 uap->status = 0; 228 uap->compat = 1; 229 return (wait1(p, uap, retval)); 230 } 231 232 wait4(p, uap, retval) 233 struct proc *p; 234 struct args { 235 int pid; 236 int *status; 237 int options; 238 struct rusage *rusage; 239 int compat; 240 } *uap; 241 int *retval; 242 { 243 244 uap->compat = 0; 245 return (wait1(p, uap, retval)); 246 } 247 #else 248 #define wait1 wait4 249 #endif 250 251 /* 252 * Wait system call. 253 * Search for a terminated (zombie) child, 254 * finally lay it to rest, and collect its status. 255 * Look also for stopped (traced) children, 256 * and pass back status from them. 257 */ 258 wait1(q, uap, retval) 259 register struct proc *q; 260 register struct args { 261 int pid; 262 int *status; 263 int options; 264 struct rusage *rusage; 265 #ifdef COMPAT_43 266 int compat; 267 #endif 268 } *uap; 269 int retval[]; 270 { 271 register int f; 272 register struct proc *p; 273 int status, error; 274 275 if (uap->pid == 0) 276 uap->pid = -q->p_pgid; 277 #ifdef notyet 278 if (uap->options &~ (WUNTRACED|WNOHANG)) 279 return (EINVAL); 280 #endif 281 loop: 282 f = 0; 283 for (p = q->p_cptr; p; p = p->p_osptr) { 284 if (uap->pid != WAIT_ANY && 285 p->p_pid != uap->pid && p->p_pgid != -uap->pid) 286 continue; 287 f++; 288 if (p->p_stat == SZOMB) { 289 retval[0] = p->p_pid; 290 #ifdef COMPAT_43 291 if (uap->compat) 292 retval[1] = p->p_xstat; 293 else 294 #endif 295 if (uap->status) { 296 status = p->p_xstat; /* convert to int */ 297 if (error = copyout((caddr_t)&status, 298 (caddr_t)uap->status, sizeof(status))) 299 return (error); 300 } 301 if (uap->rusage && (error = copyout((caddr_t)p->p_ru, 302 (caddr_t)uap->rusage, sizeof (struct rusage)))) 303 return (error); 304 pgrm(p); /* off pgrp */ 305 p->p_xstat = 0; 306 ruadd(&u.u_cru, p->p_ru); 307 FREE(p->p_ru, M_ZOMBIE); 308 p->p_ru = 0; 309 p->p_stat = NULL; 310 p->p_pid = 0; 311 p->p_ppid = 0; 312 if (*p->p_prev = p->p_nxt) /* off zombproc */ 313 p->p_nxt->p_prev = p->p_prev; 314 p->p_nxt = freeproc; /* onto freeproc */ 315 freeproc = p; 316 if (q = p->p_ysptr) 317 q->p_osptr = p->p_osptr; 318 if (q = p->p_osptr) 319 q->p_ysptr = p->p_ysptr; 320 if ((q = p->p_pptr)->p_cptr == p) 321 q->p_cptr = p->p_osptr; 322 p->p_pptr = 0; 323 p->p_ysptr = 0; 324 p->p_osptr = 0; 325 p->p_cptr = 0; 326 p->p_sig = 0; 327 p->p_sigcatch = 0; 328 p->p_sigignore = 0; 329 p->p_sigmask = 0; 330 /*p->p_pgrp = 0;*/ 331 p->p_flag = 0; 332 p->p_wchan = 0; 333 return (0); 334 } 335 if (p->p_stat == SSTOP && (p->p_flag & SWTED) == 0 && 336 (p->p_flag & STRC || uap->options & WUNTRACED)) { 337 p->p_flag |= SWTED; 338 retval[0] = p->p_pid; 339 #ifdef COMPAT_43 340 if (uap->compat) { 341 retval[1] = W_STOPCODE(p->p_xstat); 342 error = 0; 343 } else 344 #endif 345 if (uap->status) { 346 status = W_STOPCODE(p->p_xstat); 347 error = copyout((caddr_t)&status, 348 (caddr_t)uap->status, sizeof(status)); 349 } else 350 error = 0; 351 return (error); 352 } 353 } 354 if (f == 0) 355 return (ECHILD); 356 if (uap->options & WNOHANG) { 357 retval[0] = 0; 358 return (0); 359 } 360 if (error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)) 361 return (error); 362 goto loop; 363 } 364