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