]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_exit.c
xnu-792.21.3.tar.gz
[apple/xnu.git] / bsd / kern / kern_exit.c
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */
29 /*
30 * Copyright (c) 1982, 1986, 1989, 1991, 1993
31 * The Regents of the University of California. All rights reserved.
32 * (c) UNIX System Laboratories, Inc.
33 * All or some portions of this file are derived from material licensed
34 * to the University of California by American Telephone and Telegraph
35 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
36 * the permission of UNIX System Laboratories, Inc.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
67 */
68
69 #include <machine/reg.h>
70 #include <machine/psl.h>
71
72 #include "compat_43.h"
73
74 #include <sys/param.h>
75 #include <sys/systm.h>
76 #include <sys/ioctl.h>
77 #include <sys/proc_internal.h>
78 #include <sys/kauth.h>
79 #include <sys/tty.h>
80 #include <sys/time.h>
81 #include <sys/resource.h>
82 #include <sys/kernel.h>
83 #include <sys/wait.h>
84 #include <sys/file_internal.h>
85 #include <sys/vnode_internal.h>
86 #include <sys/syslog.h>
87 #include <sys/malloc.h>
88 #include <sys/resourcevar.h>
89 #include <sys/ptrace.h>
90 #include <sys/user.h>
91 #include <sys/aio_kern.h>
92 #include <sys/sysproto.h>
93 #include <sys/signalvar.h>
94 #include <sys/filedesc.h> /* fdfree */
95 #include <sys/shm_internal.h> /* shmexit */
96 #include <sys/acct.h> /* acct_process */
97 #include <machine/spl.h>
98
99 #include <bsm/audit_kernel.h>
100 #include <bsm/audit_kevents.h>
101
102 #include <mach/mach_types.h>
103
104 #include <kern/kern_types.h>
105 #include <kern/kalloc.h>
106 #include <kern/task.h>
107 #include <kern/thread.h>
108 #include <kern/sched_prim.h>
109 #include <kern/assert.h>
110 #if KTRACE
111 #include <sys/ktrace.h>
112 #endif
113
114 #include <mach/mach_types.h>
115 #include <mach/task.h>
116 #include <mach/thread_act.h>
117 #include <mach/mach_traps.h> /* init_process */
118
119 extern char init_task_failure_data[];
120 int exit1(struct proc *, int, int *);
121 void proc_prepareexit(struct proc *p);
122 void vfork_exit(struct proc *p, int rv);
123 void vproc_exit(struct proc *p);
124 __private_extern__ void munge_rusage(struct rusage *a_rusage_p, struct user_rusage *a_user_rusage_p);
125
126 /*
127 * Things which should have prototypes in headers, but don't
128 */
129 void unix_syscall_return(int);
130 void *get_bsduthreadarg(thread_t);
131 void proc_exit(struct proc *p);
132 int wait1continue(int result);
133 int waitidcontinue(int result);
134 int *get_bsduthreadrval(thread_t);
135 kern_return_t sys_perf_notify(struct task *task, exception_data_t code,
136 mach_msg_type_number_t codeCnt);
137
138 /*
139 * NOTE: Source and target may *NOT* overlap!
140 * XXX Should share code with bsd/dev/ppc/unix_signal.c
141 */
142 static void
143 siginfo_64to32(user_siginfo_t *in, siginfo_t *out)
144 {
145 out->si_signo = in->si_signo;
146 out->si_errno = in->si_errno;
147 out->si_code = in->si_code;
148 out->si_pid = in->si_pid;
149 out->si_uid = in->si_uid;
150 out->si_status = in->si_status;
151 out->si_addr = CAST_DOWN(void *,in->si_addr);
152 /* following cast works for sival_int because of padding */
153 out->si_value.sival_ptr = CAST_DOWN(void *,in->si_value.sival_ptr);
154 out->si_band = in->si_band; /* range reduction */
155 out->pad[0] = in->pad[0]; /* mcontext.ss.r1 */
156 }
157
158 /*
159 * exit --
160 * Death of process.
161 */
162 void
163 exit(struct proc *p, struct exit_args *uap, int *retval)
164 {
165 exit1(p, W_EXITCODE(uap->rval, 0), retval);
166
167 /* drop funnel before we return */
168 thread_funnel_set(kernel_flock, FALSE);
169 thread_exception_return();
170 /* NOTREACHED */
171 while (TRUE)
172 thread_block(THREAD_CONTINUE_NULL);
173 /* NOTREACHED */
174 }
175
176 /*
177 * Exit: deallocate address space and other resources, change proc state
178 * to zombie, and unlink proc from allproc and parent's lists. Save exit
179 * status and rusage for wait(). Check for child processes and orphan them.
180 */
181 int
182 exit1(struct proc *p, int rv, int *retval)
183 {
184 thread_t self = current_thread();
185 struct task *task = p->task;
186 register int s;
187 struct uthread *ut;
188
189 /*
190 * If a thread in this task has already
191 * called exit(), then halt any others
192 * right here.
193 */
194
195 ut = get_bsdthread_info(self);
196 if (ut->uu_flag & UT_VFORK) {
197 vfork_exit(p, rv);
198 vfork_return(self, p->p_pptr, p , retval);
199 unix_syscall_return(0);
200 /* NOT REACHED */
201 }
202 AUDIT_SYSCALL_EXIT(0, p, ut); /* Exit is always successfull */
203 signal_lock(p);
204 while (p->exit_thread != self) {
205 if (sig_try_locked(p) <= 0) {
206 if (get_threadtask(self) != task) {
207 signal_unlock(p);
208 return(0);
209 }
210 signal_unlock(p);
211 thread_terminate(self);
212 thread_funnel_set(kernel_flock, FALSE);
213 thread_exception_return();
214 /* NOTREACHED */
215 }
216 sig_lock_to_exit(p);
217 }
218 signal_unlock(p);
219 if (p->p_pid == 1) {
220 printf("pid 1 exited (signal %d, exit %d)",
221 WTERMSIG(rv), WEXITSTATUS(rv));
222 panic("init died\nState at Last Exception:\n\n%s",
223 init_task_failure_data);
224 }
225
226 s = splsched();
227 p->p_flag |= P_WEXIT;
228 splx(s);
229 proc_prepareexit(p);
230 p->p_xstat = rv;
231
232 /* task terminate will call proc_terminate and that cleans it up */
233 task_terminate_internal(task);
234
235 return(0);
236 }
237
238 void
239 proc_prepareexit(struct proc *p)
240 {
241 struct uthread *ut;
242 exception_data_t code[EXCEPTION_CODE_MAX];
243 thread_t self = current_thread();
244
245 code[0] = (exception_data_t)0xFF000001; /* Set terminate code */
246 code[1] = (exception_data_t)p->p_pid; /* Pass out the pid */
247 /* Notify the perf server */
248 (void)sys_perf_notify(p->task, (exception_data_t)&code, 2);
249
250 /*
251 * Remove proc from allproc queue and from pidhash chain.
252 * Need to do this before we do anything that can block.
253 * Not doing causes things like mount() find this on allproc
254 * in partially cleaned state.
255 */
256 LIST_REMOVE(p, p_list);
257 LIST_INSERT_HEAD(&zombproc, p, p_list); /* Place onto zombproc. */
258 LIST_REMOVE(p, p_hash);
259
260 #ifdef PGINPROF
261 vmsizmon();
262 #endif
263 /*
264 * If parent is waiting for us to exit or exec,
265 * P_PPWAIT is set; we will wakeup the parent below.
266 */
267 p->p_flag &= ~(P_TRACED | P_PPWAIT);
268 p->p_sigignore = ~(sigcantmask);
269 p->p_siglist = 0;
270 ut = get_bsdthread_info(self);
271 ut->uu_siglist = 0;
272 untimeout(realitexpire, (caddr_t)p->p_pid);
273 }
274
275 void
276 proc_exit(struct proc *p)
277 {
278 register struct proc *q, *nq, *pp;
279 struct task *task = p->task;
280 register int s;
281 boolean_t funnel_state;
282
283 /* This can happen if thread_terminate of the single thread
284 * process
285 */
286
287 funnel_state = thread_funnel_set(kernel_flock, TRUE);
288 if( !(p->p_flag & P_WEXIT)) {
289 s = splsched();
290 p->p_flag |= P_WEXIT;
291 splx(s);
292 proc_prepareexit(p);
293 }
294
295 p->p_lflag |= P_LPEXIT;
296 /* XXX Zombie allocation may fail, in which case stats get lost */
297 MALLOC_ZONE(p->p_ru, struct rusage *,
298 sizeof (*p->p_ru), M_ZOMBIE, M_WAITOK);
299
300 /*
301 * need to cancel async IO requests that can be cancelled and wait for those
302 * already active. MAY BLOCK!
303 */
304
305 p->p_lflag |= P_LREFDRAIN;
306 while (p->p_internalref) {
307 p->p_lflag |= P_LREFDRAINWAIT;
308 msleep(&p->p_internalref, (lck_mtx_t *)0, 0, "proc_refdrain", 0) ;
309 }
310 p->p_lflag &= ~P_LREFDRAIN;
311 p->p_lflag |= P_LREFDEAD;
312
313 _aio_exit( p );
314
315 /*
316 * Close open files and release open-file table.
317 * This may block!
318 */
319 fdfree(p);
320
321 /* Close ref SYSV Shared memory*/
322 if (p->vm_shm)
323 shmexit(p);
324 /* Release SYSV semaphores */
325 semexit(p);
326
327 if (SESS_LEADER(p)) {
328 register struct session *sp = p->p_session;
329
330 if (sp->s_ttyvp) {
331 struct vnode *ttyvp;
332 struct vfs_context context;
333
334 /*
335 * Controlling process.
336 * Signal foreground pgrp,
337 * drain controlling terminal
338 * and revoke access to controlling terminal.
339 */
340 if (sp->s_ttyp->t_session == sp) {
341 if (sp->s_ttyp->t_pgrp)
342 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
343 (void) ttywait(sp->s_ttyp);
344 /*
345 * The tty could have been revoked
346 * if we blocked.
347 */
348 context.vc_proc = p;
349 context.vc_ucred = p->p_ucred;
350 if (sp->s_ttyvp)
351 VNOP_REVOKE(sp->s_ttyvp, REVOKEALL, &context);
352 }
353 ttyvp = sp->s_ttyvp;
354 sp->s_ttyvp = NULL;
355 if (ttyvp) {
356 vnode_rele(ttyvp);
357 }
358 /*
359 * s_ttyp is not zero'd; we use this to indicate
360 * that the session once had a controlling terminal.
361 * (for logging and informational purposes)
362 */
363 }
364 sp->s_leader = NULL;
365 }
366
367 fixjobc(p, p->p_pgrp, 0);
368 p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
369 (void)acct_process(p);
370
371 #if KTRACE
372 /*
373 * release trace file
374 */
375 p->p_traceflag = 0; /* don't trace the vnode_put() */
376 if (p->p_tracep) {
377 struct vnode *tvp = p->p_tracep;
378 p->p_tracep = NULL;
379 vnode_rele(tvp);
380 }
381 #endif
382
383 while (q = p->p_children.lh_first) {
384 proc_reparent(q, initproc);
385 /*
386 * Traced processes are killed
387 * since their existence means someone is messing up.
388 */
389 if (q->p_flag & P_TRACED) {
390 q->p_flag &= ~P_TRACED;
391 if (q->sigwait_thread) {
392 /*
393 * The sigwait_thread could be stopped at a
394 * breakpoint. Wake it up to kill.
395 * Need to do this as it could be a thread which is not
396 * the first thread in the task. So any attempts to kill
397 * the process would result into a deadlock on q->sigwait.
398 */
399 thread_resume((thread_t)q->sigwait_thread);
400 clear_wait(q->sigwait_thread, THREAD_INTERRUPTED);
401 threadsignal((thread_t)q->sigwait_thread, SIGKILL, 0);
402 }
403 psignal(q, SIGKILL);
404 }
405 }
406
407 /*
408 * Save exit status and final rusage info, adding in child rusage
409 * info and self times. If we were unable to allocate a zombie
410 * structure, this information is lost.
411 */
412 if (p->p_ru != NULL) {
413 *p->p_ru = p->p_stats->p_ru;
414
415 timerclear(&p->p_ru->ru_utime);
416 timerclear(&p->p_ru->ru_stime);
417
418 if (task) {
419 task_basic_info_data_t tinfo;
420 task_thread_times_info_data_t ttimesinfo;
421 int task_info_stuff, task_ttimes_stuff;
422 struct timeval ut,st;
423
424 task_info_stuff = TASK_BASIC_INFO_COUNT;
425 task_info(task, TASK_BASIC_INFO,
426 (task_info_t)&tinfo, &task_info_stuff);
427 p->p_ru->ru_utime.tv_sec = tinfo.user_time.seconds;
428 p->p_ru->ru_utime.tv_usec = tinfo.user_time.microseconds;
429 p->p_ru->ru_stime.tv_sec = tinfo.system_time.seconds;
430 p->p_ru->ru_stime.tv_usec = tinfo.system_time.microseconds;
431
432 task_ttimes_stuff = TASK_THREAD_TIMES_INFO_COUNT;
433 task_info(task, TASK_THREAD_TIMES_INFO,
434 (task_info_t)&ttimesinfo, &task_ttimes_stuff);
435
436 ut.tv_sec = ttimesinfo.user_time.seconds;
437 ut.tv_usec = ttimesinfo.user_time.microseconds;
438 st.tv_sec = ttimesinfo.system_time.seconds;
439 st.tv_usec = ttimesinfo.system_time.microseconds;
440 timeradd(&ut,&p->p_ru->ru_utime,&p->p_ru->ru_utime);
441 timeradd(&st,&p->p_ru->ru_stime,&p->p_ru->ru_stime);
442 }
443
444 ruadd(p->p_ru, &p->p_stats->p_cru);
445 }
446
447 /*
448 * Free up profiling buffers.
449 */
450 {
451 struct uprof *p0 = &p->p_stats->p_prof, *p1, *pn;
452
453 p1 = p0->pr_next;
454 p0->pr_next = NULL;
455 p0->pr_scale = 0;
456
457 for (; p1 != NULL; p1 = pn) {
458 pn = p1->pr_next;
459 kfree(p1, sizeof *p1);
460 }
461 }
462
463 /*
464 * Other substructures are freed from wait().
465 */
466 FREE_ZONE(p->p_stats, sizeof *p->p_stats, M_SUBPROC);
467 p->p_stats = NULL;
468
469 FREE_ZONE(p->p_sigacts, sizeof *p->p_sigacts, M_SUBPROC);
470 p->p_sigacts = NULL;
471
472 if (--p->p_limit->p_refcnt == 0)
473 FREE_ZONE(p->p_limit, sizeof *p->p_limit, M_SUBPROC);
474 p->p_limit = NULL;
475
476 /*
477 * Finish up by terminating the task
478 * and halt this thread (only if a
479 * member of the task exiting).
480 */
481 p->task = TASK_NULL;
482 //task->proc = NULL;
483 set_bsdtask_info(task, NULL);
484
485 KNOTE(&p->p_klist, NOTE_EXIT);
486
487 /*
488 * Notify parent that we're gone.
489 */
490 if (p->p_pptr->p_flag & P_NOCLDWAIT) {
491 struct proc *opp = p->p_pptr;
492
493 /*
494 * Add child resource usage to parent before giving
495 * zombie to init. If we were unable to allocate a
496 * zombie structure, this information is lost.
497 */
498 if (p->p_ru != NULL)
499 ruadd(&p->p_pptr->p_stats->p_cru, p->p_ru);
500
501 proc_reparent(p, initproc);
502 /* If there are no more children wakeup parent */
503 if (LIST_EMPTY(&opp->p_children))
504 wakeup((caddr_t)opp);
505 }
506 /* should be fine as parent proc would be initproc */
507 pp = p->p_pptr;
508 if (pp != initproc) {
509 pp->si_pid = p->p_pid;
510 pp->si_status = p->p_xstat;
511 pp->si_code = CLD_EXITED;
512 pp->si_uid = p->p_ucred->cr_ruid;
513 }
514 /* mark as a zombie */
515 p->p_stat = SZOMB;
516
517 psignal(pp, SIGCHLD);
518
519 /* and now wakeup the parent */
520 wakeup((caddr_t)p->p_pptr);
521
522 (void) thread_funnel_set(kernel_flock, funnel_state);
523 }
524
525
526 /*
527 * reap_child_process
528 *
529 * Description: Given a process from which all status information needed
530 * has already been extracted, if the process is a ptrace
531 * attach process, detach it and give it back to its real
532 * parent, else recover all resources remaining associated
533 * with it.
534 *
535 * Parameters: struct proc *parent Parent of process being reaped
536 * struct proc *child Process to reap
537 *
538 * Returns: 0 Process was not reaped because it
539 * came from an attach
540 * 1 Process was reaped
541 */
542 static int
543 reap_child_process(struct proc *parent, struct proc *child)
544 {
545 struct proc *trace_parent; /* Traced parent process, if tracing */
546 struct vnode *tvp; /* Traced vnode pointer, if used */
547
548 /*
549 * If we got the child via a ptrace 'attach',
550 * we need to give it back to the old parent.
551 */
552 if (child->p_oppid && (trace_parent = pfind(child->p_oppid))) {
553 child->p_oppid = 0;
554 proc_reparent(child, trace_parent);
555 if (trace_parent != initproc) {
556 trace_parent->si_pid = child->p_pid;
557 trace_parent->si_status = child->p_xstat;
558 trace_parent->si_code = CLD_CONTINUED;
559 trace_parent->si_uid = child->p_ucred->cr_ruid;
560 }
561 psignal(trace_parent, SIGCHLD);
562 wakeup((caddr_t)trace_parent);
563 return (0);
564 }
565 child->p_xstat = 0;
566 if (child->p_ru) {
567 ruadd(&parent->p_stats->p_cru, child->p_ru);
568 FREE_ZONE(child->p_ru, sizeof *child->p_ru, M_ZOMBIE);
569 child->p_ru = NULL;
570 } else {
571 printf("Warning : lost p_ru for %s\n", child->p_comm);
572 }
573
574 /*
575 * Decrement the count of procs running with this uid.
576 */
577 (void)chgproccnt(child->p_ucred->cr_ruid, -1);
578
579 /*
580 * Free up credentials.
581 */
582 if (child->p_ucred != NOCRED) {
583 kauth_cred_t ucr = child->p_ucred;
584 child->p_ucred = NOCRED;
585 kauth_cred_rele(ucr);
586 }
587
588 /*
589 * Release reference to text vnode
590 */
591 tvp = child->p_textvp;
592 child->p_textvp = NULL;
593 if (tvp) {
594 vnode_rele(tvp);
595 }
596 /*
597 * Finally finished with old proc entry.
598 * Unlink it from its process group and free it.
599 */
600 leavepgrp(child);
601 LIST_REMOVE(child, p_list); /* off zombproc */
602 LIST_REMOVE(child, p_sibling);
603 child->p_lflag &= ~P_LWAITING;
604 wakeup(&child->p_stat);
605
606 lck_mtx_destroy(&child->p_mlock, proc_lck_grp);
607 lck_mtx_destroy(&child->p_fdmlock, proc_lck_grp);
608 FREE_ZONE(child, sizeof *child, M_PROC);
609 nprocs--;
610 return (1);
611 }
612
613
614 int
615 wait1continue(int result)
616 {
617 void *vt;
618 thread_t thread;
619 int *retval;
620 struct proc *p;
621
622 if (result)
623 return(result);
624
625 p = current_proc();
626 thread = current_thread();
627 vt = get_bsduthreadarg(thread);
628 retval = get_bsduthreadrval(thread);
629 return(wait4((struct proc *)p, (struct wait4_args *)vt, retval));
630 }
631
632 int
633 wait4(struct proc *q, struct wait4_args *uap, register_t *retval)
634 {
635 register int nfound;
636 register struct proc *p;
637 int status, error;
638
639 if (uap->pid == 0)
640 uap->pid = -q->p_pgid;
641
642 loop:
643 nfound = 0;
644 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
645 if (uap->pid != WAIT_ANY &&
646 p->p_pid != uap->pid &&
647 p->p_pgid != -(uap->pid))
648 continue;
649 nfound++;
650
651 /* XXX This is racy because we don't get the lock!!!! */
652
653 if (p->p_lflag & P_LWAITING) {
654 (void)tsleep(&p->p_stat, PWAIT, "waitcoll", 0);
655 goto loop;
656 }
657 p->p_lflag |= P_LWAITING; /* only allow single thread to wait() */
658
659 if (p->p_stat == SZOMB) {
660 retval[0] = p->p_pid;
661 if (uap->status) {
662 status = p->p_xstat; /* convert to int */
663 error = copyout((caddr_t)&status,
664 uap->status,
665 sizeof(status));
666 if (error) {
667 p->p_lflag &= ~P_LWAITING;
668 wakeup(&p->p_stat);
669 return (error);
670 }
671 }
672 if (uap->rusage) {
673 if (p->p_ru == NULL) {
674 error = ENOMEM;
675 } else {
676 if (IS_64BIT_PROCESS(q)) {
677 struct user_rusage my_rusage;
678 munge_rusage(p->p_ru, &my_rusage);
679 error = copyout((caddr_t)&my_rusage,
680 uap->rusage,
681 sizeof (my_rusage));
682 }
683 else {
684 error = copyout((caddr_t)p->p_ru,
685 uap->rusage,
686 sizeof (struct rusage));
687 }
688 }
689 /* information unavailable? */
690 if (error) {
691 p->p_lflag &= ~P_LWAITING;
692 wakeup(&p->p_stat);
693 return (error);
694 }
695 }
696
697 /* Clean up */
698 if (!reap_child_process(q, p)) {
699 p->p_lflag &= ~P_LWAITING;
700 wakeup(&p->p_stat);
701 }
702
703 return (0);
704 }
705 if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
706 (p->p_flag & P_TRACED || uap->options & WUNTRACED)) {
707 p->p_flag |= P_WAITED;
708 retval[0] = p->p_pid;
709 if (uap->status) {
710 status = W_STOPCODE(p->p_xstat);
711 error = copyout((caddr_t)&status,
712 uap->status,
713 sizeof(status));
714 } else
715 error = 0;
716 p->p_lflag &= ~P_LWAITING;
717 wakeup(&p->p_stat);
718 return (error);
719 }
720 p->p_lflag &= ~P_LWAITING;
721 wakeup(&p->p_stat);
722 }
723 if (nfound == 0)
724 return (ECHILD);
725
726 if (uap->options & WNOHANG) {
727 retval[0] = 0;
728 return (0);
729 }
730
731 if ((error = tsleep0((caddr_t)q, PWAIT | PCATCH, "wait", 0, wait1continue)))
732 return (error);
733
734 goto loop;
735 }
736
737
738 int
739 waitidcontinue(int result)
740 {
741 void *vt;
742 thread_t thread;
743 int *retval;
744 struct proc *p;
745
746 if (result)
747 return(result);
748
749 p = current_proc();
750 thread = current_thread();
751 vt = get_bsduthreadarg(thread);
752 retval = get_bsduthreadrval(thread);
753 return(waitid((struct proc *)p, (struct waitid_args *)vt, retval));
754 }
755
756 /*
757 * Description: Suspend the calling thread until one child of the process
758 * containing the calling thread changes state.
759 *
760 * Parameters: uap->idtype one of P_PID, P_PGID, P_ALL
761 * uap->id pid_t or gid_t or ignored
762 * uap->infop Address of signinfo_t struct in
763 * user space into which to return status
764 * uap->options flag values
765 *
766 * Returns: 0 Success
767 * !0 Error returning status to user space
768 */
769 int
770 waitid(struct proc *q, struct waitid_args *uap, register_t *retval)
771 {
772 user_siginfo_t collect64; /* siginfo data to return to caller */
773
774 register int nfound;
775 register struct proc *p;
776 int error;
777
778 loop:
779 nfound = 0;
780 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
781 switch(uap->idtype) {
782 case P_PID: /* child with process ID equal to... */
783 if (p->p_pid != (pid_t)uap->id)
784 continue;
785 break;
786 case P_PGID: /* child with process group ID equal to... */
787 if (p->p_pgid != (pid_t)uap->id)
788 continue;
789 break;
790 case P_ALL: /* any child */
791 break;
792 }
793
794 /* XXX This is racy because we don't get the lock!!!! */
795
796 /*
797 * Wait collision; go to sleep and restart; used to maintain
798 * the single return for waited process guarantee.
799 */
800 if (p->p_lflag & P_LWAITING) {
801 (void)tsleep(&p->p_stat, PWAIT, "waitidcoll", 0);
802 goto loop;
803 }
804 p->p_lflag |= P_LWAITING; /* mark busy */
805
806 nfound++;
807
808 /*
809 * Types of processes we are interested in
810 *
811 * XXX Don't know what to do for WCONTINUED?!?
812 */
813 switch(p->p_stat) {
814 case SZOMB: /* Exited */
815 if (!(uap->options & WEXITED))
816 break;
817
818 /* Collect "siginfo" information for caller */
819 collect64.si_signo = 0;
820 collect64.si_code = 0;
821 collect64.si_errno = 0;
822 collect64.si_pid = 0;
823 collect64.si_uid = 0;
824 collect64.si_addr = 0;
825 collect64.si_status = p->p_xstat;
826 collect64.si_band = 0;
827
828 if (IS_64BIT_PROCESS(p)) {
829 error = copyout((caddr_t)&collect64,
830 uap->infop,
831 sizeof(collect64));
832 } else {
833 siginfo_t collect;
834 siginfo_64to32(&collect64,&collect);
835 error = copyout((caddr_t)&collect,
836 uap->infop,
837 sizeof(collect));
838 }
839 /* information unavailable? */
840 if (error) {
841 p->p_lflag &= ~P_LWAITING;
842 wakeup(&p->p_stat);
843 return (error);
844 }
845
846 /* Prevent other process for waiting for this event? */
847 if (!(uap->options & WNOWAIT)) {
848 /* Clean up */
849 if (!reap_child_process(q, p)) {
850 p->p_lflag &= ~P_LWAITING;
851 wakeup(&p->p_stat);
852 }
853 }
854
855 return (0);
856
857 case SSTOP: /* Stopped */
858 /*
859 * If we are not interested in stopped processes, then
860 * ignore this one.
861 */
862 if (!(uap->options & WSTOPPED))
863 break;
864
865 /*
866 * If someone has already waited it, we lost a race
867 * to be the one to return status.
868 */
869 if ((p->p_flag & P_WAITED) != 0)
870 break;
871
872 /*
873 * If this is not a traced process, and they haven't
874 * indicated an interest in untraced processes, then
875 * ignore this one.
876 */
877 if (!(p->p_flag & P_TRACED) && !(uap->options & WUNTRACED))
878 break;
879
880 /* Collect "siginfo" information for caller */
881 collect64.si_signo = 0;
882 collect64.si_code = 0;
883 collect64.si_errno = 0;
884 collect64.si_pid = 0;
885 collect64.si_uid = 0;
886 collect64.si_addr = 0;
887 collect64.si_status = p->p_xstat;
888 collect64.si_band = 0;
889
890 if (IS_64BIT_PROCESS(p)) {
891 error = copyout((caddr_t)&collect64,
892 uap->infop,
893 sizeof(collect64));
894 } else {
895 siginfo_t collect;
896 siginfo_64to32(&collect64,&collect);
897 error = copyout((caddr_t)&collect,
898 uap->infop,
899 sizeof(collect));
900 }
901 /* information unavailable? */
902 if (error) {
903 p->p_lflag &= ~P_LWAITING;
904 wakeup(&p->p_stat);
905 return (error);
906 }
907
908 /* Prevent other process for waiting for this event? */
909 if (!(uap->options & WNOWAIT)) {
910 p->p_flag |= P_WAITED;
911 }
912
913 p->p_lflag &= ~P_LWAITING;
914 wakeup(&p->p_stat);
915 return (0);
916
917 default: /* All others */
918 /* ...meaning Continued */
919 if (!(uap->options & WCONTINUED))
920 break;
921
922 /*
923 * If the flag isn't set, then this process has not
924 * been stopped and continued, or the status has
925 * already been reaped by another caller of waitid().
926 */
927 if ((p->p_flag & P_CONTINUED) == 0)
928 break;
929
930 /* Collect "siginfo" information for caller */
931 collect64.si_signo = 0;
932 collect64.si_code = 0;
933 collect64.si_errno = 0;
934 collect64.si_pid = 0;
935 collect64.si_uid = 0;
936 collect64.si_addr = 0;
937 collect64.si_status = p->p_xstat;
938 collect64.si_band = 0;
939
940 if (IS_64BIT_PROCESS(p)) {
941 error = copyout((caddr_t)&collect64,
942 uap->infop,
943 sizeof(collect64));
944 } else {
945 siginfo_t collect;
946 siginfo_64to32(&collect64,&collect);
947 error = copyout((caddr_t)&collect,
948 uap->infop,
949 sizeof(collect));
950 }
951 /* information unavailable? */
952 if (error) {
953 p->p_lflag &= ~P_LWAITING;
954 wakeup(&p->p_stat);
955 return (error);
956 }
957
958 /* Prevent other process for waiting for this event? */
959 if (!(uap->options & WNOWAIT)) {
960 p->p_flag &= ~P_CONTINUED;
961 }
962
963 p->p_lflag &= ~P_LWAITING;
964 wakeup(&p->p_stat);
965 return (0);
966
967 break;
968 }
969
970
971 /* Not a process we are interested in; go on to next child */
972 p->p_lflag &= ~P_LWAITING;
973 wakeup(&p->p_stat);
974 }
975
976 /* No child processes that could possibly satisfy the request? */
977 if (nfound == 0)
978 return (ECHILD);
979
980 if (uap->options & WNOHANG) {
981 retval[0] = 0;
982 return (0);
983 }
984
985 if ((error = tsleep0((caddr_t)q, PWAIT | PCATCH, "waitid", 0, waitidcontinue)))
986 return (error);
987
988 goto loop;
989 }
990
991 /*
992 * make process 'parent' the new parent of process 'child'.
993 */
994 void
995 proc_reparent(struct proc *child, struct proc *parent)
996 {
997
998 if (child->p_pptr == parent)
999 return;
1000
1001 LIST_REMOVE(child, p_sibling);
1002 LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
1003 child->p_pptr = parent;
1004
1005 if (initproc == parent && child->p_stat == SZOMB)
1006 psignal(initproc, SIGCHLD);
1007 }
1008
1009 /*
1010 * Make the current process an "init" process, meaning
1011 * that it doesn't have a parent, and that it won't be
1012 * gunned down by kill(-1, 0).
1013 */
1014 kern_return_t
1015 init_process(__unused struct init_process_args *args)
1016 {
1017 register struct proc *p = current_proc();
1018
1019 AUDIT_MACH_SYSCALL_ENTER(AUE_INITPROCESS);
1020 if (suser(kauth_cred_get(), &p->p_acflag)) {
1021 AUDIT_MACH_SYSCALL_EXIT(KERN_NO_ACCESS);
1022 return(KERN_NO_ACCESS);
1023 }
1024
1025 if (p->p_pid != 1 && p->p_pgid != p->p_pid)
1026 enterpgrp(p, p->p_pid, 0);
1027 p->p_flag |= P_SYSTEM;
1028
1029 /*
1030 * Take us out of the sibling chain, and
1031 * out of our parent's child chain.
1032 */
1033 LIST_REMOVE(p, p_sibling);
1034 p->p_sibling.le_prev = NULL;
1035 p->p_sibling.le_next = NULL;
1036 p->p_pptr = kernproc;
1037
1038 AUDIT_MACH_SYSCALL_EXIT(KERN_SUCCESS);
1039 return(KERN_SUCCESS);
1040 }
1041
1042
1043 /*
1044 * Exit: deallocate address space and other resources, change proc state
1045 * to zombie, and unlink proc from allproc and parent's lists. Save exit
1046 * status and rusage for wait(). Check for child processes and orphan them.
1047 */
1048
1049 void
1050 vfork_exit(struct proc *p, int rv)
1051 {
1052 thread_t self = current_thread();
1053 #ifdef FIXME
1054 struct task *task = p->task;
1055 #endif
1056 register int s;
1057 struct uthread *ut;
1058 exception_data_t code[EXCEPTION_CODE_MAX];
1059
1060 /*
1061 * If a thread in this task has already
1062 * called exit(), then halt any others
1063 * right here.
1064 */
1065
1066 ut = get_bsdthread_info(self);
1067 #ifdef FIXME
1068 signal_lock(p);
1069 while (p->exit_thread != self) {
1070 if (sig_try_locked(p) <= 0) {
1071 if (get_threadtask(self) != task) {
1072 signal_unlock(p);
1073 return;
1074 }
1075 signal_unlock(p);
1076 thread_terminate(self);
1077 thread_funnel_set(kernel_flock, FALSE);
1078 thread_exception_return();
1079 /* NOTREACHED */
1080 }
1081 sig_lock_to_exit(p);
1082 }
1083 signal_unlock(p);
1084 if (p->p_pid == 1) {
1085 printf("pid 1 exited (signal %d, exit %d)",
1086 WTERMSIG(rv), WEXITSTATUS(rv));
1087 panic("init died\nState at Last Exception:\n\n%s", init_task_failure_data);
1088 }
1089 #endif /* FIXME */
1090
1091 s = splsched();
1092 p->p_flag |= P_WEXIT;
1093 p->p_lflag |= P_LPEXIT;
1094 splx(s);
1095
1096 code[0] = (exception_data_t)0xFF000001; /* Set terminate code */
1097 code[1] = (exception_data_t)p->p_pid; /* Pass out the pid */
1098 /* Notify the perf server */
1099 (void)sys_perf_notify(p->task, (exception_data_t)&code, 2);
1100
1101 /*
1102 * Remove proc from allproc queue and from pidhash chain.
1103 * Need to do this before we do anything that can block.
1104 * Not doing causes things like mount() find this on allproc
1105 * in partially cleaned state.
1106 */
1107 LIST_REMOVE(p, p_list);
1108 LIST_INSERT_HEAD(&zombproc, p, p_list); /* Place onto zombproc. */
1109 LIST_REMOVE(p, p_hash);
1110 /*
1111 * If parent is waiting for us to exit or exec,
1112 * P_PPWAIT is set; we will wakeup the parent below.
1113 */
1114 p->p_flag &= ~(P_TRACED | P_PPWAIT);
1115 p->p_sigignore = ~0;
1116 p->p_siglist = 0;
1117
1118 ut->uu_siglist = 0;
1119 untimeout(realitexpire, (caddr_t)p->p_pid);
1120
1121 p->p_xstat = rv;
1122
1123 vproc_exit(p);
1124 }
1125
1126 void
1127 vproc_exit(struct proc *p)
1128 {
1129 register struct proc *q, *nq, *pp;
1130 #ifdef FIXME
1131 struct task *task = p->task;
1132 #endif
1133
1134 /* XXX Zombie allocation may fail, in which case stats get lost */
1135 MALLOC_ZONE(p->p_ru, struct rusage *,
1136 sizeof (*p->p_ru), M_ZOMBIE, M_WAITOK);
1137
1138 /*
1139 * Close open files and release open-file table.
1140 * This may block!
1141 */
1142 fdfree(p);
1143
1144 if (SESS_LEADER(p)) {
1145 register struct session *sp = p->p_session;
1146
1147 if (sp->s_ttyvp) {
1148 struct vnode *ttyvp;
1149 struct vfs_context context;
1150
1151 /*
1152 * Controlling process.
1153 * Signal foreground pgrp,
1154 * drain controlling terminal
1155 * and revoke access to controlling terminal.
1156 */
1157 if (sp->s_ttyp->t_session == sp) {
1158 if (sp->s_ttyp->t_pgrp)
1159 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
1160 (void) ttywait(sp->s_ttyp);
1161 /*
1162 * The tty could have been revoked
1163 * if we blocked.
1164 */
1165 context.vc_proc = p;
1166 context.vc_ucred = p->p_ucred;
1167 if (sp->s_ttyvp)
1168 VNOP_REVOKE(sp->s_ttyvp, REVOKEALL, &context);
1169 }
1170 ttyvp = sp->s_ttyvp;
1171 sp->s_ttyvp = NULL;
1172 if (ttyvp) {
1173 vnode_rele(ttyvp);
1174 }
1175 /*
1176 * s_ttyp is not zero'd; we use this to indicate
1177 * that the session once had a controlling terminal.
1178 * (for logging and informational purposes)
1179 */
1180 }
1181 sp->s_leader = NULL;
1182 }
1183
1184 fixjobc(p, p->p_pgrp, 0);
1185 p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
1186
1187 #if KTRACE
1188 /*
1189 * release trace file
1190 */
1191 p->p_traceflag = 0; /* don't trace the vnode_rele() */
1192 if (p->p_tracep) {
1193 struct vnode *tvp = p->p_tracep;
1194 p->p_tracep = NULL;
1195 vnode_rele(tvp);
1196 }
1197 #endif
1198
1199 while (q = p->p_children.lh_first) {
1200 proc_reparent(q, initproc);
1201 /*
1202 * Traced processes are killed
1203 * since their existence means someone is messing up.
1204 */
1205 if (q->p_flag & P_TRACED) {
1206 q->p_flag &= ~P_TRACED;
1207 if (q->sigwait_thread) {
1208 /*
1209 * The sigwait_thread could be stopped at a
1210 * breakpoint. Wake it up to kill.
1211 * Need to do this as it could be a thread which is not
1212 * the first thread in the task. So any attempts to kill
1213 * the process would result into a deadlock on q->sigwait.
1214 */
1215 thread_resume((thread_t)q->sigwait_thread);
1216 clear_wait(q->sigwait_thread, THREAD_INTERRUPTED);
1217 threadsignal((thread_t)q->sigwait_thread, SIGKILL, 0);
1218 }
1219 psignal(q, SIGKILL);
1220 }
1221 }
1222
1223 /*
1224 * Save exit status and final rusage info, adding in child rusage
1225 * info and self times. If we were unable to allocate a zombie
1226 * structure, this information is lost.
1227 */
1228 if (p->p_ru != NULL) {
1229 *p->p_ru = p->p_stats->p_ru;
1230 timerclear(&p->p_ru->ru_utime);
1231 timerclear(&p->p_ru->ru_stime);
1232
1233 #ifdef FIXME
1234 if (task) {
1235 task_basic_info_data_t tinfo;
1236 task_thread_times_info_data_t ttimesinfo;
1237 int task_info_stuff, task_ttimes_stuff;
1238 struct timeval ut,st;
1239
1240 task_info_stuff = TASK_BASIC_INFO_COUNT;
1241 task_info(task, TASK_BASIC_INFO,
1242 &tinfo, &task_info_stuff);
1243 p->p_ru->ru_utime.tv_sec = tinfo.user_time.seconds;
1244 p->p_ru->ru_utime.tv_usec = tinfo.user_time.microseconds;
1245 p->p_ru->ru_stime.tv_sec = tinfo.system_time.seconds;
1246 p->p_ru->ru_stime.tv_usec = tinfo.system_time.microseconds;
1247
1248 task_ttimes_stuff = TASK_THREAD_TIMES_INFO_COUNT;
1249 task_info(task, TASK_THREAD_TIMES_INFO,
1250 &ttimesinfo, &task_ttimes_stuff);
1251
1252 ut.tv_sec = ttimesinfo.user_time.seconds;
1253 ut.tv_usec = ttimesinfo.user_time.microseconds;
1254 st.tv_sec = ttimesinfo.system_time.seconds;
1255 st.tv_usec = ttimesinfo.system_time.microseconds;
1256 timeradd(&ut,&p->p_ru->ru_utime,&p->p_ru->ru_utime);
1257 timeradd(&st,&p->p_ru->ru_stime,&p->p_ru->ru_stime);
1258 }
1259 #endif /* FIXME */
1260
1261 ruadd(p->p_ru, &p->p_stats->p_cru);
1262 }
1263
1264 /*
1265 * Free up profiling buffers.
1266 */
1267 {
1268 struct uprof *p0 = &p->p_stats->p_prof, *p1, *pn;
1269
1270 p1 = p0->pr_next;
1271 p0->pr_next = NULL;
1272 p0->pr_scale = 0;
1273
1274 for (; p1 != NULL; p1 = pn) {
1275 pn = p1->pr_next;
1276 kfree(p1, sizeof *p1);
1277 }
1278 }
1279
1280 /*
1281 * Other substructures are freed from wait().
1282 */
1283 FREE_ZONE(p->p_stats, sizeof *p->p_stats, M_SUBPROC);
1284 p->p_stats = NULL;
1285
1286 FREE_ZONE(p->p_sigacts, sizeof *p->p_sigacts, M_SUBPROC);
1287 p->p_sigacts = NULL;
1288
1289 if (--p->p_limit->p_refcnt == 0)
1290 FREE_ZONE(p->p_limit, sizeof *p->p_limit, M_SUBPROC);
1291 p->p_limit = NULL;
1292
1293 /*
1294 * Finish up by terminating the task
1295 * and halt this thread (only if a
1296 * member of the task exiting).
1297 */
1298 p->task = TASK_NULL;
1299
1300 /*
1301 * Notify parent that we're gone.
1302 */
1303 pp = p->p_pptr;
1304 if (pp != initproc) {
1305 pp->si_pid = p->p_pid;
1306 pp->si_status = p->p_xstat;
1307 pp->si_code = CLD_EXITED;
1308 pp->si_uid = p->p_ucred->cr_ruid;
1309 }
1310 /* mark as a zombie */
1311 p->p_stat = SZOMB;
1312
1313 psignal(p->p_pptr, SIGCHLD);
1314
1315 /* and now wakeup the parent */
1316 wakeup((caddr_t)p->p_pptr);
1317 }
1318
1319
1320 /*
1321 * munge_rusage
1322 * LP64 support - long is 64 bits if we are dealing with a 64 bit user
1323 * process. We munge the kernel (32 bit) version of rusage into the
1324 * 64 bit version.
1325 */
1326 __private_extern__ void
1327 munge_rusage(struct rusage *a_rusage_p, struct user_rusage *a_user_rusage_p)
1328 {
1329 /* timeval changes size, so utime and stime need special handling */
1330 a_user_rusage_p->ru_utime.tv_sec = a_rusage_p->ru_utime.tv_sec;
1331 a_user_rusage_p->ru_utime.tv_usec = a_rusage_p->ru_utime.tv_usec;
1332 a_user_rusage_p->ru_stime.tv_sec = a_rusage_p->ru_stime.tv_sec;
1333 a_user_rusage_p->ru_stime.tv_usec = a_rusage_p->ru_stime.tv_usec;
1334 /*
1335 * everything else can be a direct assign, since there is no loss
1336 * of precision implied boing 32->64.
1337 */
1338 a_user_rusage_p->ru_maxrss = a_rusage_p->ru_maxrss;
1339 a_user_rusage_p->ru_ixrss = a_rusage_p->ru_ixrss;
1340 a_user_rusage_p->ru_idrss = a_rusage_p->ru_idrss;
1341 a_user_rusage_p->ru_isrss = a_rusage_p->ru_isrss;
1342 a_user_rusage_p->ru_minflt = a_rusage_p->ru_minflt;
1343 a_user_rusage_p->ru_majflt = a_rusage_p->ru_majflt;
1344 a_user_rusage_p->ru_nswap = a_rusage_p->ru_nswap;
1345 a_user_rusage_p->ru_inblock = a_rusage_p->ru_inblock;
1346 a_user_rusage_p->ru_oublock = a_rusage_p->ru_oublock;
1347 a_user_rusage_p->ru_msgsnd = a_rusage_p->ru_msgsnd;
1348 a_user_rusage_p->ru_msgrcv = a_rusage_p->ru_msgrcv;
1349 a_user_rusage_p->ru_nsignals = a_rusage_p->ru_nsignals;
1350 a_user_rusage_p->ru_nvcsw = a_rusage_p->ru_nvcsw;
1351 a_user_rusage_p->ru_nivcsw = a_rusage_p->ru_nivcsw;
1352 }