2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */
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.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
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.
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
60 * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
63 #include <machine/reg.h>
64 #include <machine/psl.h>
66 #include "compat_43.h"
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>
75 #include <sys/resource.h>
76 #include <sys/kernel.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>
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>
93 #include <bsm/audit_kernel.h>
94 #include <bsm/audit_kevents.h>
96 #include <mach/mach_types.h>
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>
105 #include <sys/ktrace.h>
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 */
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
);
121 * Things which should have prototypes in headers, but don't
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
);
133 * NOTE: Source and target may *NOT* overlap!
134 * XXX Should share code with bsd/dev/ppc/unix_signal.c
137 siginfo_64to32(user_siginfo_t
*in
, siginfo_t
*out
)
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 */
157 exit(struct proc
*p
, struct exit_args
*uap
, int *retval
)
159 exit1(p
, W_EXITCODE(uap
->rval
, 0), retval
);
161 /* drop funnel before we return */
162 thread_funnel_set(kernel_flock
, FALSE
);
163 thread_exception_return();
166 thread_block(THREAD_CONTINUE_NULL
);
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.
176 exit1(struct proc
*p
, int rv
, int *retval
)
178 thread_t self
= current_thread();
179 struct task
*task
= p
->task
;
184 * If a thread in this task has already
185 * called exit(), then halt any others
189 ut
= get_bsdthread_info(self
);
190 if (ut
->uu_flag
& UT_VFORK
) {
192 vfork_return(self
, p
->p_pptr
, p
, retval
);
193 unix_syscall_return(0);
196 AUDIT_SYSCALL_EXIT(0, p
, ut
); /* Exit is always successfull */
198 while (p
->exit_thread
!= self
) {
199 if (sig_try_locked(p
) <= 0) {
200 if (get_threadtask(self
) != task
) {
205 thread_terminate(self
);
206 thread_funnel_set(kernel_flock
, FALSE
);
207 thread_exception_return();
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
);
221 p
->p_flag
|= P_WEXIT
;
226 /* task terminate will call proc_terminate and that cleans it up */
227 task_terminate_internal(task
);
233 proc_prepareexit(struct proc
*p
)
236 exception_data_t code
[EXCEPTION_CODE_MAX
];
237 thread_t self
= current_thread();
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);
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.
250 LIST_REMOVE(p
, p_list
);
251 LIST_INSERT_HEAD(&zombproc
, p
, p_list
); /* Place onto zombproc. */
252 LIST_REMOVE(p
, p_hash
);
258 * If parent is waiting for us to exit or exec,
259 * P_PPWAIT is set; we will wakeup the parent below.
261 p
->p_flag
&= ~(P_TRACED
| P_PPWAIT
);
262 p
->p_sigignore
= ~(sigcantmask
);
264 ut
= get_bsdthread_info(self
);
266 untimeout(realitexpire
, (caddr_t
)p
->p_pid
);
270 proc_exit(struct proc
*p
)
272 register struct proc
*q
, *nq
, *pp
;
273 struct task
*task
= p
->task
;
275 boolean_t funnel_state
;
277 /* This can happen if thread_terminate of the single thread
281 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
282 if( !(p
->p_flag
& P_WEXIT
)) {
284 p
->p_flag
|= P_WEXIT
;
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
);
295 * need to cancel async IO requests that can be cancelled and wait for those
296 * already active. MAY BLOCK!
301 * Close open files and release open-file table.
306 /* Close ref SYSV Shared memory*/
309 /* Release SYSV semaphores */
312 if (SESS_LEADER(p
)) {
313 register struct session
*sp
= p
->p_session
;
317 struct vfs_context context
;
320 * Controlling process.
321 * Signal foreground pgrp,
322 * drain controlling terminal
323 * and revoke access to controlling terminal.
325 if (sp
->s_ttyp
->t_session
== sp
) {
326 if (sp
->s_ttyp
->t_pgrp
)
327 pgsignal(sp
->s_ttyp
->t_pgrp
, SIGHUP
, 1);
328 (void) ttywait(sp
->s_ttyp
);
330 * The tty could have been revoked
334 context
.vc_ucred
= p
->p_ucred
;
336 VNOP_REVOKE(sp
->s_ttyvp
, REVOKEALL
, &context
);
344 * s_ttyp is not zero'd; we use this to indicate
345 * that the session once had a controlling terminal.
346 * (for logging and informational purposes)
352 fixjobc(p
, p
->p_pgrp
, 0);
353 p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur
= RLIM_INFINITY
;
354 (void)acct_process(p
);
360 p
->p_traceflag
= 0; /* don't trace the vnode_put() */
362 struct vnode
*tvp
= p
->p_tracep
;
368 while (q
= p
->p_children
.lh_first
) {
369 proc_reparent(q
, initproc
);
371 * Traced processes are killed
372 * since their existence means someone is messing up.
374 if (q
->p_flag
& P_TRACED
) {
375 q
->p_flag
&= ~P_TRACED
;
376 if (q
->sigwait_thread
) {
378 * The sigwait_thread could be stopped at a
379 * breakpoint. Wake it up to kill.
380 * Need to do this as it could be a thread which is not
381 * the first thread in the task. So any attempts to kill
382 * the process would result into a deadlock on q->sigwait.
384 thread_resume((thread_t
)q
->sigwait_thread
);
385 clear_wait(q
->sigwait_thread
, THREAD_INTERRUPTED
);
386 threadsignal((thread_t
)q
->sigwait_thread
, SIGKILL
, 0);
393 * Save exit status and final rusage info, adding in child rusage
394 * info and self times. If we were unable to allocate a zombie
395 * structure, this information is lost.
397 if (p
->p_ru
!= NULL
) {
398 *p
->p_ru
= p
->p_stats
->p_ru
;
400 timerclear(&p
->p_ru
->ru_utime
);
401 timerclear(&p
->p_ru
->ru_stime
);
404 task_basic_info_data_t tinfo
;
405 task_thread_times_info_data_t ttimesinfo
;
406 int task_info_stuff
, task_ttimes_stuff
;
407 struct timeval ut
,st
;
409 task_info_stuff
= TASK_BASIC_INFO_COUNT
;
410 task_info(task
, TASK_BASIC_INFO
,
411 (task_info_t
)&tinfo
, &task_info_stuff
);
412 p
->p_ru
->ru_utime
.tv_sec
= tinfo
.user_time
.seconds
;
413 p
->p_ru
->ru_utime
.tv_usec
= tinfo
.user_time
.microseconds
;
414 p
->p_ru
->ru_stime
.tv_sec
= tinfo
.system_time
.seconds
;
415 p
->p_ru
->ru_stime
.tv_usec
= tinfo
.system_time
.microseconds
;
417 task_ttimes_stuff
= TASK_THREAD_TIMES_INFO_COUNT
;
418 task_info(task
, TASK_THREAD_TIMES_INFO
,
419 (task_info_t
)&ttimesinfo
, &task_ttimes_stuff
);
421 ut
.tv_sec
= ttimesinfo
.user_time
.seconds
;
422 ut
.tv_usec
= ttimesinfo
.user_time
.microseconds
;
423 st
.tv_sec
= ttimesinfo
.system_time
.seconds
;
424 st
.tv_usec
= ttimesinfo
.system_time
.microseconds
;
425 timeradd(&ut
,&p
->p_ru
->ru_utime
,&p
->p_ru
->ru_utime
);
426 timeradd(&st
,&p
->p_ru
->ru_stime
,&p
->p_ru
->ru_stime
);
429 ruadd(p
->p_ru
, &p
->p_stats
->p_cru
);
433 * Free up profiling buffers.
436 struct uprof
*p0
= &p
->p_stats
->p_prof
, *p1
, *pn
;
442 for (; p1
!= NULL
; p1
= pn
) {
444 kfree(p1
, sizeof *p1
);
449 * Other substructures are freed from wait().
451 FREE_ZONE(p
->p_stats
, sizeof *p
->p_stats
, M_SUBPROC
);
454 FREE_ZONE(p
->p_sigacts
, sizeof *p
->p_sigacts
, M_SUBPROC
);
457 if (--p
->p_limit
->p_refcnt
== 0)
458 FREE_ZONE(p
->p_limit
, sizeof *p
->p_limit
, M_SUBPROC
);
462 * Finish up by terminating the task
463 * and halt this thread (only if a
464 * member of the task exiting).
468 set_bsdtask_info(task
, NULL
);
470 KNOTE(&p
->p_klist
, NOTE_EXIT
);
473 * Notify parent that we're gone.
475 if (p
->p_pptr
->p_flag
& P_NOCLDWAIT
) {
476 struct proc
*opp
= p
->p_pptr
;
479 * Add child resource usage to parent before giving
480 * zombie to init. If we were unable to allocate a
481 * zombie structure, this information is lost.
484 ruadd(&p
->p_pptr
->p_stats
->p_cru
, p
->p_ru
);
486 proc_reparent(p
, initproc
);
487 /* If there are no more children wakeup parent */
488 if (LIST_EMPTY(&opp
->p_children
))
489 wakeup((caddr_t
)opp
);
491 /* should be fine as parent proc would be initproc */
493 if (pp
!= initproc
) {
494 pp
->si_pid
= p
->p_pid
;
495 pp
->si_status
= p
->p_xstat
;
496 pp
->si_code
= CLD_EXITED
;
497 pp
->si_uid
= p
->p_ucred
->cr_ruid
;
499 /* mark as a zombie */
502 psignal(pp
, SIGCHLD
);
504 /* and now wakeup the parent */
505 wakeup((caddr_t
)p
->p_pptr
);
507 (void) thread_funnel_set(kernel_flock
, funnel_state
);
514 * Description: Given a process from which all status information needed
515 * has already been extracted, if the process is a ptrace
516 * attach process, detach it and give it back to its real
517 * parent, else recover all resources remaining associated
520 * Parameters: struct proc *parent Parent of process being reaped
521 * struct proc *child Process to reap
523 * Returns: 0 Process was not reaped because it
524 * came from an attach
525 * 1 Process was reaped
528 reap_child_process(struct proc
*parent
, struct proc
*child
)
530 struct proc
*trace_parent
; /* Traced parent process, if tracing */
531 struct vnode
*tvp
; /* Traced vnode pointer, if used */
534 * If we got the child via a ptrace 'attach',
535 * we need to give it back to the old parent.
537 if (child
->p_oppid
&& (trace_parent
= pfind(child
->p_oppid
))) {
539 proc_reparent(child
, trace_parent
);
540 if (trace_parent
!= initproc
) {
541 trace_parent
->si_pid
= child
->p_pid
;
542 trace_parent
->si_status
= child
->p_xstat
;
543 trace_parent
->si_code
= CLD_CONTINUED
;
544 trace_parent
->si_uid
= child
->p_ucred
->cr_ruid
;
546 psignal(trace_parent
, SIGCHLD
);
547 wakeup((caddr_t
)trace_parent
);
552 ruadd(&parent
->p_stats
->p_cru
, child
->p_ru
);
553 FREE_ZONE(child
->p_ru
, sizeof *child
->p_ru
, M_ZOMBIE
);
556 printf("Warning : lost p_ru for %s\n", child
->p_comm
);
560 * Decrement the count of procs running with this uid.
562 (void)chgproccnt(child
->p_ucred
->cr_ruid
, -1);
565 * Free up credentials.
567 if (child
->p_ucred
!= NOCRED
) {
568 kauth_cred_t ucr
= child
->p_ucred
;
569 child
->p_ucred
= NOCRED
;
570 kauth_cred_rele(ucr
);
574 * Release reference to text vnode
576 tvp
= child
->p_textvp
;
577 child
->p_textvp
= NULL
;
582 * Finally finished with old proc entry.
583 * Unlink it from its process group and free it.
586 LIST_REMOVE(child
, p_list
); /* off zombproc */
587 LIST_REMOVE(child
, p_sibling
);
588 child
->p_flag
&= ~P_WAITING
;
590 lck_mtx_destroy(&child
->p_mlock
, proc_lck_grp
);
591 lck_mtx_destroy(&child
->p_fdmlock
, proc_lck_grp
);
592 FREE_ZONE(child
, sizeof *child
, M_PROC
);
599 wait1continue(int result
)
610 thread
= current_thread();
611 vt
= get_bsduthreadarg(thread
);
612 retval
= get_bsduthreadrval(thread
);
613 return(wait4((struct proc
*)p
, (struct wait4_args
*)vt
, retval
));
617 wait4(struct proc
*q
, struct wait4_args
*uap
, register_t
*retval
)
620 register struct proc
*p
;
624 uap
->pid
= -q
->p_pgid
;
628 for (p
= q
->p_children
.lh_first
; p
!= 0; p
= p
->p_sibling
.le_next
) {
629 if (uap
->pid
!= WAIT_ANY
&&
630 p
->p_pid
!= uap
->pid
&&
631 p
->p_pgid
!= -(uap
->pid
))
635 /* XXX This is racy because we don't get the lock!!!! */
637 if (p
->p_flag
& P_WAITING
) {
638 (void)tsleep(&p
->p_stat
, PWAIT
, "waitcoll", 0);
641 p
->p_flag
|= P_WAITING
; /* only allow single thread to wait() */
643 if (p
->p_stat
== SZOMB
) {
644 retval
[0] = p
->p_pid
;
646 status
= p
->p_xstat
; /* convert to int */
647 error
= copyout((caddr_t
)&status
,
651 p
->p_flag
&= ~P_WAITING
;
657 if (p
->p_ru
== NULL
) {
660 if (IS_64BIT_PROCESS(q
)) {
661 struct user_rusage my_rusage
;
662 munge_rusage(p
->p_ru
, &my_rusage
);
663 error
= copyout((caddr_t
)&my_rusage
,
668 error
= copyout((caddr_t
)p
->p_ru
,
670 sizeof (struct rusage
));
673 /* information unavailable? */
675 p
->p_flag
&= ~P_WAITING
;
682 if (!reap_child_process(q
, p
))
683 p
->p_flag
&= ~P_WAITING
;
685 /* Wake other wait'ers, if any */
690 if (p
->p_stat
== SSTOP
&& (p
->p_flag
& P_WAITED
) == 0 &&
691 (p
->p_flag
& P_TRACED
|| uap
->options
& WUNTRACED
)) {
692 p
->p_flag
|= P_WAITED
;
693 retval
[0] = p
->p_pid
;
695 status
= W_STOPCODE(p
->p_xstat
);
696 error
= copyout((caddr_t
)&status
,
701 p
->p_flag
&= ~P_WAITING
;
705 p
->p_flag
&= ~P_WAITING
;
711 if (uap
->options
& WNOHANG
) {
716 if ((error
= tsleep0((caddr_t
)q
, PWAIT
| PCATCH
, "wait", 0, wait1continue
)))
724 waitidcontinue(int result
)
735 thread
= current_thread();
736 vt
= get_bsduthreadarg(thread
);
737 retval
= get_bsduthreadrval(thread
);
738 return(waitid((struct proc
*)p
, (struct waitid_args
*)vt
, retval
));
742 * Description: Suspend the calling thread until one child of the process
743 * containing the calling thread changes state.
745 * Parameters: uap->idtype one of P_PID, P_PGID, P_ALL
746 * uap->id pid_t or gid_t or ignored
747 * uap->infop Address of signinfo_t struct in
748 * user space into which to return status
749 * uap->options flag values
752 * !0 Error returning status to user space
755 waitid(struct proc
*q
, struct waitid_args
*uap
, register_t
*retval
)
757 user_siginfo_t collect64
; /* siginfo data to return to caller */
760 register struct proc
*p
;
765 for (p
= q
->p_children
.lh_first
; p
!= 0; p
= p
->p_sibling
.le_next
) {
766 switch(uap
->idtype
) {
767 case P_PID
: /* child with process ID equal to... */
768 if (p
->p_pid
!= (pid_t
)uap
->id
)
771 case P_PGID
: /* child with process group ID equal to... */
772 if (p
->p_pgid
!= (pid_t
)uap
->id
)
775 case P_ALL
: /* any child */
779 /* XXX This is racy because we don't get the lock!!!! */
782 * Wait collision; go to sleep and restart; used to maintain
783 * the single return for waited process guarantee.
785 if (p
->p_flag
& P_WAITING
) {
786 (void)tsleep(&p
->p_stat
, PWAIT
, "waitidcoll", 0);
789 p
->p_flag
|= P_WAITING
; /* mark busy */
794 * Types of processes we are interested in
796 * XXX Don't know what to do for WCONTINUED?!?
799 case SZOMB
: /* Exited */
800 if (!(uap
->options
& WEXITED
))
803 /* Collect "siginfo" information for caller */
804 collect64
.si_signo
= 0;
805 collect64
.si_code
= 0;
806 collect64
.si_errno
= 0;
807 collect64
.si_pid
= 0;
808 collect64
.si_uid
= 0;
809 collect64
.si_addr
= 0;
810 collect64
.si_status
= p
->p_xstat
;
811 collect64
.si_band
= 0;
813 if (IS_64BIT_PROCESS(p
)) {
814 error
= copyout((caddr_t
)&collect64
,
819 siginfo_64to32(&collect64
,&collect
);
820 error
= copyout((caddr_t
)&collect
,
824 /* information unavailable? */
826 p
->p_flag
&= ~P_WAITING
;
831 /* Prevent other process for waiting for this event? */
832 if (!(uap
->options
& WNOWAIT
)) {
834 if (!reap_child_process(q
, p
))
835 p
->p_flag
&= ~P_WAITING
;
837 /* Wake other wait'ers, if any */
843 case SSTOP
: /* Stopped */
845 * If we are not interested in stopped processes, then
848 if (!(uap
->options
& WSTOPPED
))
852 * If someone has already waited it, we lost a race
853 * to be the one to return status.
855 if ((p
->p_flag
& P_WAITED
) != 0)
859 * If this is not a traced process, and they haven't
860 * indicated an interest in untraced processes, then
863 if (!(p
->p_flag
& P_TRACED
) && !(uap
->options
& WUNTRACED
))
866 /* Collect "siginfo" information for caller */
867 collect64
.si_signo
= 0;
868 collect64
.si_code
= 0;
869 collect64
.si_errno
= 0;
870 collect64
.si_pid
= 0;
871 collect64
.si_uid
= 0;
872 collect64
.si_addr
= 0;
873 collect64
.si_status
= p
->p_xstat
;
874 collect64
.si_band
= 0;
876 if (IS_64BIT_PROCESS(p
)) {
877 error
= copyout((caddr_t
)&collect64
,
882 siginfo_64to32(&collect64
,&collect
);
883 error
= copyout((caddr_t
)&collect
,
887 /* information unavailable? */
889 p
->p_flag
&= ~P_WAITING
;
894 /* Prevent other process for waiting for this event? */
895 if (!(uap
->options
& WNOWAIT
)) {
896 p
->p_flag
|= P_WAITED
;
899 p
->p_flag
&= ~P_WAITING
;
903 default: /* All others */
904 /* ...meaning Continued */
905 if (!(uap
->options
& WCONTINUED
))
909 * If the flag isn't set, then this process has not
910 * been stopped and continued, or the status has
911 * already been reaped by another caller of waitid().
913 if ((p
->p_flag
& P_CONTINUED
) == 0)
916 /* Collect "siginfo" information for caller */
917 collect64
.si_signo
= 0;
918 collect64
.si_code
= 0;
919 collect64
.si_errno
= 0;
920 collect64
.si_pid
= 0;
921 collect64
.si_uid
= 0;
922 collect64
.si_addr
= 0;
923 collect64
.si_status
= p
->p_xstat
;
924 collect64
.si_band
= 0;
926 if (IS_64BIT_PROCESS(p
)) {
927 error
= copyout((caddr_t
)&collect64
,
932 siginfo_64to32(&collect64
,&collect
);
933 error
= copyout((caddr_t
)&collect
,
937 /* information unavailable? */
939 p
->p_flag
&= ~P_WAITING
;
944 /* Prevent other process for waiting for this event? */
945 if (!(uap
->options
& WNOWAIT
)) {
946 p
->p_flag
&= ~P_CONTINUED
;
949 p
->p_flag
&= ~P_WAITING
;
957 /* Not a process we are interested in; go on to next child */
958 p
->p_flag
&= ~P_WAITING
;
962 /* No child processes that could possibly satisfy the request? */
966 if (uap
->options
& WNOHANG
) {
971 if ((error
= tsleep0((caddr_t
)q
, PWAIT
| PCATCH
, "waitid", 0, waitidcontinue
)))
978 * make process 'parent' the new parent of process 'child'.
981 proc_reparent(struct proc
*child
, struct proc
*parent
)
984 if (child
->p_pptr
== parent
)
987 LIST_REMOVE(child
, p_sibling
);
988 LIST_INSERT_HEAD(&parent
->p_children
, child
, p_sibling
);
989 child
->p_pptr
= parent
;
991 if (initproc
== parent
&& child
->p_stat
== SZOMB
)
992 psignal(initproc
, SIGCHLD
);
996 * Make the current process an "init" process, meaning
997 * that it doesn't have a parent, and that it won't be
998 * gunned down by kill(-1, 0).
1001 init_process(__unused
struct init_process_args
*args
)
1003 register struct proc
*p
= current_proc();
1005 AUDIT_MACH_SYSCALL_ENTER(AUE_INITPROCESS
);
1006 if (suser(kauth_cred_get(), &p
->p_acflag
)) {
1007 AUDIT_MACH_SYSCALL_EXIT(KERN_NO_ACCESS
);
1008 return(KERN_NO_ACCESS
);
1011 if (p
->p_pid
!= 1 && p
->p_pgid
!= p
->p_pid
)
1012 enterpgrp(p
, p
->p_pid
, 0);
1013 p
->p_flag
|= P_SYSTEM
;
1016 * Take us out of the sibling chain, and
1017 * out of our parent's child chain.
1019 LIST_REMOVE(p
, p_sibling
);
1020 p
->p_sibling
.le_prev
= NULL
;
1021 p
->p_sibling
.le_next
= NULL
;
1022 p
->p_pptr
= kernproc
;
1024 AUDIT_MACH_SYSCALL_EXIT(KERN_SUCCESS
);
1025 return(KERN_SUCCESS
);
1030 * Exit: deallocate address space and other resources, change proc state
1031 * to zombie, and unlink proc from allproc and parent's lists. Save exit
1032 * status and rusage for wait(). Check for child processes and orphan them.
1036 vfork_exit(struct proc
*p
, int rv
)
1038 thread_t self
= current_thread();
1040 struct task
*task
= p
->task
;
1044 exception_data_t code
[EXCEPTION_CODE_MAX
];
1047 * If a thread in this task has already
1048 * called exit(), then halt any others
1052 ut
= get_bsdthread_info(self
);
1055 while (p
->exit_thread
!= self
) {
1056 if (sig_try_locked(p
) <= 0) {
1057 if (get_threadtask(self
) != task
) {
1062 thread_terminate(self
);
1063 thread_funnel_set(kernel_flock
, FALSE
);
1064 thread_exception_return();
1067 sig_lock_to_exit(p
);
1070 if (p
->p_pid
== 1) {
1071 printf("pid 1 exited (signal %d, exit %d)",
1072 WTERMSIG(rv
), WEXITSTATUS(rv
));
1073 panic("init died\nState at Last Exception:\n\n%s", init_task_failure_data
);
1078 p
->p_flag
|= P_WEXIT
;
1079 p
->p_lflag
|= P_LPEXIT
;
1082 code
[0] = (exception_data_t
)0xFF000001; /* Set terminate code */
1083 code
[1] = (exception_data_t
)p
->p_pid
; /* Pass out the pid */
1084 /* Notify the perf server */
1085 (void)sys_perf_notify(p
->task
, (exception_data_t
)&code
, 2);
1088 * Remove proc from allproc queue and from pidhash chain.
1089 * Need to do this before we do anything that can block.
1090 * Not doing causes things like mount() find this on allproc
1091 * in partially cleaned state.
1093 LIST_REMOVE(p
, p_list
);
1094 LIST_INSERT_HEAD(&zombproc
, p
, p_list
); /* Place onto zombproc. */
1095 LIST_REMOVE(p
, p_hash
);
1097 * If parent is waiting for us to exit or exec,
1098 * P_PPWAIT is set; we will wakeup the parent below.
1100 p
->p_flag
&= ~(P_TRACED
| P_PPWAIT
);
1101 p
->p_sigignore
= ~0;
1105 untimeout(realitexpire
, (caddr_t
)p
->p_pid
);
1113 vproc_exit(struct proc
*p
)
1115 register struct proc
*q
, *nq
, *pp
;
1117 struct task
*task
= p
->task
;
1120 /* XXX Zombie allocation may fail, in which case stats get lost */
1121 MALLOC_ZONE(p
->p_ru
, struct rusage
*,
1122 sizeof (*p
->p_ru
), M_ZOMBIE
, M_WAITOK
);
1125 * Close open files and release open-file table.
1130 if (SESS_LEADER(p
)) {
1131 register struct session
*sp
= p
->p_session
;
1134 struct vnode
*ttyvp
;
1135 struct vfs_context context
;
1138 * Controlling process.
1139 * Signal foreground pgrp,
1140 * drain controlling terminal
1141 * and revoke access to controlling terminal.
1143 if (sp
->s_ttyp
->t_session
== sp
) {
1144 if (sp
->s_ttyp
->t_pgrp
)
1145 pgsignal(sp
->s_ttyp
->t_pgrp
, SIGHUP
, 1);
1146 (void) ttywait(sp
->s_ttyp
);
1148 * The tty could have been revoked
1151 context
.vc_proc
= p
;
1152 context
.vc_ucred
= p
->p_ucred
;
1154 VNOP_REVOKE(sp
->s_ttyvp
, REVOKEALL
, &context
);
1156 ttyvp
= sp
->s_ttyvp
;
1162 * s_ttyp is not zero'd; we use this to indicate
1163 * that the session once had a controlling terminal.
1164 * (for logging and informational purposes)
1167 sp
->s_leader
= NULL
;
1170 fixjobc(p
, p
->p_pgrp
, 0);
1171 p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur
= RLIM_INFINITY
;
1175 * release trace file
1177 p
->p_traceflag
= 0; /* don't trace the vnode_rele() */
1179 struct vnode
*tvp
= p
->p_tracep
;
1185 while (q
= p
->p_children
.lh_first
) {
1186 proc_reparent(q
, initproc
);
1188 * Traced processes are killed
1189 * since their existence means someone is messing up.
1191 if (q
->p_flag
& P_TRACED
) {
1192 q
->p_flag
&= ~P_TRACED
;
1193 if (q
->sigwait_thread
) {
1195 * The sigwait_thread could be stopped at a
1196 * breakpoint. Wake it up to kill.
1197 * Need to do this as it could be a thread which is not
1198 * the first thread in the task. So any attempts to kill
1199 * the process would result into a deadlock on q->sigwait.
1201 thread_resume((thread_t
)q
->sigwait_thread
);
1202 clear_wait(q
->sigwait_thread
, THREAD_INTERRUPTED
);
1203 threadsignal((thread_t
)q
->sigwait_thread
, SIGKILL
, 0);
1205 psignal(q
, SIGKILL
);
1210 * Save exit status and final rusage info, adding in child rusage
1211 * info and self times. If we were unable to allocate a zombie
1212 * structure, this information is lost.
1214 if (p
->p_ru
!= NULL
) {
1215 *p
->p_ru
= p
->p_stats
->p_ru
;
1216 timerclear(&p
->p_ru
->ru_utime
);
1217 timerclear(&p
->p_ru
->ru_stime
);
1221 task_basic_info_data_t tinfo
;
1222 task_thread_times_info_data_t ttimesinfo
;
1223 int task_info_stuff
, task_ttimes_stuff
;
1224 struct timeval ut
,st
;
1226 task_info_stuff
= TASK_BASIC_INFO_COUNT
;
1227 task_info(task
, TASK_BASIC_INFO
,
1228 &tinfo
, &task_info_stuff
);
1229 p
->p_ru
->ru_utime
.tv_sec
= tinfo
.user_time
.seconds
;
1230 p
->p_ru
->ru_utime
.tv_usec
= tinfo
.user_time
.microseconds
;
1231 p
->p_ru
->ru_stime
.tv_sec
= tinfo
.system_time
.seconds
;
1232 p
->p_ru
->ru_stime
.tv_usec
= tinfo
.system_time
.microseconds
;
1234 task_ttimes_stuff
= TASK_THREAD_TIMES_INFO_COUNT
;
1235 task_info(task
, TASK_THREAD_TIMES_INFO
,
1236 &ttimesinfo
, &task_ttimes_stuff
);
1238 ut
.tv_sec
= ttimesinfo
.user_time
.seconds
;
1239 ut
.tv_usec
= ttimesinfo
.user_time
.microseconds
;
1240 st
.tv_sec
= ttimesinfo
.system_time
.seconds
;
1241 st
.tv_usec
= ttimesinfo
.system_time
.microseconds
;
1242 timeradd(&ut
,&p
->p_ru
->ru_utime
,&p
->p_ru
->ru_utime
);
1243 timeradd(&st
,&p
->p_ru
->ru_stime
,&p
->p_ru
->ru_stime
);
1247 ruadd(p
->p_ru
, &p
->p_stats
->p_cru
);
1251 * Free up profiling buffers.
1254 struct uprof
*p0
= &p
->p_stats
->p_prof
, *p1
, *pn
;
1260 for (; p1
!= NULL
; p1
= pn
) {
1262 kfree(p1
, sizeof *p1
);
1267 * Other substructures are freed from wait().
1269 FREE_ZONE(p
->p_stats
, sizeof *p
->p_stats
, M_SUBPROC
);
1272 FREE_ZONE(p
->p_sigacts
, sizeof *p
->p_sigacts
, M_SUBPROC
);
1273 p
->p_sigacts
= NULL
;
1275 if (--p
->p_limit
->p_refcnt
== 0)
1276 FREE_ZONE(p
->p_limit
, sizeof *p
->p_limit
, M_SUBPROC
);
1280 * Finish up by terminating the task
1281 * and halt this thread (only if a
1282 * member of the task exiting).
1284 p
->task
= TASK_NULL
;
1287 * Notify parent that we're gone.
1290 if (pp
!= initproc
) {
1291 pp
->si_pid
= p
->p_pid
;
1292 pp
->si_status
= p
->p_xstat
;
1293 pp
->si_code
= CLD_EXITED
;
1294 pp
->si_uid
= p
->p_ucred
->cr_ruid
;
1296 /* mark as a zombie */
1299 psignal(p
->p_pptr
, SIGCHLD
);
1301 /* and now wakeup the parent */
1302 wakeup((caddr_t
)p
->p_pptr
);
1308 * LP64 support - long is 64 bits if we are dealing with a 64 bit user
1309 * process. We munge the kernel (32 bit) version of rusage into the
1312 __private_extern__
void
1313 munge_rusage(struct rusage
*a_rusage_p
, struct user_rusage
*a_user_rusage_p
)
1315 /* timeval changes size, so utime and stime need special handling */
1316 a_user_rusage_p
->ru_utime
.tv_sec
= a_rusage_p
->ru_utime
.tv_sec
;
1317 a_user_rusage_p
->ru_utime
.tv_usec
= a_rusage_p
->ru_utime
.tv_usec
;
1318 a_user_rusage_p
->ru_stime
.tv_sec
= a_rusage_p
->ru_stime
.tv_sec
;
1319 a_user_rusage_p
->ru_stime
.tv_usec
= a_rusage_p
->ru_stime
.tv_usec
;
1321 * everything else can be a direct assign, since there is no loss
1322 * of precision implied boing 32->64.
1324 a_user_rusage_p
->ru_maxrss
= a_rusage_p
->ru_maxrss
;
1325 a_user_rusage_p
->ru_ixrss
= a_rusage_p
->ru_ixrss
;
1326 a_user_rusage_p
->ru_idrss
= a_rusage_p
->ru_idrss
;
1327 a_user_rusage_p
->ru_isrss
= a_rusage_p
->ru_isrss
;
1328 a_user_rusage_p
->ru_minflt
= a_rusage_p
->ru_minflt
;
1329 a_user_rusage_p
->ru_majflt
= a_rusage_p
->ru_majflt
;
1330 a_user_rusage_p
->ru_nswap
= a_rusage_p
->ru_nswap
;
1331 a_user_rusage_p
->ru_inblock
= a_rusage_p
->ru_inblock
;
1332 a_user_rusage_p
->ru_oublock
= a_rusage_p
->ru_oublock
;
1333 a_user_rusage_p
->ru_msgsnd
= a_rusage_p
->ru_msgsnd
;
1334 a_user_rusage_p
->ru_msgrcv
= a_rusage_p
->ru_msgrcv
;
1335 a_user_rusage_p
->ru_nsignals
= a_rusage_p
->ru_nsignals
;
1336 a_user_rusage_p
->ru_nvcsw
= a_rusage_p
->ru_nvcsw
;
1337 a_user_rusage_p
->ru_nivcsw
= a_rusage_p
->ru_nivcsw
;