]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_exit.c
xnu-1504.9.17.tar.gz
[apple/xnu.git] / bsd / kern / kern_exit.c
CommitLineData
1c79356b 1/*
2d21ac55 2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
5d5c5d0d 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
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.
8f6c56a5 14 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
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 */
2d21ac55
A
68/*
69 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
70 * support for mandatory and extensible security protections. This notice
71 * is included in support of clause 2.2 (b) of the Apple Public License,
72 * Version 2.0.
73 */
1c79356b
A
74
75#include <machine/reg.h>
76#include <machine/psl.h>
77
78#include "compat_43.h"
79
80#include <sys/param.h>
81#include <sys/systm.h>
82#include <sys/ioctl.h>
91447636 83#include <sys/proc_internal.h>
2d21ac55 84#include <sys/proc.h>
91447636 85#include <sys/kauth.h>
1c79356b
A
86#include <sys/tty.h>
87#include <sys/time.h>
88#include <sys/resource.h>
89#include <sys/kernel.h>
1c79356b 90#include <sys/wait.h>
91447636
A
91#include <sys/file_internal.h>
92#include <sys/vnode_internal.h>
1c79356b
A
93#include <sys/syslog.h>
94#include <sys/malloc.h>
95#include <sys/resourcevar.h>
96#include <sys/ptrace.h>
97#include <sys/user.h>
55e303ae 98#include <sys/aio_kern.h>
91447636
A
99#include <sys/sysproto.h>
100#include <sys/signalvar.h>
b0d623f7 101#include <sys/kdebug.h>
91447636 102#include <sys/filedesc.h> /* fdfree */
2d21ac55 103#if SYSV_SHM
91447636 104#include <sys/shm_internal.h> /* shmexit */
2d21ac55 105#endif
91447636 106#include <sys/acct.h> /* acct_process */
e5568f75 107
b0d623f7 108#include <security/audit/audit.h>
e5568f75 109#include <bsm/audit_kevents.h>
1c79356b
A
110
111#include <mach/mach_types.h>
91447636
A
112
113#include <kern/kern_types.h>
114#include <kern/kalloc.h>
115#include <kern/task.h>
1c79356b 116#include <kern/thread.h>
2d21ac55 117#include <kern/thread_call.h>
9bccf70c 118#include <kern/sched_prim.h>
1c79356b 119#include <kern/assert.h>
2d21ac55
A
120#if CONFIG_DTRACE
121/* Do not include dtrace.h, it redefines kmem_[alloc/free] */
122extern void (*dtrace_fasttrap_exit_ptr)(proc_t);
123extern void (*dtrace_helpers_cleanup)(proc_t);
124extern void dtrace_lazy_dofs_destroy(proc_t);
125
126#include <sys/dtrace_ptss.h>
127#endif
128
129#if CONFIG_MACF
130#include <security/mac.h>
131#include <sys/syscall.h>
9bccf70c 132#endif
1c79356b 133
91447636
A
134#include <mach/mach_types.h>
135#include <mach/task.h>
136#include <mach/thread_act.h>
91447636 137
2d21ac55
A
138#include <sys/sdt.h>
139
1c79356b 140extern char init_task_failure_data[];
2d21ac55
A
141void proc_prepareexit(proc_t p, int rv);
142void vfork_exit(proc_t p, int rv);
143void vproc_exit(proc_t p);
b0d623f7
A
144__private_extern__ void munge_user64_rusage(struct rusage *a_rusage_p, struct user64_rusage *a_user_rusage_p);
145__private_extern__ void munge_user32_rusage(struct rusage *a_rusage_p, struct user32_rusage *a_user_rusage_p);
2d21ac55 146static int reap_child_locked(proc_t parent, proc_t child, int deadparent, int locked, int droplock);
91447636
A
147
148/*
149 * Things which should have prototypes in headers, but don't
150 */
91447636 151void *get_bsduthreadarg(thread_t);
2d21ac55 152void proc_exit(proc_t p);
91447636
A
153int wait1continue(int result);
154int waitidcontinue(int result);
155int *get_bsduthreadrval(thread_t);
2d21ac55
A
156kern_return_t sys_perf_notify(thread_t thread, int pid);
157kern_return_t abnormal_exit_notify(mach_exception_data_type_t code,
158 mach_exception_data_type_t subcode);
2d21ac55
A
159void workqueue_exit(struct proc *);
160void delay(int);
161
91447636
A
162/*
163 * NOTE: Source and target may *NOT* overlap!
164 * XXX Should share code with bsd/dev/ppc/unix_signal.c
165 */
166static void
b0d623f7 167siginfo_user_to_user32(user_siginfo_t *in, user32_siginfo_t *out)
91447636
A
168{
169 out->si_signo = in->si_signo;
170 out->si_errno = in->si_errno;
171 out->si_code = in->si_code;
172 out->si_pid = in->si_pid;
173 out->si_uid = in->si_uid;
174 out->si_status = in->si_status;
b0d623f7 175 out->si_addr = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_addr);
91447636 176 /* following cast works for sival_int because of padding */
b0d623f7
A
177 out->si_value.sival_ptr = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_value.sival_ptr);
178 out->si_band = in->si_band; /* range reduction */
179}
180
181static void
182siginfo_user_to_user64(user_siginfo_t *in, user64_siginfo_t *out)
183{
184 out->si_signo = in->si_signo;
185 out->si_errno = in->si_errno;
186 out->si_code = in->si_code;
187 out->si_pid = in->si_pid;
188 out->si_uid = in->si_uid;
189 out->si_status = in->si_status;
190 out->si_addr = in->si_addr;
191 /* following cast works for sival_int because of padding */
192 out->si_value.sival_ptr = in->si_value.sival_ptr;
91447636 193 out->si_band = in->si_band; /* range reduction */
91447636 194}
1c79356b
A
195
196/*
197 * exit --
198 * Death of process.
199 */
1c79356b 200void
2d21ac55 201exit(proc_t p, struct exit_args *uap, int *retval)
1c79356b 202{
0b4e3aa0 203 exit1(p, W_EXITCODE(uap->rval, 0), retval);
1c79356b 204
9bccf70c 205 /* drop funnel before we return */
1c79356b
A
206 thread_exception_return();
207 /* NOTREACHED */
208 while (TRUE)
9bccf70c 209 thread_block(THREAD_CONTINUE_NULL);
1c79356b
A
210 /* NOTREACHED */
211}
212
213/*
214 * Exit: deallocate address space and other resources, change proc state
215 * to zombie, and unlink proc from allproc and parent's lists. Save exit
216 * status and rusage for wait(). Check for child processes and orphan them.
217 */
0b4e3aa0 218int
2d21ac55 219exit1(proc_t p, int rv, int *retval)
1c79356b 220{
91447636 221 thread_t self = current_thread();
1c79356b 222 struct task *task = p->task;
1c79356b
A
223 struct uthread *ut;
224
225 /*
226 * If a thread in this task has already
227 * called exit(), then halt any others
228 * right here.
229 */
0b4e3aa0 230
55e303ae 231 ut = get_bsdthread_info(self);
91447636
A
232 if (ut->uu_flag & UT_VFORK) {
233 vfork_exit(p, rv);
2d21ac55 234 vfork_return(p , retval, p->p_pid);
0b4e3aa0
A
235 unix_syscall_return(0);
236 /* NOT REACHED */
237 }
2d21ac55
A
238
239 /*
240 * The parameter list of audit_syscall_exit() was augmented to
241 * take the Darwin syscall number as the first parameter,
242 * which is currently required by mac_audit_postselect().
243 */
244
b0d623f7
A
245 /*
246 * The BSM token contains two components: an exit status as passed
247 * to exit(), and a return value to indicate what sort of exit it
248 * was. The exit status is WEXITSTATUS(rv), but it's not clear
249 * what the return value is.
250 */
251 AUDIT_ARG(exit, WEXITSTATUS(rv), 0);
2d21ac55
A
252 AUDIT_SYSCALL_EXIT(SYS_exit, p, ut, 0); /* Exit is always successfull */
253
254 DTRACE_PROC1(exit, int, CLD_EXITED);
255
256 proc_lock(p);
1c79356b
A
257 while (p->exit_thread != self) {
258 if (sig_try_locked(p) <= 0) {
55e303ae 259 if (get_threadtask(self) != task) {
2d21ac55 260 proc_unlock(p);
0b4e3aa0 261 return(0);
1c79356b 262 }
2d21ac55 263 proc_unlock(p);
55e303ae 264 thread_terminate(self);
1c79356b
A
265 thread_exception_return();
266 /* NOTREACHED */
267 }
268 sig_lock_to_exit(p);
269 }
4a3eedf9 270 if (p == initproc) {
2d21ac55 271 proc_unlock(p);
1c79356b
A
272 printf("pid 1 exited (signal %d, exit %d)",
273 WTERMSIG(rv), WEXITSTATUS(rv));
2d21ac55
A
274 panic("%s died\nState at Last Exception:\n\n%s",
275 (p->p_comm[0] != '\0' ?
276 p->p_comm :
277 "launchd"),
1c79356b
A
278 init_task_failure_data);
279 }
280
2d21ac55 281 p->p_lflag |= P_LEXIT;
1c79356b
A
282 p->p_xstat = rv;
283
2d21ac55
A
284 proc_unlock(p);
285
286 proc_prepareexit(p, rv);
287
1c79356b
A
288 /* task terminate will call proc_terminate and that cleans it up */
289 task_terminate_internal(task);
290
0b4e3aa0 291 return(0);
1c79356b
A
292}
293
294void
2d21ac55 295proc_prepareexit(proc_t p, int rv)
1c79356b 296{
2d21ac55 297 mach_exception_data_type_t code, subcode;
1c79356b 298 struct uthread *ut;
91447636 299 thread_t self = current_thread();
2d21ac55 300 ut = get_bsdthread_info(self);
55e303ae 301
2d21ac55 302 /* If a core should be generated, notify crash reporter */
b0d623f7 303 if (hassigprop(WTERMSIG(rv), SA_CORE)) {
2d21ac55
A
304 /*
305 * Workaround for processes checking up on PT_DENY_ATTACH:
306 * should be backed out post-Leopard (details in 5431025).
307 */
308 if ((SIGSEGV == WTERMSIG(rv)) &&
309 (p->p_pptr->p_lflag & P_LNOATTACH)) {
310 goto skipcheck;
311 }
312
313 /*
314 * Crash Reporter looks for the signal value, original exception
315 * type, and low 20 bits of the original code in code[0]
316 * (8, 4, and 20 bits respectively). code[1] is unmodified.
317 */
318 code = ((WTERMSIG(rv) & 0xff) << 24) |
319 ((ut->uu_exception & 0x0f) << 20) |
320 ((int)ut->uu_code & 0xfffff);
321 subcode = ut->uu_subcode;
322 (void) abnormal_exit_notify(code, subcode);
323 }
324
325skipcheck:
91447636 326 /* Notify the perf server */
2d21ac55 327 (void)sys_perf_notify(self, p->p_pid);
1c79356b 328
1c79356b
A
329 /*
330 * Remove proc from allproc queue and from pidhash chain.
331 * Need to do this before we do anything that can block.
332 * Not doing causes things like mount() find this on allproc
333 * in partially cleaned state.
334 */
2d21ac55
A
335
336 proc_list_lock();
337
1c79356b 338 LIST_REMOVE(p, p_list);
55e303ae 339 LIST_INSERT_HEAD(&zombproc, p, p_list); /* Place onto zombproc. */
2d21ac55
A
340 /* will not be visible via proc_find */
341 p->p_listflag |= P_LIST_EXITED;
342
343 proc_list_unlock();
344
1c79356b
A
345
346#ifdef PGINPROF
347 vmsizmon();
348#endif
349 /*
350 * If parent is waiting for us to exit or exec,
2d21ac55 351 * P_LPPWAIT is set; we will wakeup the parent below.
1c79356b 352 */
2d21ac55
A
353 proc_lock(p);
354 p->p_lflag &= ~(P_LTRACED | P_LPPWAIT);
91447636 355 p->p_sigignore = ~(sigcantmask);
9bccf70c 356 ut->uu_siglist = 0;
2d21ac55 357 proc_unlock(p);
1c79356b
A
358}
359
360void
2d21ac55 361proc_exit(proc_t p)
1c79356b 362{
2d21ac55
A
363 proc_t q;
364 proc_t pp;
1c79356b 365 struct task *task = p->task;
2d21ac55
A
366 vnode_t tvp = NULLVP;
367 struct pgrp * pg;
368 struct session *sessp;
369 struct uthread * uth;
b0d623f7
A
370 pid_t pid;
371 int exitval;
1c79356b
A
372
373 /* This can happen if thread_terminate of the single thread
374 * process
375 */
376
2d21ac55
A
377 uth = (struct uthread *)get_bsdthread_info(current_thread());
378
379 proc_lock(p);
380 if( !(p->p_lflag & P_LEXIT)) {
381 p->p_lflag |= P_LEXIT;
382 proc_unlock(p);
383 proc_prepareexit(p, 0);
384 proc_lock(p);
1c79356b
A
385 }
386
91447636 387 p->p_lflag |= P_LPEXIT;
2d21ac55 388 proc_unlock(p);
b0d623f7
A
389 pid = p->p_pid;
390 exitval = p->p_xstat;
391 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_EXIT) | DBG_FUNC_START,
392 pid, exitval, 0, 0, 0);
2d21ac55
A
393
394#if CONFIG_DTRACE
395 /*
396 * Free any outstanding lazy dof entries. It is imperative we
397 * always call dtrace_lazy_dofs_destroy, rather than null check
398 * and call if !NULL. If we NULL test, during lazy dof faulting
399 * we can race with the faulting code and proceed from here to
400 * beyond the helpers cleanup. The lazy dof faulting will then
401 * install new helpers which will never be cleaned up, and leak.
402 */
403 dtrace_lazy_dofs_destroy(p);
404
405 /*
406 * Clean up any DTrace helper actions or probes for the process.
407 */
408 if (p->p_dtrace_helpers != NULL) {
409 (*dtrace_helpers_cleanup)(p);
410 }
411
412 /*
413 * Clean up any DTrace probes associated with this process.
414 */
415 /*
416 * APPLE NOTE: We release ptss pages/entries in dtrace_fasttrap_exit_ptr(),
417 * call this after dtrace_helpers_cleanup()
418 */
419 proc_lock(p);
420 if (p->p_dtrace_probes && dtrace_fasttrap_exit_ptr) {
421 (*dtrace_fasttrap_exit_ptr)(p);
422 }
423 proc_unlock(p);
424#endif
425
91447636 426 /* XXX Zombie allocation may fail, in which case stats get lost */
1c79356b
A
427 MALLOC_ZONE(p->p_ru, struct rusage *,
428 sizeof (*p->p_ru), M_ZOMBIE, M_WAITOK);
429
55e303ae
A
430 /*
431 * need to cancel async IO requests that can be cancelled and wait for those
432 * already active. MAY BLOCK!
433 */
ff6e181a 434
2d21ac55
A
435 proc_refdrain(p);
436
437 workqueue_exit(p);
ff6e181a 438
55e303ae
A
439 _aio_exit( p );
440
1c79356b
A
441 /*
442 * Close open files and release open-file table.
443 * This may block!
444 */
445 fdfree(p);
446
593a1d5f
A
447 if (uth->uu_lowpri_window) {
448 /*
449 * task is marked as a low priority I/O type
b0d623f7 450 * and the I/O we issued while in flushing files on close
593a1d5f
A
451 * collided with normal I/O operations...
452 * no need to throttle this thread since its going away
453 * but we do need to update our bookeeping w/r to throttled threads
454 */
455 throttle_lowpri_io(FALSE);
456 }
457
2d21ac55 458#if SYSV_SHM
1c79356b
A
459 /* Close ref SYSV Shared memory*/
460 if (p->vm_shm)
461 shmexit(p);
2d21ac55
A
462#endif
463#if SYSV_SEM
9bccf70c
A
464 /* Release SYSV semaphores */
465 semexit(p);
2d21ac55 466#endif
1c79356b 467
b0d623f7
A
468#if PSYNCH
469 pth_proc_hashdelete(p);
470#endif /* PSYNCH */
471
2d21ac55
A
472 sessp = proc_session(p);
473 if (SESS_LEADER(p, sessp)) {
474
2d21ac55 475 if (sessp->s_ttyvp != NULLVP) {
fa4905b1 476 struct vnode *ttyvp;
2d21ac55 477 int ttyvid;
91447636 478 struct vfs_context context;
2d21ac55
A
479 struct tty * tp;
480
fa4905b1 481
1c79356b
A
482 /*
483 * Controlling process.
484 * Signal foreground pgrp,
485 * drain controlling terminal
486 * and revoke access to controlling terminal.
487 */
b0d623f7 488 tp = SESSION_TP(sessp);
2d21ac55
A
489
490 if ((tp != TTY_NULL) && (tp->t_session == sessp)) {
491 tty_pgsignal(tp, SIGHUP, 1);
2d21ac55
A
492
493 session_lock(sessp);
b0d623f7
A
494 /* reget potentially tp due to revocation */
495 tp = SESSION_TP(sessp);
2d21ac55
A
496 ttyvp = sessp->s_ttyvp;
497 ttyvid = sessp->s_ttyvid;
b0d623f7 498 sessp->s_ttyvp = NULLVP;
2d21ac55 499 sessp->s_ttyvid = 0;
b0d623f7 500 sessp->s_ttyp = TTY_NULL;
2d21ac55
A
501 sessp->s_ttypgrpid = NO_PID;
502 session_unlock(sessp);
503
504 if ((ttyvp != NULLVP) && (vnode_getwithvid(ttyvp, ttyvid) == 0)) {
b0d623f7
A
505
506 if (tp != TTY_NULL) {
507 tty_lock(tp);
508 (void) ttywait(tp);
509 tty_unlock(tp);
510 }
2d21ac55
A
511 context.vc_thread = proc_thread(p); /* XXX */
512 context.vc_ucred = kauth_cred_proc_ref(p);
513 VNOP_REVOKE(ttyvp, REVOKEALL, &context);
514 vnode_put(ttyvp);
515 kauth_cred_unref(&context.vc_ucred);
516 }
517 } else {
518 session_lock(sessp);
b0d623f7
A
519 /* reget potentially tp due to revocation */
520 tp = SESSION_TP(sessp);
2d21ac55 521 ttyvp = sessp->s_ttyvp;
b0d623f7 522 sessp->s_ttyvp = NULLVP;
2d21ac55 523 sessp->s_ttyvid = 0;
b0d623f7 524 sessp->s_ttyp = TTY_NULL;
2d21ac55
A
525 sessp->s_ttypgrpid = NO_PID;
526 session_unlock(sessp);
1c79356b 527 }
2d21ac55 528 if (ttyvp)
91447636 529 vnode_rele(ttyvp);
1c79356b
A
530 /*
531 * s_ttyp is not zero'd; we use this to indicate
532 * that the session once had a controlling terminal.
533 * (for logging and informational purposes)
534 */
535 }
2d21ac55 536
2d21ac55
A
537 session_lock(sessp);
538 sessp->s_leader = NULL;
539 session_unlock(sessp);
1c79356b 540 }
2d21ac55
A
541 session_rele(sessp);
542
543 pg = proc_pgrp(p);
544 fixjobc(p, pg, 0);
545 pg_rele(pg);
1c79356b 546
1c79356b 547 p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
9bccf70c
A
548 (void)acct_process(p);
549
2d21ac55 550 proc_list_lock();
b0d623f7
A
551
552 if ((p->p_listflag & P_LIST_EXITCOUNT) == P_LIST_EXITCOUNT) {
553 p->p_listflag &= ~P_LIST_EXITCOUNT;
554 proc_shutdown_exitcount--;
555 if (proc_shutdown_exitcount == 0)
556 wakeup(&proc_shutdown_exitcount);
557 }
558
2d21ac55
A
559 /* wait till parentrefs are dropped and grant no more */
560 proc_childdrainstart(p);
561 while ((q = p->p_children.lh_first) != NULL) {
562 q->p_listflag |= P_LIST_DEADPARENT;
563 if (q->p_stat == SZOMB) {
564 if (p != q->p_pptr)
565 panic("parent child linkage broken");
566 /* check for sysctl zomb lookup */
567 while ((q->p_listflag & P_LIST_WAITING) == P_LIST_WAITING) {
568 msleep(&q->p_stat, proc_list_mlock, PWAIT, "waitcoll", 0);
569 }
570 q->p_listflag |= P_LIST_WAITING;
571 /*
572 * This is a named reference and it is not granted
573 * if the reap is already in progress. So we get
574 * the reference here exclusively and their can be
575 * no waiters. So there is no need for a wakeup
576 * after we are done. AlsO the reap frees the structure
577 * and the proc struct cannot be used for wakeups as well.
578 * It is safe to use q here as this is system reap
579 */
580 (void)reap_child_locked(p, q, 1, 1, 0);
581 } else {
582 proc_reparentlocked(q, initproc, 0, 1);
583 /*
584 * Traced processes are killed
585 * since their existence means someone is messing up.
586 */
587 if (q->p_lflag & P_LTRACED) {
588 proc_list_unlock();
589 proc_lock(q);
590 q->p_lflag &= ~P_LTRACED;
591 if (q->sigwait_thread) {
592 proc_unlock(q);
593 /*
594 * The sigwait_thread could be stopped at a
595 * breakpoint. Wake it up to kill.
596 * Need to do this as it could be a thread which is not
597 * the first thread in the task. So any attempts to kill
598 * the process would result into a deadlock on q->sigwait.
599 */
600 thread_resume((thread_t)q->sigwait_thread);
601 clear_wait(q->sigwait_thread, THREAD_INTERRUPTED);
602 threadsignal((thread_t)q->sigwait_thread, SIGKILL, 0);
603 } else
604 proc_unlock(q);
605 psignal(q, SIGKILL);
606 proc_list_lock();
1c79356b 607 }
1c79356b
A
608 }
609 }
610
2d21ac55
A
611 proc_childdrainend(p);
612 proc_list_unlock();
613
614 /*
615 * Release reference to text vnode
616 */
617 tvp = p->p_textvp;
618 p->p_textvp = NULL;
619 if (tvp != NULLVP) {
620 vnode_rele(tvp);
621 }
622
1c79356b
A
623 /*
624 * Save exit status and final rusage info, adding in child rusage
91447636
A
625 * info and self times. If we were unable to allocate a zombie
626 * structure, this information is lost.
1c79356b 627 */
2d21ac55 628 /* No need for locking here as no one than this thread can access this */
91447636
A
629 if (p->p_ru != NULL) {
630 *p->p_ru = p->p_stats->p_ru;
1c79356b 631
b0d623f7 632 calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL);
1c79356b 633
91447636
A
634 ruadd(p->p_ru, &p->p_stats->p_cru);
635 }
1c79356b
A
636
637 /*
638 * Free up profiling buffers.
639 */
640 {
641 struct uprof *p0 = &p->p_stats->p_prof, *p1, *pn;
642
643 p1 = p0->pr_next;
644 p0->pr_next = NULL;
645 p0->pr_scale = 0;
646
647 for (; p1 != NULL; p1 = pn) {
648 pn = p1->pr_next;
91447636 649 kfree(p1, sizeof *p1);
1c79356b
A
650 }
651 }
652
2d21ac55
A
653 proc_spinlock(p);
654 if (thread_call_cancel(p->p_rcall))
655 p->p_ractive--;
656
657 while (p->p_ractive > 0) {
658 proc_spinunlock(p);
659
660 delay(1);
661
662 proc_spinlock(p);
663 }
664 proc_spinunlock(p);
665
666 thread_call_free(p->p_rcall);
667 p->p_rcall = NULL;
668
1c79356b
A
669 /*
670 * Other substructures are freed from wait().
671 */
2d21ac55 672 FREE_ZONE(p->p_stats, sizeof *p->p_stats, M_PSTATS);
1c79356b
A
673 p->p_stats = NULL;
674
2d21ac55 675 FREE_ZONE(p->p_sigacts, sizeof *p->p_sigacts, M_SIGACTS);
1c79356b
A
676 p->p_sigacts = NULL;
677
2d21ac55 678 proc_limitdrop(p, 1);
1c79356b
A
679 p->p_limit = NULL;
680
2d21ac55 681
1c79356b
A
682 /*
683 * Finish up by terminating the task
684 * and halt this thread (only if a
685 * member of the task exiting).
686 */
687 p->task = TASK_NULL;
1c79356b
A
688 set_bsdtask_info(task, NULL);
689
2d21ac55 690 proc_knote(p, NOTE_EXIT);
55e303ae 691
2d21ac55
A
692 /* mark the thread as the one that is doing proc_exit
693 * no need to hold proc lock in uthread_free
694 */
695 uth->uu_flag |= UT_PROCEXIT;
1c79356b
A
696 /*
697 * Notify parent that we're gone.
698 */
2d21ac55
A
699 pp = proc_parent(p);
700 if (pp->p_flag & P_NOCLDWAIT) {
9bccf70c 701
2d21ac55
A
702#if 3839178
703 /*
704 * If the parent is ignoring SIGCHLD, then POSIX requires
705 * us to not add the resource usage to the parent process -
706 * we are only going to hand it off to init to get reaped.
707 * We should contest the standard in this case on the basis
708 * of RLIMIT_CPU.
709 */
710#else /* !3839178 */
55e303ae
A
711 /*
712 * Add child resource usage to parent before giving
91447636
A
713 * zombie to init. If we were unable to allocate a
714 * zombie structure, this information is lost.
55e303ae 715 */
2d21ac55
A
716 if (p->p_ru != NULL) {
717 proc_lock(pp);
718 ruadd(&pp->p_stats->p_cru, p->p_ru);
719 proc_unlock(pp);
720 }
721#endif /* !3839178 */
55e303ae 722
2d21ac55
A
723 /* kernel can reap this one, no need to move it to launchd */
724 proc_list_lock();
725 p->p_listflag |= P_LIST_DEADPARENT;
726 proc_list_unlock();
9bccf70c 727 }
2d21ac55
A
728 if ((p->p_listflag & P_LIST_DEADPARENT) == 0) {
729 if (pp != initproc) {
730 proc_lock(pp);
731 pp->si_pid = p->p_pid;
732 pp->si_status = p->p_xstat;
733 pp->si_code = CLD_EXITED;
734 /*
735 * p_ucred usage is safe as it is an exiting process
736 * and reference is dropped in reap
737 */
738 pp->si_uid = p->p_ucred->cr_ruid;
739 proc_unlock(pp);
740 }
741 /* mark as a zombie */
742 /* No need to take proc lock as all refs are drained and
743 * no one except parent (reaping ) can look at this.
744 * The write is to an int and is coherent. Also parent is
745 * keyed off of list lock for reaping
746 */
b0d623f7
A
747 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_EXIT) | DBG_FUNC_END,
748 pid, exitval, 0, 0, 0);
2d21ac55
A
749 p->p_stat = SZOMB;
750 /*
751 * The current process can be reaped so, no one
752 * can depend on this
753 */
1c79356b 754
2d21ac55
A
755 psignal(pp, SIGCHLD);
756
757 /* and now wakeup the parent */
758 proc_list_lock();
759 wakeup((caddr_t)pp);
760 proc_list_unlock();
761 } else {
762 /* should be fine as parent proc would be initproc */
763 /* mark as a zombie */
764 /* No need to take proc lock as all refs are drained and
765 * no one except parent (reaping ) can look at this.
766 * The write is to an int and is coherent. Also parent is
767 * keyed off of list lock for reaping
768 */
769 proc_list_lock();
b0d623f7
A
770 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_EXIT) | DBG_FUNC_END,
771 pid, exitval, 0, 0, 0);
2d21ac55
A
772 /* check for sysctl zomb lookup */
773 while ((p->p_listflag & P_LIST_WAITING) == P_LIST_WAITING) {
774 msleep(&p->p_stat, proc_list_mlock, PWAIT, "waitcoll", 0);
775 }
776 /* safe to use p as this is a system reap */
d1ecb069 777 p->p_stat = SZOMB;
2d21ac55 778 p->p_listflag |= P_LIST_WAITING;
d1ecb069 779
2d21ac55
A
780 /*
781 * This is a named reference and it is not granted
782 * if the reap is already in progress. So we get
783 * the reference here exclusively and their can be
784 * no waiters. So there is no need for a wakeup
785 * after we are done. AlsO the reap frees the structure
786 * and the proc struct cannot be used for wakeups as well.
787 * It is safe to use p here as this is system reap
788 */
789 (void)reap_child_locked(pp, p, 1, 1, 1);
790 /* list lock dropped by reap_child_locked */
791 }
593a1d5f
A
792 if (uth->uu_lowpri_window) {
793 /*
794 * task is marked as a low priority I/O type and we've
795 * somehow picked up another throttle during exit processing...
796 * no need to throttle this thread since its going away
797 * but we do need to update our bookeeping w/r to throttled threads
798 */
799 throttle_lowpri_io(FALSE);
800 }
91447636 801
2d21ac55 802 proc_rele(pp);
1c79356b 803
1c79356b
A
804}
805
806
91447636 807/*
2d21ac55 808 * reap_child_locked
91447636
A
809 *
810 * Description: Given a process from which all status information needed
811 * has already been extracted, if the process is a ptrace
812 * attach process, detach it and give it back to its real
813 * parent, else recover all resources remaining associated
814 * with it.
815 *
2d21ac55
A
816 * Parameters: proc_t parent Parent of process being reaped
817 * proc_t child Process to reap
91447636
A
818 *
819 * Returns: 0 Process was not reaped because it
820 * came from an attach
821 * 1 Process was reaped
822 */
823static int
2d21ac55 824reap_child_locked(proc_t parent, proc_t child, int deadparent, int locked, int droplock)
1c79356b 825{
b0d623f7 826 proc_t trace_parent = PROC_NULL; /* Traced parent process, if tracing */
1c79356b 827
b0d623f7
A
828 if (locked == 1)
829 proc_list_unlock();
830
91447636
A
831 /*
832 * If we got the child via a ptrace 'attach',
833 * we need to give it back to the old parent.
b0d623f7
A
834 *
835 * Exception: someone who has been reparented to launchd before being
836 * ptraced can simply be reaped, refer to radar 5677288
837 * p_oppid -> ptraced
838 * trace_parent == initproc -> away from launchd
839 * P_LIST_DEADPARENT -> came to launchd by reparenting
91447636 840 */
b0d623f7
A
841 if (child->p_oppid && (trace_parent = proc_find(child->p_oppid))
842 && !((trace_parent == initproc) && (child->p_lflag & P_LIST_DEADPARENT))) {
2d21ac55 843 proc_lock(child);
91447636 844 child->p_oppid = 0;
2d21ac55 845 proc_unlock(child);
91447636 846 if (trace_parent != initproc) {
2d21ac55
A
847 /*
848 * proc internal fileds and p_ucred usage safe
849 * here as child is dead and is not reaped or
850 * reparented yet
851 */
852 proc_lock(trace_parent);
91447636
A
853 trace_parent->si_pid = child->p_pid;
854 trace_parent->si_status = child->p_xstat;
855 trace_parent->si_code = CLD_CONTINUED;
856 trace_parent->si_uid = child->p_ucred->cr_ruid;
2d21ac55 857 proc_unlock(trace_parent);
91447636 858 }
2d21ac55 859 proc_reparentlocked(child, trace_parent, 1, 0);
91447636 860 psignal(trace_parent, SIGCHLD);
2d21ac55 861 proc_list_lock();
91447636 862 wakeup((caddr_t)trace_parent);
2d21ac55
A
863 child->p_listflag &= ~P_LIST_WAITING;
864 wakeup(&child->p_stat);
865 proc_list_unlock();
866 proc_rele(trace_parent);
867 if ((locked == 1) && (droplock == 0))
868 proc_list_lock();
91447636
A
869 return (0);
870 }
b0d623f7
A
871
872 if (trace_parent != PROC_NULL) {
873 proc_rele(trace_parent);
874 }
875
2d21ac55 876 proc_knote(child, NOTE_REAP);
b0d623f7 877 proc_knote_drain(child);
2d21ac55 878
91447636
A
879 child->p_xstat = 0;
880 if (child->p_ru) {
2d21ac55
A
881 proc_lock(parent);
882#if 3839178
883 /*
884 * If the parent is ignoring SIGCHLD, then POSIX requires
885 * us to not add the resource usage to the parent process -
886 * we are only going to hand it off to init to get reaped.
887 * We should contest the standard in this case on the basis
888 * of RLIMIT_CPU.
889 */
890 if (!(parent->p_flag & P_NOCLDWAIT))
891#endif /* 3839178 */
892 ruadd(&parent->p_stats->p_cru, child->p_ru);
893 proc_unlock(parent);
91447636
A
894 FREE_ZONE(child->p_ru, sizeof *child->p_ru, M_ZOMBIE);
895 child->p_ru = NULL;
896 } else {
897 printf("Warning : lost p_ru for %s\n", child->p_comm);
898 }
1c79356b 899
b0d623f7
A
900 AUDIT_SESSION_PROCEXIT(child->p_ucred);
901
91447636
A
902 /*
903 * Decrement the count of procs running with this uid.
2d21ac55
A
904 * p_ucred usage is safe here as it is an exited process.
905 * and refernce is dropped after these calls down below
906 * (locking protection is provided by list lock held in chgproccnt)
91447636
A
907 */
908 (void)chgproccnt(child->p_ucred->cr_ruid, -1);
1c79356b 909
2d21ac55
A
910#if CONFIG_LCTX
911 ALLLCTX_LOCK;
912 leavelctx(child);
913 ALLLCTX_UNLOCK;
914#endif
915
91447636
A
916 /*
917 * Free up credentials.
918 */
0c530ab8
A
919 if (IS_VALID_CRED(child->p_ucred)) {
920 kauth_cred_unref(&child->p_ucred);
921 }
1c79356b 922
2d21ac55
A
923 /* XXXX Note NOT SAFE TO USE p_ucred from this point onwards */
924
91447636
A
925 /*
926 * Finally finished with old proc entry.
927 * Unlink it from its process group and free it.
928 */
929 leavepgrp(child);
2d21ac55
A
930
931 proc_list_lock();
91447636 932 LIST_REMOVE(child, p_list); /* off zombproc */
2d21ac55 933 parent->p_childrencnt--;
91447636 934 LIST_REMOVE(child, p_sibling);
2d21ac55
A
935 /* If there are no more children wakeup parent */
936 if ((deadparent != 0) && (LIST_EMPTY(&parent->p_children)))
937 wakeup((caddr_t)parent); /* with list lock held */
938 child->p_listflag &= ~P_LIST_WAITING;
b36670ce 939 wakeup(&child->p_stat);
1c79356b 940
2d21ac55
A
941 /* Take it out of process hash */
942 LIST_REMOVE(child, p_hash);
943 child->p_listflag &= ~P_LIST_INHASH;
944 proc_checkdeadrefs(child);
945 nprocs--;
946
947 proc_list_unlock();
948
b0d623f7 949#ifdef CONFIG_EMBEDDED
91447636
A
950 lck_mtx_destroy(&child->p_mlock, proc_lck_grp);
951 lck_mtx_destroy(&child->p_fdmlock, proc_lck_grp);
2d21ac55
A
952#if CONFIG_DTRACE
953 lck_mtx_destroy(&child->p_dtrace_sprlock, proc_lck_grp);
954#endif
955 lck_spin_destroy(&child->p_slock, proc_lck_grp);
b0d623f7
A
956
957#else
958 lck_mtx_destroy(&child->p_mlock, proc_mlock_grp);
959 lck_mtx_destroy(&child->p_fdmlock, proc_fdmlock_grp);
960#if CONFIG_DTRACE
961 lck_mtx_destroy(&child->p_dtrace_sprlock, proc_lck_grp);
962#endif
963 lck_spin_destroy(&child->p_slock, proc_slock_grp);
964#endif
2d21ac55
A
965 workqueue_destroy_lock(child);
966
91447636 967 FREE_ZONE(child, sizeof *child, M_PROC);
2d21ac55
A
968 if ((locked == 1) && (droplock == 0))
969 proc_list_lock();
970
91447636 971 return (1);
1c79356b
A
972}
973
1c79356b
A
974
975int
91447636 976wait1continue(int result)
1c79356b 977{
7b1edb79 978 void *vt;
91447636 979 thread_t thread;
7b1edb79 980 int *retval;
2d21ac55 981 proc_t p;
1c79356b 982
7b1edb79
A
983 if (result)
984 return(result);
1c79356b 985
7b1edb79 986 p = current_proc();
91447636
A
987 thread = current_thread();
988 vt = get_bsduthreadarg(thread);
989 retval = get_bsduthreadrval(thread);
2d21ac55 990 return(wait4(p, (struct wait4_args *)vt, retval));
1c79356b
A
991}
992
993int
b0d623f7 994wait4(proc_t q, struct wait4_args *uap, int32_t *retval)
1c79356b 995{
2d21ac55
A
996 __pthread_testcancel(1);
997 return(wait4_nocancel(q, (struct wait4_nocancel_args *)uap, retval));
998}
999
1000int
b0d623f7 1001wait4_nocancel(proc_t q, struct wait4_nocancel_args *uap, int32_t *retval)
2d21ac55
A
1002{
1003 int nfound;
b0d623f7 1004 int sibling_count;
2d21ac55 1005 proc_t p;
1c79356b
A
1006 int status, error;
1007
b0d623f7
A
1008 AUDIT_ARG(pid, uap->pid);
1009
1c79356b 1010 if (uap->pid == 0)
2d21ac55 1011 uap->pid = -q->p_pgrpid;
1c79356b
A
1012
1013loop:
2d21ac55
A
1014 proc_list_lock();
1015loop1:
1c79356b 1016 nfound = 0;
b0d623f7
A
1017 sibling_count = 0;
1018
1c79356b 1019 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
b0d623f7
A
1020 if ( p->p_sibling.le_next != 0 )
1021 sibling_count++;
1c79356b
A
1022 if (uap->pid != WAIT_ANY &&
1023 p->p_pid != uap->pid &&
2d21ac55 1024 p->p_pgrpid != -(uap->pid))
1c79356b 1025 continue;
2d21ac55 1026
1c79356b 1027 nfound++;
91447636
A
1028
1029 /* XXX This is racy because we don't get the lock!!!! */
1030
2d21ac55
A
1031 if (p->p_listflag & P_LIST_WAITING) {
1032 (void)msleep(&p->p_stat, proc_list_mlock, PWAIT, "waitcoll", 0);
1033 goto loop1;
7b1edb79 1034 }
2d21ac55
A
1035 p->p_listflag |= P_LIST_WAITING; /* only allow single thread to wait() */
1036
7b1edb79 1037
1c79356b 1038 if (p->p_stat == SZOMB) {
2d21ac55
A
1039 proc_list_unlock();
1040#if CONFIG_MACF
1041 if ((error = mac_proc_check_wait(q, p)) != 0)
1042 goto out;
1043#endif
1c79356b 1044 retval[0] = p->p_pid;
1c79356b 1045 if (uap->status) {
2d21ac55
A
1046 /* Legacy apps expect only 8 bits of status */
1047 status = 0xffff & p->p_xstat; /* convert to int */
91447636
A
1048 error = copyout((caddr_t)&status,
1049 uap->status,
1050 sizeof(status));
2d21ac55
A
1051 if (error)
1052 goto out;
1c79356b 1053 }
91447636
A
1054 if (uap->rusage) {
1055 if (p->p_ru == NULL) {
1056 error = ENOMEM;
1057 } else {
1058 if (IS_64BIT_PROCESS(q)) {
b0d623f7
A
1059 struct user64_rusage my_rusage;
1060 munge_user64_rusage(p->p_ru, &my_rusage);
91447636
A
1061 error = copyout((caddr_t)&my_rusage,
1062 uap->rusage,
1063 sizeof (my_rusage));
1064 }
1065 else {
b0d623f7
A
1066 struct user32_rusage my_rusage;
1067 munge_user32_rusage(p->p_ru, &my_rusage);
1068 error = copyout((caddr_t)&my_rusage,
91447636 1069 uap->rusage,
b0d623f7 1070 sizeof (my_rusage));
91447636 1071 }
9bccf70c 1072 }
91447636 1073 /* information unavailable? */
2d21ac55
A
1074 if (error)
1075 goto out;
1c79356b
A
1076 }
1077
b0d623f7
A
1078 /* Conformance change for 6577252.
1079 * When SIGCHLD is blocked and wait() returns because the status
1080 * of a child process is available and there are no other
1081 * children processes, then any pending SIGCHLD signal is cleared.
1082 */
1083 if ( sibling_count == 0 ) {
1084 int mask = sigmask(SIGCHLD);
1085 uthread_t uth = (struct uthread *)get_bsdthread_info(current_thread());
1086
1087 if ( (uth->uu_sigmask & mask) != 0 ) {
1088 /* we are blocking SIGCHLD signals. clear any pending SIGCHLD.
1089 * This locking looks funny but it is protecting access to the
1090 * thread via p_uthlist.
1091 */
1092 proc_lock(q);
1093 uth->uu_siglist &= ~mask; /* clear pending signal */
1094 proc_unlock(q);
1095 }
b36670ce 1096 }
b0d623f7
A
1097
1098 /* Clean up */
1099 (void)reap_child_locked(q, p, 0, 0, 0);
91447636 1100
1c79356b
A
1101 return (0);
1102 }
2d21ac55
A
1103 if (p->p_stat == SSTOP && (p->p_lflag & P_LWAITED) == 0 &&
1104 (p->p_lflag & P_LTRACED || uap->options & WUNTRACED)) {
1105 proc_list_unlock();
1106#if CONFIG_MACF
1107 if ((error = mac_proc_check_wait(q, p)) != 0)
1108 goto out;
1109#endif
1110 proc_lock(p);
1111 p->p_lflag |= P_LWAITED;
1112 proc_unlock(p);
1c79356b 1113 retval[0] = p->p_pid;
1c79356b
A
1114 if (uap->status) {
1115 status = W_STOPCODE(p->p_xstat);
1116 error = copyout((caddr_t)&status,
91447636 1117 uap->status,
1c79356b
A
1118 sizeof(status));
1119 } else
1120 error = 0;
2d21ac55
A
1121 goto out;
1122 }
1123 /*
1124 * If we are waiting for continued processses, and this
1125 * process was continued
1126 */
1127 if ((uap->options & WCONTINUED) &&
1128 (p->p_flag & P_CONTINUED)) {
1129 proc_list_unlock();
1130#if CONFIG_MACF
1131 if ((error = mac_proc_check_wait(q, p)) != 0)
1132 goto out;
1133#endif
1134
1135 /* Prevent other process for waiting for this event */
b0d623f7 1136 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
2d21ac55
A
1137 retval[0] = p->p_pid;
1138 if (uap->status) {
1139 status = W_STOPCODE(SIGCONT);
1140 error = copyout((caddr_t)&status,
1141 uap->status,
1142 sizeof(status));
1143 } else
1144 error = 0;
1145 goto out;
1c79356b 1146 }
2d21ac55 1147 p->p_listflag &= ~P_LIST_WAITING;
7b1edb79 1148 wakeup(&p->p_stat);
1c79356b 1149 }
2d21ac55
A
1150 /* list lock is held when we get here any which way */
1151 if (nfound == 0) {
1152 proc_list_unlock();
1c79356b 1153 return (ECHILD);
2d21ac55 1154 }
7b1edb79 1155
1c79356b
A
1156 if (uap->options & WNOHANG) {
1157 retval[0] = 0;
2d21ac55 1158 proc_list_unlock();
1c79356b
A
1159 return (0);
1160 }
1161
2d21ac55 1162 if ((error = msleep0((caddr_t)q, proc_list_mlock, PWAIT | PCATCH | PDROP, "wait", 0, wait1continue)))
91447636
A
1163 return (error);
1164
1165 goto loop;
2d21ac55
A
1166out:
1167 proc_list_lock();
1168 p->p_listflag &= ~P_LIST_WAITING;
1169 wakeup(&p->p_stat);
1170 proc_list_unlock();
1171 return (error);
91447636
A
1172}
1173
1174
1175int
1176waitidcontinue(int result)
1177{
1178 void *vt;
1179 thread_t thread;
1180 int *retval;
91447636
A
1181
1182 if (result)
1183 return(result);
1184
91447636
A
1185 thread = current_thread();
1186 vt = get_bsduthreadarg(thread);
1187 retval = get_bsduthreadrval(thread);
2d21ac55 1188 return(waitid(current_proc(), (struct waitid_args *)vt, retval));
91447636
A
1189}
1190
1191/*
1192 * Description: Suspend the calling thread until one child of the process
1193 * containing the calling thread changes state.
1194 *
1195 * Parameters: uap->idtype one of P_PID, P_PGID, P_ALL
1196 * uap->id pid_t or gid_t or ignored
1197 * uap->infop Address of signinfo_t struct in
1198 * user space into which to return status
1199 * uap->options flag values
1200 *
1201 * Returns: 0 Success
1202 * !0 Error returning status to user space
1203 */
1204int
b0d623f7 1205waitid(proc_t q, struct waitid_args *uap, int32_t *retval)
2d21ac55
A
1206{
1207 __pthread_testcancel(1);
1208 return(waitid_nocancel(q, (struct waitid_nocancel_args *)uap, retval));
1209}
1210
1211int
b0d623f7 1212waitid_nocancel(proc_t q, struct waitid_nocancel_args *uap, __unused int32_t *retval)
91447636
A
1213{
1214 user_siginfo_t collect64; /* siginfo data to return to caller */
1215
2d21ac55
A
1216 int nfound;
1217 proc_t p;
91447636
A
1218 int error;
1219
2d21ac55
A
1220 /*
1221 * Forced validation of options for T.waitpid 21; should be a TSD!
1222 * This will pass the test, but note that we have more bits than the
1223 * standard specifies that we will allow in, in this case. The test
1224 * passes because they light all the bits, not just the ones we allow,
1225 * and so the following check returns EINVAL like the test wants.
1226 */
1227 if (((uap->options & (WNOHANG|WNOWAIT|WCONTINUED|WUNTRACED|WSTOPPED|WEXITED)) != uap->options) ||
1228 (uap->options == 0))
1229 return (EINVAL); /* bits set that aren't recognized */
1230
1231 /*
1232 * Overly critical options checking, per POSIX
1233 */
1234 switch(uap->idtype) {
1235 case P_PID: /* child with process ID equal to... */
1236 case P_PGID: /* child with process group ID equal to... */
1237 if (((int)uap->id) < 0)
1238 return (EINVAL);
1239 break;
1240 case P_ALL: /* any child */
1241 break;
1242 }
1243
91447636 1244loop:
2d21ac55
A
1245 proc_list_lock();
1246loop1:
91447636
A
1247 nfound = 0;
1248 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
1249 switch(uap->idtype) {
1250 case P_PID: /* child with process ID equal to... */
1251 if (p->p_pid != (pid_t)uap->id)
1252 continue;
1253 break;
1254 case P_PGID: /* child with process group ID equal to... */
2d21ac55 1255 if (p->p_pgrpid != (pid_t)uap->id)
91447636
A
1256 continue;
1257 break;
1258 case P_ALL: /* any child */
1259 break;
1260 }
1261
1262 /* XXX This is racy because we don't get the lock!!!! */
1263
1264 /*
1265 * Wait collision; go to sleep and restart; used to maintain
1266 * the single return for waited process guarantee.
1267 */
2d21ac55
A
1268 if (p->p_listflag & P_LIST_WAITING) {
1269 (void)msleep(&p->p_stat, proc_list_mlock, PWAIT, "waitidcoll", 0);
1270 goto loop1;
91447636 1271 }
2d21ac55 1272 p->p_listflag |= P_LIST_WAITING; /* mark busy */
91447636
A
1273
1274 nfound++;
1275
1276 /*
1277 * Types of processes we are interested in
1278 *
1279 * XXX Don't know what to do for WCONTINUED?!?
1280 */
1281 switch(p->p_stat) {
1282 case SZOMB: /* Exited */
1283 if (!(uap->options & WEXITED))
1284 break;
1285
2d21ac55
A
1286 /* drop the lock and the thread is going to return */
1287 proc_list_unlock();
1288
91447636 1289 /* Collect "siginfo" information for caller */
2d21ac55 1290 collect64.si_signo = SIGCHLD;
91447636
A
1291 collect64.si_code = 0;
1292 collect64.si_errno = 0;
1293 collect64.si_pid = 0;
1294 collect64.si_uid = 0;
1295 collect64.si_addr = 0;
2d21ac55 1296 collect64.si_status = WEXITSTATUS(p->p_xstat);
91447636
A
1297 collect64.si_band = 0;
1298
1299 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
1300 user64_siginfo_t sinfo64;
1301
1302 siginfo_user_to_user64(&collect64, &sinfo64);
1303
1304 error = copyout((caddr_t)&sinfo64,
91447636 1305 uap->infop,
b0d623f7 1306 sizeof(sinfo64));
91447636 1307 } else {
b0d623f7
A
1308 user32_siginfo_t sinfo32;
1309
1310 siginfo_user_to_user32(&collect64, &sinfo32);
1311
1312 error = copyout((caddr_t)&sinfo32,
1313 uap->infop,
1314 sizeof(sinfo32));
91447636
A
1315 }
1316 /* information unavailable? */
2d21ac55
A
1317 if (error)
1318 goto out;
91447636
A
1319
1320 /* Prevent other process for waiting for this event? */
1321 if (!(uap->options & WNOWAIT)) {
1322 /* Clean up */
b0d623f7 1323 (void)reap_child_locked(q, p, 0, 0, 0);
2d21ac55
A
1324 } else {
1325 proc_list_lock();
1326 p->p_listflag &= ~P_LIST_WAITING;
1327 proc_list_unlock();
91447636
A
1328 }
1329
1330 return (0);
1331
1332 case SSTOP: /* Stopped */
1333 /*
1334 * If we are not interested in stopped processes, then
1335 * ignore this one.
1336 */
1337 if (!(uap->options & WSTOPPED))
1338 break;
1339
1340 /*
1341 * If someone has already waited it, we lost a race
1342 * to be the one to return status.
1343 */
2d21ac55 1344 if ((p->p_lflag & P_LWAITED) != 0)
91447636
A
1345 break;
1346
2d21ac55
A
1347 /* drop the lock and the thread is going to return */
1348 proc_list_unlock();
91447636
A
1349
1350 /* Collect "siginfo" information for caller */
2d21ac55 1351 collect64.si_signo = SIGCHLD;
91447636
A
1352 collect64.si_code = 0;
1353 collect64.si_errno = 0;
1354 collect64.si_pid = 0;
1355 collect64.si_uid = 0;
1356 collect64.si_addr = 0;
2d21ac55 1357 proc_lock(p);
91447636 1358 collect64.si_status = p->p_xstat;
2d21ac55 1359 proc_unlock(p);
91447636
A
1360 collect64.si_band = 0;
1361
1362 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
1363 user64_siginfo_t sinfo64;
1364
1365 siginfo_user_to_user64(&collect64, &sinfo64);
1366
1367 error = copyout((caddr_t)&sinfo64,
1368 uap->infop,
1369 sizeof(sinfo64));
91447636 1370 } else {
b0d623f7
A
1371 user32_siginfo_t sinfo32;
1372
1373 siginfo_user_to_user32(&collect64, &sinfo32);
1374
1375 error = copyout((caddr_t)&sinfo32,
1376 uap->infop,
1377 sizeof(sinfo32));
91447636
A
1378 }
1379 /* information unavailable? */
2d21ac55
A
1380 if (error)
1381 goto out;
91447636
A
1382
1383 /* Prevent other process for waiting for this event? */
1384 if (!(uap->options & WNOWAIT)) {
2d21ac55
A
1385 proc_lock(p);
1386 p->p_lflag |= P_LWAITED;
1387 proc_unlock(p);
91447636
A
1388 }
1389
2d21ac55
A
1390 error = 0;
1391 goto out;
91447636
A
1392
1393 default: /* All others */
1394 /* ...meaning Continued */
1395 if (!(uap->options & WCONTINUED))
1396 break;
1397
1398 /*
1399 * If the flag isn't set, then this process has not
1400 * been stopped and continued, or the status has
1401 * already been reaped by another caller of waitid().
1402 */
1403 if ((p->p_flag & P_CONTINUED) == 0)
1404 break;
1405
2d21ac55
A
1406 /* drop the lock and the thread is going to return */
1407 proc_list_unlock();
1408
91447636 1409 /* Collect "siginfo" information for caller */
2d21ac55
A
1410 proc_lock(p);
1411 collect64.si_signo = SIGCHLD;
1412 collect64.si_code = CLD_CONTINUED;
91447636 1413 collect64.si_errno = 0;
2d21ac55 1414 collect64.si_pid = p->p_contproc;
91447636
A
1415 collect64.si_uid = 0;
1416 collect64.si_addr = 0;
1417 collect64.si_status = p->p_xstat;
1418 collect64.si_band = 0;
2d21ac55 1419 proc_unlock(p);
91447636
A
1420
1421 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
1422 user64_siginfo_t sinfo64;
1423
1424 siginfo_user_to_user64(&collect64, &sinfo64);
1425
1426 error = copyout((caddr_t)&sinfo64,
1427 uap->infop,
1428 sizeof(sinfo64));
91447636 1429 } else {
b0d623f7
A
1430 user32_siginfo_t sinfo32;
1431
1432 siginfo_user_to_user32(&collect64, &sinfo32);
1433
1434 error = copyout((caddr_t)&sinfo32,
1435 uap->infop,
1436 sizeof(sinfo32));
91447636
A
1437 }
1438 /* information unavailable? */
2d21ac55
A
1439 if (error)
1440 goto out;
91447636
A
1441
1442 /* Prevent other process for waiting for this event? */
1443 if (!(uap->options & WNOWAIT)) {
b0d623f7 1444 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
91447636
A
1445 }
1446
2d21ac55
A
1447 error = 0;
1448 goto out;
91447636 1449 }
2d21ac55 1450 /* LIST LOCK IS HELD HERE */
91447636 1451 /* Not a process we are interested in; go on to next child */
2d21ac55
A
1452
1453 p->p_listflag &= ~P_LIST_WAITING;
91447636
A
1454 wakeup(&p->p_stat);
1455 }
1456
2d21ac55 1457 /* list lock is always held */
91447636 1458 /* No child processes that could possibly satisfy the request? */
2d21ac55
A
1459 if (nfound == 0) {
1460 proc_list_unlock();
91447636 1461 return (ECHILD);
2d21ac55 1462 }
91447636
A
1463
1464 if (uap->options & WNOHANG) {
2d21ac55 1465 proc_list_unlock();
91447636
A
1466 return (0);
1467 }
1468
2d21ac55 1469 if ((error = msleep0((caddr_t)q, proc_list_mlock, PWAIT | PCATCH | PDROP, "waitid", 0, waitidcontinue)))
1c79356b 1470 return (error);
7b1edb79 1471
1c79356b 1472 goto loop;
2d21ac55
A
1473out:
1474 proc_list_lock();
1475 p->p_listflag &= ~P_LIST_WAITING;
1476 wakeup(&p->p_stat);
1477 proc_list_unlock();
1478 return (error);
1c79356b
A
1479}
1480
1481/*
1482 * make process 'parent' the new parent of process 'child'.
1483 */
1484void
2d21ac55 1485proc_reparentlocked(proc_t child, proc_t parent, int cansignal, int locked)
1c79356b 1486{
2d21ac55 1487 proc_t oldparent = PROC_NULL;
1c79356b
A
1488
1489 if (child->p_pptr == parent)
1490 return;
1491
2d21ac55
A
1492 if (locked == 0)
1493 proc_list_lock();
1494
1495 oldparent = child->p_pptr;
1496#if __PROC_INTERNAL_DEBUG
1497 if (oldparent == PROC_NULL)
b0d623f7 1498 panic("proc_reparent: process %p does not have a parent\n", child);
2d21ac55
A
1499#endif
1500
1c79356b 1501 LIST_REMOVE(child, p_sibling);
2d21ac55
A
1502#if __PROC_INTERNAL_DEBUG
1503 if (oldparent->p_childrencnt == 0)
1504 panic("process children count already 0\n");
1505#endif
1506 oldparent->p_childrencnt--;
1507#if __PROC_INTERNAL_DEBUG1
1508 if (oldparent->p_childrencnt < 0)
1509 panic("process children count -ve\n");
1510#endif
1c79356b 1511 LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
2d21ac55 1512 parent->p_childrencnt++;
1c79356b 1513 child->p_pptr = parent;
2d21ac55
A
1514 child->p_ppid = parent->p_pid;
1515
1516 proc_list_unlock();
91447636 1517
2d21ac55 1518 if ((cansignal != 0) && (initproc == parent) && (child->p_stat == SZOMB))
91447636 1519 psignal(initproc, SIGCHLD);
2d21ac55
A
1520 if (locked == 1)
1521 proc_list_lock();
1c79356b
A
1522}
1523
0b4e3aa0
A
1524/*
1525 * Exit: deallocate address space and other resources, change proc state
1526 * to zombie, and unlink proc from allproc and parent's lists. Save exit
1527 * status and rusage for wait(). Check for child processes and orphan them.
1528 */
1529
91447636 1530void
2d21ac55
A
1531vfork_exit(proc_t p, int rv)
1532{
1533 vfork_exit_internal(p, rv, 0);
1534}
1535
1536void
1537vfork_exit_internal(proc_t p, int rv, int forceexit)
0b4e3aa0 1538{
91447636
A
1539 thread_t self = current_thread();
1540#ifdef FIXME
0b4e3aa0 1541 struct task *task = p->task;
91447636 1542#endif
0b4e3aa0
A
1543 struct uthread *ut;
1544
91447636
A
1545 /*
1546 * If a thread in this task has already
1547 * called exit(), then halt any others
1548 * right here.
1549 */
1550
1551 ut = get_bsdthread_info(self);
91447636 1552
55e303ae 1553
2d21ac55
A
1554 proc_lock(p);
1555 if ((p->p_lflag & P_LPEXIT) == P_LPEXIT) {
1556 /*
1557 * This happens when a parent exits/killed and vfork is in progress
1558 * other threads. But shutdown code for ex has already called exit1()
1559 */
1560 proc_unlock(p);
1561 return;
1562 }
1563 p->p_lflag |= (P_LEXIT | P_LPEXIT);
1564 proc_unlock(p);
1565
1566 if (forceexit == 0) {
1567 /*
1568 * parent of a vfork child has already called exit() and the
1569 * thread that has vfork in proress terminates. So there is no
1570 * separate address space here and it has already been marked for
1571 * termination. This was never covered before and could cause problems
1572 * if we block here for outside code.
1573 */
1574 /* Notify the perf server */
1575 (void)sys_perf_notify(self, p->p_pid);
1576 }
55e303ae 1577
0b4e3aa0
A
1578 /*
1579 * Remove proc from allproc queue and from pidhash chain.
1580 * Need to do this before we do anything that can block.
1581 * Not doing causes things like mount() find this on allproc
1582 * in partially cleaned state.
1583 */
2d21ac55
A
1584
1585 proc_list_lock();
1586
0b4e3aa0 1587 LIST_REMOVE(p, p_list);
55e303ae 1588 LIST_INSERT_HEAD(&zombproc, p, p_list); /* Place onto zombproc. */
2d21ac55
A
1589 /* will not be visible via proc_find */
1590 p->p_listflag |= P_LIST_EXITED;
0b4e3aa0 1591
2d21ac55 1592 proc_list_unlock();
0b4e3aa0 1593
2d21ac55 1594 proc_lock(p);
0b4e3aa0 1595 p->p_xstat = rv;
2d21ac55
A
1596 p->p_lflag &= ~(P_LTRACED | P_LPPWAIT);
1597 p->p_sigignore = ~0;
1598 proc_unlock(p);
1599
1600 proc_spinlock(p);
1601 if (thread_call_cancel(p->p_rcall))
1602 p->p_ractive--;
1603
1604 while (p->p_ractive > 0) {
1605 proc_spinunlock(p);
1606
1607 delay(1);
1608
1609 proc_spinlock(p);
1610 }
1611 proc_spinunlock(p);
1612
1613 thread_call_free(p->p_rcall);
1614 p->p_rcall = NULL;
1615
1616 ut->uu_siglist = 0;
0b4e3aa0 1617
55e303ae 1618 vproc_exit(p);
0b4e3aa0
A
1619}
1620
0b4e3aa0 1621void
2d21ac55 1622vproc_exit(proc_t p)
0b4e3aa0 1623{
2d21ac55
A
1624 proc_t q;
1625 proc_t pp;
1626
1627 vnode_t tvp;
91447636 1628#ifdef FIXME
0b4e3aa0 1629 struct task *task = p->task;
91447636 1630#endif
2d21ac55
A
1631 struct pgrp * pg;
1632 struct session *sessp;
0b4e3aa0 1633
91447636 1634 /* XXX Zombie allocation may fail, in which case stats get lost */
0b4e3aa0
A
1635 MALLOC_ZONE(p->p_ru, struct rusage *,
1636 sizeof (*p->p_ru), M_ZOMBIE, M_WAITOK);
1637
2d21ac55
A
1638
1639 proc_refdrain(p);
1640
0b4e3aa0
A
1641 /*
1642 * Close open files and release open-file table.
1643 * This may block!
1644 */
1645 fdfree(p);
1646
2d21ac55
A
1647 sessp = proc_session(p);
1648 if (SESS_LEADER(p, sessp)) {
1649
2d21ac55 1650 if (sessp->s_ttyvp != NULLVP) {
fa4905b1 1651 struct vnode *ttyvp;
2d21ac55 1652 int ttyvid;
91447636 1653 struct vfs_context context;
2d21ac55 1654 struct tty * tp;
fa4905b1 1655
0b4e3aa0
A
1656 /*
1657 * Controlling process.
1658 * Signal foreground pgrp,
1659 * drain controlling terminal
1660 * and revoke access to controlling terminal.
1661 */
b0d623f7 1662 tp = SESSION_TP(sessp);
2d21ac55
A
1663
1664 if ((tp != TTY_NULL) && (tp->t_session == sessp)) {
1665 tty_pgsignal(tp, SIGHUP, 1);
b0d623f7 1666 tty_lock(tp);
2d21ac55 1667 (void) ttywait(tp);
b0d623f7 1668 tty_unlock(tp);
0b4e3aa0
A
1669 /*
1670 * The tty could have been revoked
1671 * if we blocked.
1672 */
2d21ac55
A
1673
1674 session_lock(sessp);
b0d623f7
A
1675 /* reget in case of race */
1676 tp = SESSION_TP(sessp);
2d21ac55
A
1677 ttyvp = sessp->s_ttyvp;
1678 ttyvid = sessp->s_ttyvid;
1679 sessp->s_ttyvp = NULL;
1680 sessp->s_ttyvid = 0;
b0d623f7 1681 sessp->s_ttyp = TTY_NULL;
2d21ac55
A
1682 sessp->s_ttypgrpid = NO_PID;
1683 session_unlock(sessp);
1684
1685 if ((ttyvp != NULLVP) && (vnode_getwithvid(ttyvp, ttyvid) == 0)) {
1686 context.vc_thread = proc_thread(p); /* XXX */
1687 context.vc_ucred = kauth_cred_proc_ref(p);
1688 VNOP_REVOKE(ttyvp, REVOKEALL, &context);
1689 vnode_put(ttyvp);
1690 kauth_cred_unref(&context.vc_ucred);
1691 }
1692 } else {
1693 session_lock(sessp);
1694 ttyvp = sessp->s_ttyvp;
1695 sessp->s_ttyvp = NULL;
1696 sessp->s_ttyvid = 0;
b0d623f7 1697 sessp->s_ttyp = TTY_NULL;
2d21ac55
A
1698 sessp->s_ttypgrpid = NO_PID;
1699 session_unlock(sessp);
0b4e3aa0 1700 }
2d21ac55 1701 if (ttyvp)
91447636 1702 vnode_rele(ttyvp);
0b4e3aa0
A
1703 /*
1704 * s_ttyp is not zero'd; we use this to indicate
1705 * that the session once had a controlling terminal.
1706 * (for logging and informational purposes)
1707 */
1708 }
2d21ac55
A
1709
1710 session_lock(sessp);
1711 sessp->s_leader = NULL;
1712 session_unlock(sessp);
0b4e3aa0 1713 }
2d21ac55 1714 session_rele(sessp);
0b4e3aa0 1715
2d21ac55
A
1716 pg = proc_pgrp(p);
1717 fixjobc(p, pg, 0);
1718 pg_rele(pg);
9bccf70c 1719
2d21ac55 1720 p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
0b4e3aa0 1721
2d21ac55
A
1722 proc_list_lock();
1723 proc_childdrainstart(p);
1724 while ((q = p->p_children.lh_first) != NULL) {
1725 q->p_listflag |= P_LIST_DEADPARENT;
1726 if (q->p_stat == SZOMB) {
1727 if (p != q->p_pptr)
1728 panic("parent child linkage broken");
1729 /* check for lookups by zomb sysctl */
1730 while ((q->p_listflag & P_LIST_WAITING) == P_LIST_WAITING) {
1731 msleep(&q->p_stat, proc_list_mlock, PWAIT, "waitcoll", 0);
1732 }
1733 q->p_listflag |= P_LIST_WAITING;
1734 /*
1735 * This is a named reference and it is not granted
1736 * if the reap is already in progress. So we get
1737 * the reference here exclusively and their can be
1738 * no waiters. So there is no need for a wakeup
1739 * after we are done. AlsO the reap frees the structure
1740 * and the proc struct cannot be used for wakeups as well.
1741 * It is safe to use q here as this is system reap
1742 */
1743 (void)reap_child_locked(p, q, 1, 1, 0);
1744 } else {
1745 proc_reparentlocked(q, initproc, 0, 1);
1746 /*
1747 * Traced processes are killed
1748 * since their existence means someone is messing up.
1749 */
1750 if (q->p_lflag & P_LTRACED) {
1751 proc_list_unlock();
1752 proc_lock(q);
1753 q->p_lflag &= ~P_LTRACED;
1754 if (q->sigwait_thread) {
1755 proc_unlock(q);
1756 /*
1757 * The sigwait_thread could be stopped at a
1758 * breakpoint. Wake it up to kill.
1759 * Need to do this as it could be a thread which is not
1760 * the first thread in the task. So any attempts to kill
1761 * the process would result into a deadlock on q->sigwait.
1762 */
1763 thread_resume((thread_t)q->sigwait_thread);
1764 clear_wait(q->sigwait_thread, THREAD_INTERRUPTED);
1765 threadsignal((thread_t)q->sigwait_thread, SIGKILL, 0);
1766 } else
1767 proc_unlock(q);
1768
1769 psignal(q, SIGKILL);
1770 proc_list_lock();
0b4e3aa0 1771 }
0b4e3aa0
A
1772 }
1773 }
1774
2d21ac55
A
1775 proc_childdrainend(p);
1776 proc_list_unlock();
1777
1778 /*
1779 * Release reference to text vnode
1780 */
1781 tvp = p->p_textvp;
1782 p->p_textvp = NULL;
1783 if (tvp != NULLVP) {
1784 vnode_rele(tvp);
1785 }
1786
0b4e3aa0
A
1787 /*
1788 * Save exit status and final rusage info, adding in child rusage
91447636
A
1789 * info and self times. If we were unable to allocate a zombie
1790 * structure, this information is lost.
0b4e3aa0 1791 */
2d21ac55 1792 /* No need for locking here as no one than this thread can access this */
91447636
A
1793 if (p->p_ru != NULL) {
1794 *p->p_ru = p->p_stats->p_ru;
1795 timerclear(&p->p_ru->ru_utime);
1796 timerclear(&p->p_ru->ru_stime);
0b4e3aa0
A
1797
1798#ifdef FIXME
91447636 1799 if (task) {
0b4e3aa0
A
1800 task_basic_info_data_t tinfo;
1801 task_thread_times_info_data_t ttimesinfo;
1802 int task_info_stuff, task_ttimes_stuff;
1803 struct timeval ut,st;
1804
1805 task_info_stuff = TASK_BASIC_INFO_COUNT;
1806 task_info(task, TASK_BASIC_INFO,
1807 &tinfo, &task_info_stuff);
1808 p->p_ru->ru_utime.tv_sec = tinfo.user_time.seconds;
1809 p->p_ru->ru_utime.tv_usec = tinfo.user_time.microseconds;
1810 p->p_ru->ru_stime.tv_sec = tinfo.system_time.seconds;
1811 p->p_ru->ru_stime.tv_usec = tinfo.system_time.microseconds;
1812
1813 task_ttimes_stuff = TASK_THREAD_TIMES_INFO_COUNT;
1814 task_info(task, TASK_THREAD_TIMES_INFO,
1815 &ttimesinfo, &task_ttimes_stuff);
1816
1817 ut.tv_sec = ttimesinfo.user_time.seconds;
1818 ut.tv_usec = ttimesinfo.user_time.microseconds;
1819 st.tv_sec = ttimesinfo.system_time.seconds;
1820 st.tv_usec = ttimesinfo.system_time.microseconds;
1821 timeradd(&ut,&p->p_ru->ru_utime,&p->p_ru->ru_utime);
91447636
A
1822 timeradd(&st,&p->p_ru->ru_stime,&p->p_ru->ru_stime);
1823 }
0b4e3aa0
A
1824#endif /* FIXME */
1825
91447636
A
1826 ruadd(p->p_ru, &p->p_stats->p_cru);
1827 }
0b4e3aa0
A
1828
1829 /*
1830 * Free up profiling buffers.
1831 */
1832 {
1833 struct uprof *p0 = &p->p_stats->p_prof, *p1, *pn;
1834
1835 p1 = p0->pr_next;
1836 p0->pr_next = NULL;
1837 p0->pr_scale = 0;
1838
1839 for (; p1 != NULL; p1 = pn) {
1840 pn = p1->pr_next;
91447636 1841 kfree(p1, sizeof *p1);
0b4e3aa0
A
1842 }
1843 }
1844
1845 /*
1846 * Other substructures are freed from wait().
1847 */
2d21ac55 1848 FREE_ZONE(p->p_stats, sizeof *p->p_stats, M_PSTATS);
0b4e3aa0
A
1849 p->p_stats = NULL;
1850
2d21ac55 1851 FREE_ZONE(p->p_sigacts, sizeof *p->p_sigacts, M_SIGACTS);
0b4e3aa0
A
1852 p->p_sigacts = NULL;
1853
2d21ac55 1854 proc_limitdrop(p, 1);
0b4e3aa0
A
1855 p->p_limit = NULL;
1856
1857 /*
1858 * Finish up by terminating the task
1859 * and halt this thread (only if a
1860 * member of the task exiting).
1861 */
1862 p->task = TASK_NULL;
1863
1864 /*
1865 * Notify parent that we're gone.
1866 */
2d21ac55
A
1867 pp = proc_parent(p);
1868 if ((p->p_listflag & P_LIST_DEADPARENT) == 0) {
1869 if (pp != initproc) {
1870 proc_lock(pp);
1871 pp->si_pid = p->p_pid;
1872 pp->si_status = p->p_xstat;
1873 pp->si_code = CLD_EXITED;
1874 /*
1875 * p_ucred usage is safe as it is an exiting process
1876 * and reference is dropped in reap
1877 */
1878 pp->si_uid = p->p_ucred->cr_ruid;
1879 proc_unlock(pp);
1880 }
1881 /* mark as a zombie */
1882 /* mark as a zombie */
1883 /* No need to take proc lock as all refs are drained and
1884 * no one except parent (reaping ) can look at this.
1885 * The write is to an int and is coherent. Also parent is
1886 * keyed off of list lock for reaping
1887 */
1888 p->p_stat = SZOMB;
0b4e3aa0 1889
2d21ac55 1890 psignal(pp, SIGCHLD);
91447636 1891
2d21ac55
A
1892 /* and now wakeup the parent */
1893 proc_list_lock();
1894 wakeup((caddr_t)pp);
1895 proc_list_unlock();
1896 } else {
1897 proc_list_lock();
2d21ac55
A
1898 /* check for lookups by zomb sysctl */
1899 while ((p->p_listflag & P_LIST_WAITING) == P_LIST_WAITING) {
1900 msleep(&p->p_stat, proc_list_mlock, PWAIT, "waitcoll", 0);
1901 }
d1ecb069 1902 p->p_stat = SZOMB;
2d21ac55 1903 p->p_listflag |= P_LIST_WAITING;
d1ecb069 1904
2d21ac55
A
1905 /*
1906 * This is a named reference and it is not granted
1907 * if the reap is already in progress. So we get
1908 * the reference here exclusively and their can be
1909 * no waiters. So there is no need for a wakeup
1910 * after we are done. AlsO the reap frees the structure
1911 * and the proc struct cannot be used for wakeups as well.
1912 * It is safe to use p here as this is system reap
1913 */
1914 (void)reap_child_locked(pp, p, 0, 1, 1);
1915 /* list lock dropped by reap_child_locked */
1916 }
1917 proc_rele(pp);
0b4e3aa0 1918}
91447636
A
1919
1920
1921/*
1922 * munge_rusage
1923 * LP64 support - long is 64 bits if we are dealing with a 64 bit user
b0d623f7 1924 * process. We munge the kernel version of rusage into the
91447636
A
1925 * 64 bit version.
1926 */
1927__private_extern__ void
b0d623f7 1928munge_user64_rusage(struct rusage *a_rusage_p, struct user64_rusage *a_user_rusage_p)
91447636
A
1929{
1930 /* timeval changes size, so utime and stime need special handling */
1931 a_user_rusage_p->ru_utime.tv_sec = a_rusage_p->ru_utime.tv_sec;
1932 a_user_rusage_p->ru_utime.tv_usec = a_rusage_p->ru_utime.tv_usec;
1933 a_user_rusage_p->ru_stime.tv_sec = a_rusage_p->ru_stime.tv_sec;
1934 a_user_rusage_p->ru_stime.tv_usec = a_rusage_p->ru_stime.tv_usec;
1935 /*
1936 * everything else can be a direct assign, since there is no loss
1937 * of precision implied boing 32->64.
1938 */
1939 a_user_rusage_p->ru_maxrss = a_rusage_p->ru_maxrss;
1940 a_user_rusage_p->ru_ixrss = a_rusage_p->ru_ixrss;
1941 a_user_rusage_p->ru_idrss = a_rusage_p->ru_idrss;
1942 a_user_rusage_p->ru_isrss = a_rusage_p->ru_isrss;
1943 a_user_rusage_p->ru_minflt = a_rusage_p->ru_minflt;
1944 a_user_rusage_p->ru_majflt = a_rusage_p->ru_majflt;
1945 a_user_rusage_p->ru_nswap = a_rusage_p->ru_nswap;
1946 a_user_rusage_p->ru_inblock = a_rusage_p->ru_inblock;
1947 a_user_rusage_p->ru_oublock = a_rusage_p->ru_oublock;
1948 a_user_rusage_p->ru_msgsnd = a_rusage_p->ru_msgsnd;
1949 a_user_rusage_p->ru_msgrcv = a_rusage_p->ru_msgrcv;
1950 a_user_rusage_p->ru_nsignals = a_rusage_p->ru_nsignals;
1951 a_user_rusage_p->ru_nvcsw = a_rusage_p->ru_nvcsw;
1952 a_user_rusage_p->ru_nivcsw = a_rusage_p->ru_nivcsw;
1953}
b0d623f7
A
1954
1955/* For a 64-bit kernel and 32-bit userspace, munging may be needed */
1956__private_extern__ void
1957munge_user32_rusage(struct rusage *a_rusage_p, struct user32_rusage *a_user_rusage_p)
1958{
1959 /* timeval changes size, so utime and stime need special handling */
1960 a_user_rusage_p->ru_utime.tv_sec = a_rusage_p->ru_utime.tv_sec;
1961 a_user_rusage_p->ru_utime.tv_usec = a_rusage_p->ru_utime.tv_usec;
1962 a_user_rusage_p->ru_stime.tv_sec = a_rusage_p->ru_stime.tv_sec;
1963 a_user_rusage_p->ru_stime.tv_usec = a_rusage_p->ru_stime.tv_usec;
1964 /*
1965 * everything else can be a direct assign. We currently ignore
1966 * the loss of precision
1967 */
1968 a_user_rusage_p->ru_maxrss = a_rusage_p->ru_maxrss;
1969 a_user_rusage_p->ru_ixrss = a_rusage_p->ru_ixrss;
1970 a_user_rusage_p->ru_idrss = a_rusage_p->ru_idrss;
1971 a_user_rusage_p->ru_isrss = a_rusage_p->ru_isrss;
1972 a_user_rusage_p->ru_minflt = a_rusage_p->ru_minflt;
1973 a_user_rusage_p->ru_majflt = a_rusage_p->ru_majflt;
1974 a_user_rusage_p->ru_nswap = a_rusage_p->ru_nswap;
1975 a_user_rusage_p->ru_inblock = a_rusage_p->ru_inblock;
1976 a_user_rusage_p->ru_oublock = a_rusage_p->ru_oublock;
1977 a_user_rusage_p->ru_msgsnd = a_rusage_p->ru_msgsnd;
1978 a_user_rusage_p->ru_msgrcv = a_rusage_p->ru_msgrcv;
1979 a_user_rusage_p->ru_nsignals = a_rusage_p->ru_nsignals;
1980 a_user_rusage_p->ru_nvcsw = a_rusage_p->ru_nvcsw;
1981 a_user_rusage_p->ru_nivcsw = a_rusage_p->ru_nivcsw;
1982}