]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_exit.c
06ee02894803ef5becd1d4212795b2242924dda6
[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 = kauth_cred_proc_ref(p);
350 if (sp->s_ttyvp)
351 VNOP_REVOKE(sp->s_ttyvp, REVOKEALL, &context);
352 kauth_cred_unref(&context.vc_ucred);
353 }
354 ttyvp = sp->s_ttyvp;
355 sp->s_ttyvp = NULL;
356 if (ttyvp) {
357 vnode_rele(ttyvp);
358 }
359 /*
360 * s_ttyp is not zero'd; we use this to indicate
361 * that the session once had a controlling terminal.
362 * (for logging and informational purposes)
363 */
364 }
365 sp->s_leader = NULL;
366 }
367
368 fixjobc(p, p->p_pgrp, 0);
369 p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
370 (void)acct_process(p);
371
372 #if KTRACE
373 /*
374 * release trace file
375 */
376 p->p_traceflag = 0; /* don't trace the vnode_put() */
377 if (p->p_tracep) {
378 struct vnode *tvp = p->p_tracep;
379 p->p_tracep = NULL;
380 vnode_rele(tvp);
381 }
382 #endif
383
384 while (q = p->p_children.lh_first) {
385 proc_reparent(q, initproc);
386 /*
387 * Traced processes are killed
388 * since their existence means someone is messing up.
389 */
390 if (q->p_flag & P_TRACED) {
391 q->p_flag &= ~P_TRACED;
392 if (q->sigwait_thread) {
393 /*
394 * The sigwait_thread could be stopped at a
395 * breakpoint. Wake it up to kill.
396 * Need to do this as it could be a thread which is not
397 * the first thread in the task. So any attempts to kill
398 * the process would result into a deadlock on q->sigwait.
399 */
400 thread_resume((thread_t)q->sigwait_thread);
401 clear_wait(q->sigwait_thread, THREAD_INTERRUPTED);
402 threadsignal((thread_t)q->sigwait_thread, SIGKILL, 0);
403 }
404 psignal(q, SIGKILL);
405 }
406 }
407
408 /*
409 * Save exit status and final rusage info, adding in child rusage
410 * info and self times. If we were unable to allocate a zombie
411 * structure, this information is lost.
412 */
413 if (p->p_ru != NULL) {
414 *p->p_ru = p->p_stats->p_ru;
415
416 timerclear(&p->p_ru->ru_utime);
417 timerclear(&p->p_ru->ru_stime);
418
419 if (task) {
420 task_basic_info_data_t tinfo;
421 task_thread_times_info_data_t ttimesinfo;
422 int task_info_stuff, task_ttimes_stuff;
423 struct timeval ut,st;
424
425 task_info_stuff = TASK_BASIC_INFO_COUNT;
426 task_info(task, TASK_BASIC_INFO,
427 (task_info_t)&tinfo, &task_info_stuff);
428 p->p_ru->ru_utime.tv_sec = tinfo.user_time.seconds;
429 p->p_ru->ru_utime.tv_usec = tinfo.user_time.microseconds;
430 p->p_ru->ru_stime.tv_sec = tinfo.system_time.seconds;
431 p->p_ru->ru_stime.tv_usec = tinfo.system_time.microseconds;
432
433 task_ttimes_stuff = TASK_THREAD_TIMES_INFO_COUNT;
434 task_info(task, TASK_THREAD_TIMES_INFO,
435 (task_info_t)&ttimesinfo, &task_ttimes_stuff);
436
437 ut.tv_sec = ttimesinfo.user_time.seconds;
438 ut.tv_usec = ttimesinfo.user_time.microseconds;
439 st.tv_sec = ttimesinfo.system_time.seconds;
440 st.tv_usec = ttimesinfo.system_time.microseconds;
441 timeradd(&ut,&p->p_ru->ru_utime,&p->p_ru->ru_utime);
442 timeradd(&st,&p->p_ru->ru_stime,&p->p_ru->ru_stime);
443 }
444
445 ruadd(p->p_ru, &p->p_stats->p_cru);
446 }
447
448 /*
449 * Free up profiling buffers.
450 */
451 {
452 struct uprof *p0 = &p->p_stats->p_prof, *p1, *pn;
453
454 p1 = p0->pr_next;
455 p0->pr_next = NULL;
456 p0->pr_scale = 0;
457
458 for (; p1 != NULL; p1 = pn) {
459 pn = p1->pr_next;
460 kfree(p1, sizeof *p1);
461 }
462 }
463
464 /*
465 * Other substructures are freed from wait().
466 */
467 FREE_ZONE(p->p_stats, sizeof *p->p_stats, M_SUBPROC);
468 p->p_stats = NULL;
469
470 FREE_ZONE(p->p_sigacts, sizeof *p->p_sigacts, M_SUBPROC);
471 p->p_sigacts = NULL;
472
473 if (--p->p_limit->p_refcnt == 0)
474 FREE_ZONE(p->p_limit, sizeof *p->p_limit, M_SUBPROC);
475 p->p_limit = NULL;
476
477 /*
478 * Finish up by terminating the task
479 * and halt this thread (only if a
480 * member of the task exiting).
481 */
482 p->task = TASK_NULL;
483 //task->proc = NULL;
484 set_bsdtask_info(task, NULL);
485
486 KNOTE(&p->p_klist, NOTE_EXIT);
487
488 /*
489 * Notify parent that we're gone.
490 */
491 if (p->p_pptr->p_flag & P_NOCLDWAIT) {
492 struct proc *opp = p->p_pptr;
493
494 /*
495 * Add child resource usage to parent before giving
496 * zombie to init. If we were unable to allocate a
497 * zombie structure, this information is lost.
498 */
499 if (p->p_ru != NULL)
500 ruadd(&p->p_pptr->p_stats->p_cru, p->p_ru);
501
502 proc_reparent(p, initproc);
503 /* If there are no more children wakeup parent */
504 if (LIST_EMPTY(&opp->p_children))
505 wakeup((caddr_t)opp);
506 }
507 /* should be fine as parent proc would be initproc */
508 pp = p->p_pptr;
509 if (pp != initproc) {
510 pp->si_pid = p->p_pid;
511 pp->si_status = p->p_xstat;
512 pp->si_code = CLD_EXITED;
513 pp->si_uid = p->p_ucred->cr_ruid;
514 }
515 /* mark as a zombie */
516 p->p_stat = SZOMB;
517
518 psignal(pp, SIGCHLD);
519
520 /* and now wakeup the parent */
521 wakeup((caddr_t)p->p_pptr);
522
523 (void) thread_funnel_set(kernel_flock, funnel_state);
524 }
525
526
527 /*
528 * reap_child_process
529 *
530 * Description: Given a process from which all status information needed
531 * has already been extracted, if the process is a ptrace
532 * attach process, detach it and give it back to its real
533 * parent, else recover all resources remaining associated
534 * with it.
535 *
536 * Parameters: struct proc *parent Parent of process being reaped
537 * struct proc *child Process to reap
538 *
539 * Returns: 0 Process was not reaped because it
540 * came from an attach
541 * 1 Process was reaped
542 */
543 static int
544 reap_child_process(struct proc *parent, struct proc *child)
545 {
546 struct proc *trace_parent; /* Traced parent process, if tracing */
547 struct vnode *tvp; /* Traced vnode pointer, if used */
548
549 /*
550 * If we got the child via a ptrace 'attach',
551 * we need to give it back to the old parent.
552 */
553 if (child->p_oppid && (trace_parent = pfind(child->p_oppid))) {
554 child->p_oppid = 0;
555 proc_reparent(child, trace_parent);
556 if (trace_parent != initproc) {
557 trace_parent->si_pid = child->p_pid;
558 trace_parent->si_status = child->p_xstat;
559 trace_parent->si_code = CLD_CONTINUED;
560 trace_parent->si_uid = child->p_ucred->cr_ruid;
561 }
562 psignal(trace_parent, SIGCHLD);
563 wakeup((caddr_t)trace_parent);
564 return (0);
565 }
566 child->p_xstat = 0;
567 if (child->p_ru) {
568 ruadd(&parent->p_stats->p_cru, child->p_ru);
569 FREE_ZONE(child->p_ru, sizeof *child->p_ru, M_ZOMBIE);
570 child->p_ru = NULL;
571 } else {
572 printf("Warning : lost p_ru for %s\n", child->p_comm);
573 }
574
575 /*
576 * Decrement the count of procs running with this uid.
577 */
578 (void)chgproccnt(child->p_ucred->cr_ruid, -1);
579
580 /*
581 * Free up credentials.
582 */
583 if (IS_VALID_CRED(child->p_ucred)) {
584 kauth_cred_unref(&child->p_ucred);
585 }
586
587 /*
588 * Release reference to text vnode
589 */
590 tvp = child->p_textvp;
591 child->p_textvp = NULL;
592 if (tvp) {
593 vnode_rele(tvp);
594 }
595 /*
596 * Finally finished with old proc entry.
597 * Unlink it from its process group and free it.
598 */
599 leavepgrp(child);
600 LIST_REMOVE(child, p_list); /* off zombproc */
601 LIST_REMOVE(child, p_sibling);
602 child->p_lflag &= ~P_LWAITING;
603 wakeup(&child->p_stat);
604
605 lck_mtx_destroy(&child->p_mlock, proc_lck_grp);
606 lck_mtx_destroy(&child->p_fdmlock, proc_lck_grp);
607 FREE_ZONE(child, sizeof *child, M_PROC);
608 nprocs--;
609 return (1);
610 }
611
612
613 int
614 wait1continue(int result)
615 {
616 void *vt;
617 thread_t thread;
618 int *retval;
619 struct proc *p;
620
621 if (result)
622 return(result);
623
624 p = current_proc();
625 thread = current_thread();
626 vt = get_bsduthreadarg(thread);
627 retval = get_bsduthreadrval(thread);
628 return(wait4((struct proc *)p, (struct wait4_args *)vt, retval));
629 }
630
631 int
632 wait4(struct proc *q, struct wait4_args *uap, register_t *retval)
633 {
634 register int nfound;
635 register struct proc *p;
636 int status, error;
637
638 if (uap->pid == 0)
639 uap->pid = -q->p_pgid;
640
641 loop:
642 nfound = 0;
643 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
644 if (uap->pid != WAIT_ANY &&
645 p->p_pid != uap->pid &&
646 p->p_pgid != -(uap->pid))
647 continue;
648 nfound++;
649
650 /* XXX This is racy because we don't get the lock!!!! */
651
652 if (p->p_lflag & P_LWAITING) {
653 (void)tsleep(&p->p_stat, PWAIT, "waitcoll", 0);
654 goto loop;
655 }
656 p->p_lflag |= P_LWAITING; /* only allow single thread to wait() */
657
658 if (p->p_stat == SZOMB) {
659 retval[0] = p->p_pid;
660 if (uap->status) {
661 status = p->p_xstat; /* convert to int */
662 error = copyout((caddr_t)&status,
663 uap->status,
664 sizeof(status));
665 if (error) {
666 p->p_lflag &= ~P_LWAITING;
667 wakeup(&p->p_stat);
668 return (error);
669 }
670 }
671 if (uap->rusage) {
672 if (p->p_ru == NULL) {
673 error = ENOMEM;
674 } else {
675 if (IS_64BIT_PROCESS(q)) {
676 struct user_rusage my_rusage;
677 munge_rusage(p->p_ru, &my_rusage);
678 error = copyout((caddr_t)&my_rusage,
679 uap->rusage,
680 sizeof (my_rusage));
681 }
682 else {
683 error = copyout((caddr_t)p->p_ru,
684 uap->rusage,
685 sizeof (struct rusage));
686 }
687 }
688 /* information unavailable? */
689 if (error) {
690 p->p_lflag &= ~P_LWAITING;
691 wakeup(&p->p_stat);
692 return (error);
693 }
694 }
695
696 /* Clean up */
697 if (!reap_child_process(q, p)) {
698 p->p_lflag &= ~P_LWAITING;
699 wakeup(&p->p_stat);
700 }
701
702 return (0);
703 }
704 if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
705 (p->p_flag & P_TRACED || uap->options & WUNTRACED)) {
706 p->p_flag |= P_WAITED;
707 retval[0] = p->p_pid;
708 if (uap->status) {
709 status = W_STOPCODE(p->p_xstat);
710 error = copyout((caddr_t)&status,
711 uap->status,
712 sizeof(status));
713 } else
714 error = 0;
715 p->p_lflag &= ~P_LWAITING;
716 wakeup(&p->p_stat);
717 return (error);
718 }
719 p->p_lflag &= ~P_LWAITING;
720 wakeup(&p->p_stat);
721 }
722 if (nfound == 0)
723 return (ECHILD);
724
725 if (uap->options & WNOHANG) {
726 retval[0] = 0;
727 return (0);
728 }
729
730 if ((error = tsleep0((caddr_t)q, PWAIT | PCATCH, "wait", 0, wait1continue)))
731 return (error);
732
733 goto loop;
734 }
735
736
737 int
738 waitidcontinue(int result)
739 {
740 void *vt;
741 thread_t thread;
742 int *retval;
743 struct proc *p;
744
745 if (result)
746 return(result);
747
748 p = current_proc();
749 thread = current_thread();
750 vt = get_bsduthreadarg(thread);
751 retval = get_bsduthreadrval(thread);
752 return(waitid((struct proc *)p, (struct waitid_args *)vt, retval));
753 }
754
755 /*
756 * Description: Suspend the calling thread until one child of the process
757 * containing the calling thread changes state.
758 *
759 * Parameters: uap->idtype one of P_PID, P_PGID, P_ALL
760 * uap->id pid_t or gid_t or ignored
761 * uap->infop Address of signinfo_t struct in
762 * user space into which to return status
763 * uap->options flag values
764 *
765 * Returns: 0 Success
766 * !0 Error returning status to user space
767 */
768 int
769 waitid(struct proc *q, struct waitid_args *uap, register_t *retval)
770 {
771 user_siginfo_t collect64; /* siginfo data to return to caller */
772
773 register int nfound;
774 register struct proc *p;
775 int error;
776
777 loop:
778 nfound = 0;
779 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
780 switch(uap->idtype) {
781 case P_PID: /* child with process ID equal to... */
782 if (p->p_pid != (pid_t)uap->id)
783 continue;
784 break;
785 case P_PGID: /* child with process group ID equal to... */
786 if (p->p_pgid != (pid_t)uap->id)
787 continue;
788 break;
789 case P_ALL: /* any child */
790 break;
791 }
792
793 /* XXX This is racy because we don't get the lock!!!! */
794
795 /*
796 * Wait collision; go to sleep and restart; used to maintain
797 * the single return for waited process guarantee.
798 */
799 if (p->p_lflag & P_LWAITING) {
800 (void)tsleep(&p->p_stat, PWAIT, "waitidcoll", 0);
801 goto loop;
802 }
803 p->p_lflag |= P_LWAITING; /* mark busy */
804
805 nfound++;
806
807 /*
808 * Types of processes we are interested in
809 *
810 * XXX Don't know what to do for WCONTINUED?!?
811 */
812 switch(p->p_stat) {
813 case SZOMB: /* Exited */
814 if (!(uap->options & WEXITED))
815 break;
816
817 /* Collect "siginfo" information for caller */
818 collect64.si_signo = 0;
819 collect64.si_code = 0;
820 collect64.si_errno = 0;
821 collect64.si_pid = 0;
822 collect64.si_uid = 0;
823 collect64.si_addr = 0;
824 collect64.si_status = p->p_xstat;
825 collect64.si_band = 0;
826
827 if (IS_64BIT_PROCESS(p)) {
828 error = copyout((caddr_t)&collect64,
829 uap->infop,
830 sizeof(collect64));
831 } else {
832 siginfo_t collect;
833 siginfo_64to32(&collect64,&collect);
834 error = copyout((caddr_t)&collect,
835 uap->infop,
836 sizeof(collect));
837 }
838 /* information unavailable? */
839 if (error) {
840 p->p_lflag &= ~P_LWAITING;
841 wakeup(&p->p_stat);
842 return (error);
843 }
844
845 /* Prevent other process for waiting for this event? */
846 if (!(uap->options & WNOWAIT)) {
847 /* Clean up */
848 if (!reap_child_process(q, p)) {
849 p->p_lflag &= ~P_LWAITING;
850 wakeup(&p->p_stat);
851 }
852 }
853
854 return (0);
855
856 case SSTOP: /* Stopped */
857 /*
858 * If we are not interested in stopped processes, then
859 * ignore this one.
860 */
861 if (!(uap->options & WSTOPPED))
862 break;
863
864 /*
865 * If someone has already waited it, we lost a race
866 * to be the one to return status.
867 */
868 if ((p->p_flag & P_WAITED) != 0)
869 break;
870
871 /*
872 * If this is not a traced process, and they haven't
873 * indicated an interest in untraced processes, then
874 * ignore this one.
875 */
876 if (!(p->p_flag & P_TRACED) && !(uap->options & WUNTRACED))
877 break;
878
879 /* Collect "siginfo" information for caller */
880 collect64.si_signo = 0;
881 collect64.si_code = 0;
882 collect64.si_errno = 0;
883 collect64.si_pid = 0;
884 collect64.si_uid = 0;
885 collect64.si_addr = 0;
886 collect64.si_status = p->p_xstat;
887 collect64.si_band = 0;
888
889 if (IS_64BIT_PROCESS(p)) {
890 error = copyout((caddr_t)&collect64,
891 uap->infop,
892 sizeof(collect64));
893 } else {
894 siginfo_t collect;
895 siginfo_64to32(&collect64,&collect);
896 error = copyout((caddr_t)&collect,
897 uap->infop,
898 sizeof(collect));
899 }
900 /* information unavailable? */
901 if (error) {
902 p->p_lflag &= ~P_LWAITING;
903 wakeup(&p->p_stat);
904 return (error);
905 }
906
907 /* Prevent other process for waiting for this event? */
908 if (!(uap->options & WNOWAIT)) {
909 p->p_flag |= P_WAITED;
910 }
911
912 p->p_lflag &= ~P_LWAITING;
913 wakeup(&p->p_stat);
914 return (0);
915
916 default: /* All others */
917 /* ...meaning Continued */
918 if (!(uap->options & WCONTINUED))
919 break;
920
921 /*
922 * If the flag isn't set, then this process has not
923 * been stopped and continued, or the status has
924 * already been reaped by another caller of waitid().
925 */
926 if ((p->p_flag & P_CONTINUED) == 0)
927 break;
928
929 /* Collect "siginfo" information for caller */
930 collect64.si_signo = 0;
931 collect64.si_code = 0;
932 collect64.si_errno = 0;
933 collect64.si_pid = 0;
934 collect64.si_uid = 0;
935 collect64.si_addr = 0;
936 collect64.si_status = p->p_xstat;
937 collect64.si_band = 0;
938
939 if (IS_64BIT_PROCESS(p)) {
940 error = copyout((caddr_t)&collect64,
941 uap->infop,
942 sizeof(collect64));
943 } else {
944 siginfo_t collect;
945 siginfo_64to32(&collect64,&collect);
946 error = copyout((caddr_t)&collect,
947 uap->infop,
948 sizeof(collect));
949 }
950 /* information unavailable? */
951 if (error) {
952 p->p_lflag &= ~P_LWAITING;
953 wakeup(&p->p_stat);
954 return (error);
955 }
956
957 /* Prevent other process for waiting for this event? */
958 if (!(uap->options & WNOWAIT)) {
959 p->p_flag &= ~P_CONTINUED;
960 }
961
962 p->p_lflag &= ~P_LWAITING;
963 wakeup(&p->p_stat);
964 return (0);
965
966 break;
967 }
968
969
970 /* Not a process we are interested in; go on to next child */
971 p->p_lflag &= ~P_LWAITING;
972 wakeup(&p->p_stat);
973 }
974
975 /* No child processes that could possibly satisfy the request? */
976 if (nfound == 0)
977 return (ECHILD);
978
979 if (uap->options & WNOHANG) {
980 retval[0] = 0;
981 return (0);
982 }
983
984 if ((error = tsleep0((caddr_t)q, PWAIT | PCATCH, "waitid", 0, waitidcontinue)))
985 return (error);
986
987 goto loop;
988 }
989
990 /*
991 * make process 'parent' the new parent of process 'child'.
992 */
993 void
994 proc_reparent(struct proc *child, struct proc *parent)
995 {
996
997 if (child->p_pptr == parent)
998 return;
999
1000 LIST_REMOVE(child, p_sibling);
1001 LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
1002 child->p_pptr = parent;
1003
1004 if (initproc == parent && child->p_stat == SZOMB)
1005 psignal(initproc, SIGCHLD);
1006 }
1007
1008 /*
1009 * Make the current process an "init" process, meaning
1010 * that it doesn't have a parent, and that it won't be
1011 * gunned down by kill(-1, 0).
1012 */
1013 kern_return_t
1014 init_process(__unused struct init_process_args *args)
1015 {
1016 register struct proc *p = current_proc();
1017
1018 AUDIT_MACH_SYSCALL_ENTER(AUE_INITPROCESS);
1019 if (suser(kauth_cred_get(), &p->p_acflag)) {
1020 AUDIT_MACH_SYSCALL_EXIT(KERN_NO_ACCESS);
1021 return(KERN_NO_ACCESS);
1022 }
1023
1024 if (p->p_pid != 1 && p->p_pgid != p->p_pid)
1025 enterpgrp(p, p->p_pid, 0);
1026 p->p_flag |= P_SYSTEM;
1027
1028 /*
1029 * Take us out of the sibling chain, and
1030 * out of our parent's child chain.
1031 */
1032 LIST_REMOVE(p, p_sibling);
1033 p->p_sibling.le_prev = NULL;
1034 p->p_sibling.le_next = NULL;
1035 p->p_pptr = kernproc;
1036
1037 AUDIT_MACH_SYSCALL_EXIT(KERN_SUCCESS);
1038 return(KERN_SUCCESS);
1039 }
1040
1041
1042 /*
1043 * Exit: deallocate address space and other resources, change proc state
1044 * to zombie, and unlink proc from allproc and parent's lists. Save exit
1045 * status and rusage for wait(). Check for child processes and orphan them.
1046 */
1047
1048 void
1049 vfork_exit(struct proc *p, int rv)
1050 {
1051 thread_t self = current_thread();
1052 #ifdef FIXME
1053 struct task *task = p->task;
1054 #endif
1055 register int s;
1056 struct uthread *ut;
1057 exception_data_t code[EXCEPTION_CODE_MAX];
1058
1059 /*
1060 * If a thread in this task has already
1061 * called exit(), then halt any others
1062 * right here.
1063 */
1064
1065 ut = get_bsdthread_info(self);
1066 #ifdef FIXME
1067 signal_lock(p);
1068 while (p->exit_thread != self) {
1069 if (sig_try_locked(p) <= 0) {
1070 if (get_threadtask(self) != task) {
1071 signal_unlock(p);
1072 return;
1073 }
1074 signal_unlock(p);
1075 thread_terminate(self);
1076 thread_funnel_set(kernel_flock, FALSE);
1077 thread_exception_return();
1078 /* NOTREACHED */
1079 }
1080 sig_lock_to_exit(p);
1081 }
1082 signal_unlock(p);
1083 if (p->p_pid == 1) {
1084 printf("pid 1 exited (signal %d, exit %d)",
1085 WTERMSIG(rv), WEXITSTATUS(rv));
1086 panic("init died\nState at Last Exception:\n\n%s", init_task_failure_data);
1087 }
1088 #endif /* FIXME */
1089
1090 s = splsched();
1091 p->p_flag |= P_WEXIT;
1092 p->p_lflag |= P_LPEXIT;
1093 splx(s);
1094
1095 code[0] = (exception_data_t)0xFF000001; /* Set terminate code */
1096 code[1] = (exception_data_t)p->p_pid; /* Pass out the pid */
1097 /* Notify the perf server */
1098 (void)sys_perf_notify(p->task, (exception_data_t)&code, 2);
1099
1100 /*
1101 * Remove proc from allproc queue and from pidhash chain.
1102 * Need to do this before we do anything that can block.
1103 * Not doing causes things like mount() find this on allproc
1104 * in partially cleaned state.
1105 */
1106 LIST_REMOVE(p, p_list);
1107 LIST_INSERT_HEAD(&zombproc, p, p_list); /* Place onto zombproc. */
1108 LIST_REMOVE(p, p_hash);
1109 /*
1110 * If parent is waiting for us to exit or exec,
1111 * P_PPWAIT is set; we will wakeup the parent below.
1112 */
1113 p->p_flag &= ~(P_TRACED | P_PPWAIT);
1114 p->p_sigignore = ~0;
1115 p->p_siglist = 0;
1116
1117 ut->uu_siglist = 0;
1118 untimeout(realitexpire, (caddr_t)p->p_pid);
1119
1120 p->p_xstat = rv;
1121
1122 vproc_exit(p);
1123 }
1124
1125 void
1126 vproc_exit(struct proc *p)
1127 {
1128 register struct proc *q, *nq, *pp;
1129 #ifdef FIXME
1130 struct task *task = p->task;
1131 #endif
1132
1133 /* XXX Zombie allocation may fail, in which case stats get lost */
1134 MALLOC_ZONE(p->p_ru, struct rusage *,
1135 sizeof (*p->p_ru), M_ZOMBIE, M_WAITOK);
1136
1137 /*
1138 * Close open files and release open-file table.
1139 * This may block!
1140 */
1141 fdfree(p);
1142
1143 if (SESS_LEADER(p)) {
1144 register struct session *sp = p->p_session;
1145
1146 if (sp->s_ttyvp) {
1147 struct vnode *ttyvp;
1148 struct vfs_context context;
1149
1150 /*
1151 * Controlling process.
1152 * Signal foreground pgrp,
1153 * drain controlling terminal
1154 * and revoke access to controlling terminal.
1155 */
1156 if (sp->s_ttyp->t_session == sp) {
1157 if (sp->s_ttyp->t_pgrp)
1158 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
1159 (void) ttywait(sp->s_ttyp);
1160 /*
1161 * The tty could have been revoked
1162 * if we blocked.
1163 */
1164 context.vc_proc = p;
1165 context.vc_ucred = kauth_cred_proc_ref(p);
1166 if (sp->s_ttyvp)
1167 VNOP_REVOKE(sp->s_ttyvp, REVOKEALL, &context);
1168 kauth_cred_unref(&context.vc_ucred);
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 }