xref: /csrg-svn/sys/kern/kern_exit.c (revision 45914)
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.30 (Berkeley) 01/10/91
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 	fdrele(p->p_fd);
96 	p->p_fd = (struct filedesc *)0;
97 	if (SESS_LEADER(p)) {
98 		register struct session *sp = p->p_session;
99 
100 		if (sp->s_ttyvp) {
101 			/*
102 			 * Controlling process.
103 			 * Signal foreground pgrp and revoke access
104 			 * to controlling terminal.
105 			 */
106 			if (sp->s_ttyp->t_pgrp)
107 				pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
108 			vgoneall(sp->s_ttyvp);
109 			vrele(sp->s_ttyvp);
110 			sp->s_ttyvp = NULL;
111 			/*
112 			 * s_ttyp is not zero'd; we use this to indicate
113 			 * that the session once had a controlling terminal.
114 			 * (for logging and informational purposes)
115 			 */
116 		}
117 		sp->s_leader = 0;
118 	}
119 	u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
120 	(void) acct(p);
121 	crfree(u.u_cred);
122 #ifdef KTRACE
123 	/*
124 	 * release trace file
125 	 */
126 	if (p->p_tracep)
127 		vrele(p->p_tracep);
128 #endif
129 	splimp();
130 	/* I don't think this will cause a sleep/realloc anywhere... */
131 	kmem_free(kernel_map, (vm_offset_t)p->p_addr,
132 		  round_page(ctob(UPAGES)));
133 	if (*p->p_prev = p->p_nxt)		/* off allproc queue */
134 		p->p_nxt->p_prev = p->p_prev;
135 	if (p->p_nxt = zombproc)		/* onto zombproc */
136 		p->p_nxt->p_prev = &p->p_nxt;
137 	p->p_prev = &zombproc;
138 	zombproc = p;
139 	p->p_stat = SZOMB;
140 	noproc = 1;
141 	for (pp = &pidhash[PIDHASH(p->p_pid)]; *pp; pp = &(*pp)->p_hash)
142 		if (*pp == p) {
143 			*pp = p->p_hash;
144 			goto done;
145 		}
146 	panic("exit");
147 done:
148 	if (p->p_pid == 1)
149 		panic("init died");
150 	p->p_xstat = rv;
151 	*p->p_ru = u.u_ru;
152 	i = splclock();
153 	p->p_ru->ru_stime = p->p_stime;
154 	p->p_ru->ru_utime = p->p_utime;
155 	splx(i);
156 	ruadd(p->p_ru, &u.u_cru);
157 	if (p->p_cptr)		/* only need this if any child is S_ZOMB */
158 		wakeup((caddr_t)&proc[1]);
159 	fixjobc(p, p->p_pgrp, 0);
160 	for (q = p->p_cptr; q != NULL; q = nq) {
161 		nq = q->p_osptr;
162 		if (nq != NULL)
163 			nq->p_ysptr = NULL;
164 		if (proc[1].p_cptr)
165 			proc[1].p_cptr->p_ysptr = q;
166 		q->p_osptr = proc[1].p_cptr;
167 		q->p_ysptr = NULL;
168 		proc[1].p_cptr = q;
169 
170 		q->p_pptr = &proc[1];
171 		q->p_ppid = 1;
172 		/*
173 		 * Traced processes are killed
174 		 * since their existence means someone is screwing up.
175 		 */
176 		if (q->p_flag&STRC) {
177 			q->p_flag &= ~STRC;
178 			psignal(q, SIGKILL);
179 		}
180 	}
181 	p->p_cptr = NULL;
182 	psignal(p->p_pptr, SIGCHLD);
183 	wakeup((caddr_t)p->p_pptr);
184 #if defined(tahoe)
185 	dkeyrelease(p->p_dkey), p->p_dkey = 0;
186 	ckeyrelease(p->p_ckey), p->p_ckey = 0;
187 	u.u_pcb.pcb_savacc.faddr = (float *)NULL;
188 #endif
189 	swtch();
190 }
191 
192 #ifdef COMPAT_43
193 owait(p, uap, retval)
194 	struct proc *p;
195 	register struct args {
196 		int	pid;
197 		int	*status;
198 		int	options;
199 		struct	rusage *rusage;
200 		int	compat;
201 	} *uap;
202 	int *retval;
203 {
204 
205 	if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) {
206 		uap->options = 0;
207 		uap->rusage = 0;
208 	} else {
209 		uap->options = u.u_ar0[R0];
210 		uap->rusage = (struct rusage *)u.u_ar0[R1];
211 	}
212 	uap->pid = WAIT_ANY;
213 	uap->status = 0;
214 	uap->compat = 1;
215 	return (wait1(p, uap, retval));
216 }
217 
218 wait4(p, uap, retval)
219 	struct proc *p;
220 	struct args {
221 		int	pid;
222 		int	*status;
223 		int	options;
224 		struct	rusage *rusage;
225 		int	compat;
226 	} *uap;
227 	int *retval;
228 {
229 
230 	uap->compat = 0;
231 	return (wait1(p, uap, retval));
232 }
233 #else
234 #define	wait1	wait4
235 #endif
236 
237 /*
238  * Wait system call.
239  * Search for a terminated (zombie) child,
240  * finally lay it to rest, and collect its status.
241  * Look also for stopped (traced) children,
242  * and pass back status from them.
243  */
244 wait1(q, uap, retval)
245 	register struct proc *q;
246 	register struct args {
247 		int	pid;
248 		int	*status;
249 		int	options;
250 		struct	rusage *rusage;
251 #ifdef COMPAT_43
252 		int compat;
253 #endif
254 	} *uap;
255 	int retval[];
256 {
257 	register int f;
258 	register struct proc *p;
259 	int status, error;
260 
261 	if (uap->pid == 0)
262 		uap->pid = -q->p_pgid;
263 #ifdef notyet
264 	if (uap->options &~ (WUNTRACED|WNOHANG))
265 		return (EINVAL);
266 #endif
267 loop:
268 	f = 0;
269 	for (p = q->p_cptr; p; p = p->p_osptr) {
270 		if (uap->pid != WAIT_ANY &&
271 		    p->p_pid != uap->pid && p->p_pgid != -uap->pid)
272 			continue;
273 		f++;
274 		if (p->p_stat == SZOMB) {
275 			retval[0] = p->p_pid;
276 #ifdef COMPAT_43
277 			if (uap->compat)
278 				retval[1] = p->p_xstat;
279 			else
280 #endif
281 			if (uap->status) {
282 				status = p->p_xstat;	/* convert to int */
283 				if (error = copyout((caddr_t)&status,
284 				    (caddr_t)uap->status, sizeof(status)))
285 					return (error);
286 			}
287 			if (uap->rusage && (error = copyout((caddr_t)p->p_ru,
288 			    (caddr_t)uap->rusage, sizeof (struct rusage))))
289 				return (error);
290 			pgrm(p);			/* off pgrp */
291 			p->p_xstat = 0;
292 			ruadd(&u.u_cru, p->p_ru);
293 			FREE(p->p_ru, M_ZOMBIE);
294 			p->p_ru = 0;
295 			p->p_stat = NULL;
296 			p->p_pid = 0;
297 			p->p_ppid = 0;
298 			if (*p->p_prev = p->p_nxt)	/* off zombproc */
299 				p->p_nxt->p_prev = p->p_prev;
300 			p->p_nxt = freeproc;		/* onto freeproc */
301 			freeproc = p;
302 			if (q = p->p_ysptr)
303 				q->p_osptr = p->p_osptr;
304 			if (q = p->p_osptr)
305 				q->p_ysptr = p->p_ysptr;
306 			if ((q = p->p_pptr)->p_cptr == p)
307 				q->p_cptr = p->p_osptr;
308 			p->p_pptr = 0;
309 			p->p_ysptr = 0;
310 			p->p_osptr = 0;
311 			p->p_cptr = 0;
312 			p->p_sig = 0;
313 			p->p_sigcatch = 0;
314 			p->p_sigignore = 0;
315 			p->p_sigmask = 0;
316 			/*p->p_pgrp = 0;*/
317 			p->p_flag = 0;
318 			p->p_wchan = 0;
319 			return (0);
320 		}
321 		if (p->p_stat == SSTOP && (p->p_flag & SWTED) == 0 &&
322 		    (p->p_flag & STRC || uap->options & WUNTRACED)) {
323 			p->p_flag |= SWTED;
324 			retval[0] = p->p_pid;
325 #ifdef COMPAT_43
326 			if (uap->compat) {
327 				retval[1] = W_STOPCODE(p->p_xstat);
328 				error = 0;
329 			} else
330 #endif
331 			if (uap->status) {
332 				status = W_STOPCODE(p->p_xstat);
333 				error = copyout((caddr_t)&status,
334 				    (caddr_t)uap->status, sizeof(status));
335 			} else
336 				error = 0;
337 			return (error);
338 		}
339 	}
340 	if (f == 0)
341 		return (ECHILD);
342 	if (uap->options & WNOHANG) {
343 		retval[0] = 0;
344 		return (0);
345 	}
346 	if (error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0))
347 		return (error);
348 	goto loop;
349 }
350