]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_sig.c
xnu-1699.32.7.tar.gz
[apple/xnu.git] / bsd / kern / kern_sig.c
CommitLineData
1c79356b 1/*
2d21ac55 2 * Copyright (c) 1995-2007 Apple Inc. All rights reserved.
1c79356b 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 27 */
1c79356b
A
28/*
29 * Copyright (c) 1982, 1986, 1989, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
31 * (c) UNIX System Laboratories, Inc.
32 * All or some portions of this file are derived from material licensed
33 * to the University of California by American Telephone and Telegraph
34 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
35 * the permission of UNIX System Laboratories, Inc.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by the University of
48 * California, Berkeley and its contributors.
49 * 4. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 *
65 * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
66 */
2d21ac55
A
67/*
68 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
69 * support for mandatory and extensible security protections. This notice
70 * is included in support of clause 2.2 (b) of the Apple Public License,
71 * Version 2.0.
72 */
1c79356b
A
73
74#define SIGPROP /* include signal properties table */
75#include <sys/param.h>
1c79356b 76#include <sys/resourcevar.h>
91447636
A
77#include <sys/proc_internal.h>
78#include <sys/kauth.h>
1c79356b
A
79#include <sys/systm.h>
80#include <sys/timeb.h>
81#include <sys/times.h>
1c79356b 82#include <sys/acct.h>
91447636 83#include <sys/file_internal.h>
1c79356b
A
84#include <sys/kernel.h>
85#include <sys/wait.h>
9bccf70c 86#include <sys/signalvar.h>
1c79356b
A
87#include <sys/syslog.h>
88#include <sys/stat.h>
89#include <sys/lock.h>
9bccf70c 90#include <sys/kdebug.h>
91447636 91
1c79356b 92#include <sys/mount.h>
91447636 93#include <sys/sysproto.h>
1c79356b 94
b0d623f7 95#include <security/audit/audit.h>
e5568f75 96
91447636
A
97#include <machine/spl.h>
98
1c79356b
A
99#include <kern/cpu_number.h>
100
101#include <sys/vm.h>
102#include <sys/user.h> /* for coredump */
103#include <kern/ast.h> /* for APC support */
91447636
A
104#include <kern/lock.h>
105#include <kern/task.h> /* extern void *get_bsdtask_info(task_t); */
1c79356b 106#include <kern/thread.h>
9bccf70c 107#include <kern/sched_prim.h>
1c79356b 108#include <kern/thread_call.h>
9bccf70c 109#include <mach/exception.h>
91447636
A
110#include <mach/task.h>
111#include <mach/thread_act.h>
2d21ac55
A
112#include <libkern/OSAtomic.h>
113
114#include <sys/sdt.h>
91447636
A
115
116/*
117 * Missing prototypes that Mach should export
118 *
119 * +++
120 */
121extern int thread_enable_fpe(thread_t act, int onoff);
91447636 122extern thread_t port_name_to_thread(mach_port_name_t port_name);
91447636
A
123extern kern_return_t get_signalact(task_t , thread_t *, int);
124extern boolean_t thread_should_abort(thread_t);
125extern unsigned int get_useraddr(void);
126
127/*
128 * ---
129 */
9bccf70c 130
2d21ac55
A
131extern void doexception(int exc, mach_exception_code_t code,
132 mach_exception_subcode_t sub);
1c79356b 133
2d21ac55
A
134static void stop(proc_t, proc_t);
135int cansignal(proc_t, kauth_cred_t, proc_t, int, int);
136int killpg1(proc_t, int, int, int, int);
b0d623f7 137int setsigvec(proc_t, thread_t, int, struct __kern_sigaction *, boolean_t in_sigstart);
2d21ac55 138static void psignal_uthread(thread_t, int);
9bccf70c 139kern_return_t do_bsdexception(int, int, int);
91447636
A
140void __posix_sem_syscall_return(kern_return_t);
141
142/* implementations in osfmk/kern/sync_sema.c. We do not want port.h in this scope, so void * them */
2d21ac55
A
143kern_return_t semaphore_timedwait_signal_trap_internal(mach_port_name_t, mach_port_name_t, unsigned int, clock_res_t, void (*)(kern_return_t));
144kern_return_t semaphore_timedwait_trap_internal(mach_port_name_t, unsigned int, clock_res_t, void (*)(kern_return_t));
145kern_return_t semaphore_wait_signal_trap_internal(mach_port_name_t, mach_port_name_t, void (*)(kern_return_t));
146kern_return_t semaphore_wait_trap_internal(mach_port_name_t, void (*)(kern_return_t));
1c79356b 147
55e303ae
A
148static int filt_sigattach(struct knote *kn);
149static void filt_sigdetach(struct knote *kn);
150static int filt_signal(struct knote *kn, long hint);
b0d623f7
A
151static void filt_signaltouch(struct knote *kn, struct kevent64_s *kev,
152 long type);
153
154struct filterops sig_filtops = {
155 .f_attach = filt_sigattach,
156 .f_detach = filt_sigdetach,
157 .f_event = filt_signal,
158 .f_touch = filt_signaltouch,
159};
55e303ae 160
2d21ac55
A
161/* structures and fns for killpg1 iterartion callback and filters */
162struct killpg1_filtargs {
163 int posix;
164 proc_t cp;
165};
166
167struct killpg1_iterargs {
168 proc_t cp;
169 kauth_cred_t uc;
170 int signum;
171 int * nfoundp;
b0d623f7 172 int zombie;
2d21ac55
A
173};
174
175static int killpg1_filt(proc_t p, void * arg);
176static int killpg1_pgrpfilt(proc_t p, __unused void * arg);
177static int killpg1_callback(proc_t p, void * arg);
178
179static int pgsignal_filt(proc_t p, void * arg);
180static int pgsignal_callback(proc_t p, void * arg);
181static kern_return_t get_signalthread(proc_t, int, thread_t *);
182
183
184/* flags for psignal_internal */
185#define PSIG_LOCKED 0x1
186#define PSIG_VFORK 0x2
187#define PSIG_THREAD 0x4
188
189
190static void psignal_internal(proc_t p, task_t task, thread_t thread, int flavor, int signum);
91447636
A
191
192/*
193 * NOTE: Source and target may *NOT* overlap! (target is smaller)
194 */
195static void
b0d623f7 196sigaltstack_kern_to_user32(struct kern_sigaltstack *in, struct user32_sigaltstack *out)
91447636 197{
b0d623f7
A
198 out->ss_sp = CAST_DOWN_EXPLICIT(user32_addr_t, in->ss_sp);
199 out->ss_size = CAST_DOWN_EXPLICIT(user32_size_t, in->ss_size);
200 out->ss_flags = in->ss_flags;
201}
202
203static void
204sigaltstack_kern_to_user64(struct kern_sigaltstack *in, struct user64_sigaltstack *out)
205{
206 out->ss_sp = in->ss_sp;
91447636
A
207 out->ss_size = in->ss_size;
208 out->ss_flags = in->ss_flags;
209}
210
211/*
212 * NOTE: Source and target may are permitted to overlap! (source is smaller);
213 * this works because we copy fields in order from the end of the struct to
214 * the beginning.
215 */
216static void
b0d623f7
A
217sigaltstack_user32_to_kern(struct user32_sigaltstack *in, struct kern_sigaltstack *out)
218{
219 out->ss_flags = in->ss_flags;
220 out->ss_size = in->ss_size;
221 out->ss_sp = CAST_USER_ADDR_T(in->ss_sp);
222}
223static void
224sigaltstack_user64_to_kern(struct user64_sigaltstack *in, struct kern_sigaltstack *out)
91447636
A
225{
226 out->ss_flags = in->ss_flags;
227 out->ss_size = in->ss_size;
b0d623f7 228 out->ss_sp = in->ss_sp;
91447636
A
229}
230
231static void
b0d623f7 232sigaction_kern_to_user32(struct kern_sigaction *in, struct user32_sigaction *out)
91447636
A
233{
234 /* This assumes 32 bit __sa_handler is of type sig_t */
b0d623f7
A
235 out->__sigaction_u.__sa_handler = CAST_DOWN_EXPLICIT(user32_addr_t,in->__sigaction_u.__sa_handler);
236 out->sa_mask = in->sa_mask;
237 out->sa_flags = in->sa_flags;
238}
239static void
240sigaction_kern_to_user64(struct kern_sigaction *in, struct user64_sigaction *out)
241{
242 /* This assumes 32 bit __sa_handler is of type sig_t */
243 out->__sigaction_u.__sa_handler = in->__sigaction_u.__sa_handler;
91447636
A
244 out->sa_mask = in->sa_mask;
245 out->sa_flags = in->sa_flags;
246}
247
248static void
b0d623f7 249__sigaction_user32_to_kern(struct __user32_sigaction *in, struct __kern_sigaction *out)
91447636
A
250{
251 out->__sigaction_u.__sa_handler = CAST_USER_ADDR_T(in->__sigaction_u.__sa_handler);
252 out->sa_tramp = CAST_USER_ADDR_T(in->sa_tramp);
253 out->sa_mask = in->sa_mask;
254 out->sa_flags = in->sa_flags;
255}
256
b0d623f7
A
257static void
258__sigaction_user64_to_kern(struct __user64_sigaction *in, struct __kern_sigaction *out)
259{
260 out->__sigaction_u.__sa_handler = in->__sigaction_u.__sa_handler;
261 out->sa_tramp = in->sa_tramp;
262 out->sa_mask = in->sa_mask;
263 out->sa_flags = in->sa_flags;
264}
91447636 265
1c79356b 266#if SIGNAL_DEBUG
91447636 267void ram_printf(int);
1c79356b
A
268int ram_debug=0;
269unsigned int rdebug_proc=0;
270void
271ram_printf(int x)
272{
273 printf("x is %d",x);
274
275}
1c79356b 276#endif /* SIGNAL_DEBUG */
9bccf70c 277
1c79356b
A
278
279void
2d21ac55 280signal_setast(thread_t sig_actthread)
1c79356b 281{
9bccf70c 282 act_set_astbsd(sig_actthread);
1c79356b
A
283}
284
285/*
91447636 286 * Can process p, with ucred uc, send the signal signum to process q?
2d21ac55
A
287 * uc is refcounted by the caller so internal fileds can be used safely
288 * when called with zombie arg, list lock is held
1c79356b
A
289 */
290int
2d21ac55 291cansignal(proc_t p, kauth_cred_t uc, proc_t q, int signum, int zombie)
1c79356b 292{
2d21ac55
A
293 kauth_cred_t my_cred;
294 struct session * p_sessp = SESSION_NULL;
295 struct session * q_sessp = SESSION_NULL;
296#if CONFIG_MACF
297 int error;
298
299 error = mac_proc_check_signal(p, q, signum);
300 if (error)
301 return (0);
302#endif
303
9bccf70c
A
304 /* you can signal yourself */
305 if (p == q)
306 return(1);
307
91447636 308 if (!suser(uc, NULL))
1c79356b
A
309 return (1); /* root can always signal */
310
2d21ac55
A
311 if (zombie == 0)
312 proc_list_lock();
313 if (p->p_pgrp != PGRP_NULL)
314 p_sessp = p->p_pgrp->pg_session;
315 if (q->p_pgrp != PGRP_NULL)
316 q_sessp = q->p_pgrp->pg_session;
317
318 if (signum == SIGCONT && q_sessp == p_sessp) {
319 if (zombie == 0)
320 proc_list_unlock();
1c79356b 321 return (1); /* SIGCONT in session */
2d21ac55
A
322 }
323
324 if (zombie == 0)
325 proc_list_unlock();
1c79356b
A
326
327 /*
b0d623f7
A
328 * If the real or effective UID of the sender matches the real
329 * or saved UID of the target, permit the signal to
2d21ac55 330 * be sent.
1c79356b 331 */
2d21ac55
A
332 if (zombie == 0)
333 my_cred = kauth_cred_proc_ref(q);
334 else
335 my_cred = proc_ucred(q);
336
6d2010ae
A
337 if (kauth_cred_getruid(uc) == kauth_cred_getruid(my_cred) ||
338 kauth_cred_getruid(uc) == kauth_cred_getsvuid(my_cred) ||
339 kauth_cred_getuid(uc) == kauth_cred_getruid(my_cred) ||
340 kauth_cred_getuid(uc) == kauth_cred_getsvuid(my_cred)) {
2d21ac55
A
341 if (zombie == 0)
342 kauth_cred_unref(&my_cred);
343 return (1);
1c79356b
A
344 }
345
2d21ac55
A
346 if (zombie == 0)
347 kauth_cred_unref(&my_cred);
348
1c79356b
A
349 return (0);
350}
351
1c79356b 352
2d21ac55
A
353/*
354 * Returns: 0 Success
355 * EINVAL
356 * copyout:EFAULT
357 * copyin:EFAULT
b0d623f7
A
358 *
359 * Notes: Uses current thread as a parameter to inform PPC to enable
360 * FPU exceptions via setsigvec(); this operation is not proxy
361 * safe!
2d21ac55 362 */
1c79356b
A
363/* ARGSUSED */
364int
b0d623f7 365sigaction(proc_t p, struct sigaction_args *uap, __unused int32_t *retval)
1c79356b 366{
b0d623f7
A
367 struct kern_sigaction vec;
368 struct __kern_sigaction __vec;
9bccf70c 369
b0d623f7 370 struct kern_sigaction *sa = &vec;
2d21ac55 371 struct sigacts *ps = p->p_sigacts;
91447636 372
2d21ac55 373 int signum;
9bccf70c 374 int bit, error=0;
1c79356b
A
375
376 signum = uap->signum;
377 if (signum <= 0 || signum >= NSIG ||
378 signum == SIGKILL || signum == SIGSTOP)
379 return (EINVAL);
91447636 380
1c79356b
A
381 if (uap->osa) {
382 sa->sa_handler = ps->ps_sigact[signum];
383 sa->sa_mask = ps->ps_catchmask[signum];
384 bit = sigmask(signum);
385 sa->sa_flags = 0;
386 if ((ps->ps_sigonstack & bit) != 0)
387 sa->sa_flags |= SA_ONSTACK;
388 if ((ps->ps_sigintr & bit) == 0)
389 sa->sa_flags |= SA_RESTART;
9bccf70c
A
390 if (ps->ps_siginfo & bit)
391 sa->sa_flags |= SA_SIGINFO;
392 if (ps->ps_signodefer & bit)
393 sa->sa_flags |= SA_NODEFER;
55e303ae
A
394 if (ps->ps_64regset & bit)
395 sa->sa_flags |= SA_64REGSET;
9bccf70c 396 if ((signum == SIGCHLD) && (p->p_flag & P_NOCLDSTOP))
1c79356b 397 sa->sa_flags |= SA_NOCLDSTOP;
9bccf70c
A
398 if ((signum == SIGCHLD) && (p->p_flag & P_NOCLDWAIT))
399 sa->sa_flags |= SA_NOCLDWAIT;
91447636
A
400
401 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
402 struct user64_sigaction vec64;
403
404 sigaction_kern_to_user64(sa, &vec64);
405 error = copyout(&vec64, uap->osa, sizeof(vec64));
91447636 406 } else {
b0d623f7
A
407 struct user32_sigaction vec32;
408
409 sigaction_kern_to_user32(sa, &vec32);
410 error = copyout(&vec32, uap->osa, sizeof(vec32));
91447636
A
411 }
412 if (error)
1c79356b
A
413 return (error);
414 }
415 if (uap->nsa) {
91447636 416 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
417 struct __user64_sigaction __vec64;
418
419 error = copyin(uap->nsa, &__vec64, sizeof(__vec64));
420 __sigaction_user64_to_kern(&__vec64, &__vec);
91447636 421 } else {
b0d623f7
A
422 struct __user32_sigaction __vec32;
423
424 error = copyin(uap->nsa, &__vec32, sizeof(__vec32));
425 __sigaction_user32_to_kern(&__vec32, &__vec);
91447636
A
426 }
427 if (error)
1c79356b 428 return (error);
2d21ac55 429 __vec.sa_flags &= SA_USERSPACE_MASK; /* Only pass on valid sa_flags */
b0d623f7 430 error = setsigvec(p, current_thread(), signum, &__vec, FALSE);
1c79356b 431 }
9bccf70c
A
432 return (error);
433}
434
435/* Routines to manipulate bits on all threads */
436int
b0d623f7 437clear_procsiglist(proc_t p, int bit, boolean_t in_signalstart)
9bccf70c
A
438{
439 struct uthread * uth;
91447636 440 thread_t thact;
9bccf70c 441
2d21ac55 442 proc_lock(p);
b0d623f7
A
443 if (!in_signalstart)
444 proc_signalstart(p, 1);
9bccf70c 445
2d21ac55 446 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
9bccf70c
A
447 thact = p->p_vforkact;
448 uth = (struct uthread *)get_bsdthread_info(thact);
449 if (uth) {
450 uth->uu_siglist &= ~bit;
451 }
b0d623f7
A
452 if (!in_signalstart)
453 proc_signalend(p, 1);
2d21ac55 454 proc_unlock(p);
9bccf70c
A
455 return(0);
456 }
457
458 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
459 uth->uu_siglist &= ~bit;
460 }
b0d623f7
A
461 p->p_siglist &= ~bit;
462 if (!in_signalstart)
463 proc_signalend(p, 1);
2d21ac55
A
464 proc_unlock(p);
465
9bccf70c 466 return(0);
1c79356b
A
467}
468
91447636
A
469
470static int
2d21ac55 471unblock_procsigmask(proc_t p, int bit)
1c79356b 472{
9bccf70c 473 struct uthread * uth;
91447636 474 thread_t thact;
9bccf70c 475
2d21ac55
A
476 proc_lock(p);
477 proc_signalstart(p, 1);
478
479 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
9bccf70c
A
480 thact = p->p_vforkact;
481 uth = (struct uthread *)get_bsdthread_info(thact);
482 if (uth) {
483 uth->uu_sigmask &= ~bit;
484 }
485 p->p_sigmask &= ~bit;
2d21ac55
A
486 proc_signalend(p, 1);
487 proc_unlock(p);
9bccf70c
A
488 return(0);
489 }
490 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
491 uth->uu_sigmask &= ~bit;
1c79356b 492 }
9bccf70c 493 p->p_sigmask &= ~bit;
2d21ac55
A
494
495 proc_signalend(p, 1);
496 proc_unlock(p);
9bccf70c 497 return(0);
1c79356b
A
498}
499
91447636 500static int
2d21ac55 501block_procsigmask(proc_t p, int bit)
1c79356b 502{
9bccf70c 503 struct uthread * uth;
91447636 504 thread_t thact;
1c79356b 505
2d21ac55
A
506 proc_lock(p);
507 proc_signalstart(p, 1);
508
509 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
9bccf70c
A
510 thact = p->p_vforkact;
511 uth = (struct uthread *)get_bsdthread_info(thact);
512 if (uth) {
513 uth->uu_sigmask |= bit;
514 }
515 p->p_sigmask |= bit;
2d21ac55
A
516 proc_signalend(p, 1);
517 proc_unlock(p);
9bccf70c
A
518 return(0);
519 }
520 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
521 uth->uu_sigmask |= bit;
522 }
523 p->p_sigmask |= bit;
2d21ac55
A
524
525 proc_signalend(p, 1);
526 proc_unlock(p);
1c79356b
A
527 return(0);
528}
91447636 529
9bccf70c 530int
2d21ac55 531set_procsigmask(proc_t p, int bit)
9bccf70c
A
532{
533 struct uthread * uth;
91447636 534 thread_t thact;
1c79356b 535
2d21ac55
A
536 proc_lock(p);
537 proc_signalstart(p, 1);
538
539 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
9bccf70c
A
540 thact = p->p_vforkact;
541 uth = (struct uthread *)get_bsdthread_info(thact);
542 if (uth) {
543 uth->uu_sigmask = bit;
544 }
545 p->p_sigmask = bit;
2d21ac55
A
546 proc_signalend(p, 1);
547 proc_unlock(p);
9bccf70c
A
548 return(0);
549 }
550 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
551 uth->uu_sigmask = bit;
552 }
553 p->p_sigmask = bit;
2d21ac55
A
554 proc_signalend(p, 1);
555 proc_unlock(p);
556
9bccf70c
A
557 return(0);
558}
1c79356b 559
91447636 560/* XXX should be static? */
b0d623f7
A
561/*
562 * Notes: The thread parameter is used in the PPC case to select the
563 * thread on which the floating point exception will be enabled
564 * or disabled. We can't simply take current_thread(), since
565 * this is called from posix_spawn() on the not currently running
566 * process/thread pair.
567 *
568 * We mark thread as unused to alow compilation without warning
6d2010ae 569 * on non-PPC platforms.
b0d623f7 570 */
9bccf70c 571int
b0d623f7 572setsigvec(proc_t p, __unused thread_t thread, int signum, struct __kern_sigaction *sa, boolean_t in_sigstart)
1c79356b 573{
2d21ac55
A
574 struct sigacts *ps = p->p_sigacts;
575 int bit;
1c79356b 576
9bccf70c
A
577 if ((signum == SIGKILL || signum == SIGSTOP) &&
578 sa->sa_handler != SIG_DFL)
579 return(EINVAL);
1c79356b
A
580 bit = sigmask(signum);
581 /*
582 * Change setting atomically.
583 */
584 ps->ps_sigact[signum] = sa->sa_handler;
91447636 585 ps->ps_trampact[signum] = sa->sa_tramp;
1c79356b 586 ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
9bccf70c
A
587 if (sa->sa_flags & SA_SIGINFO)
588 ps->ps_siginfo |= bit;
589 else
590 ps->ps_siginfo &= ~bit;
55e303ae
A
591 if (sa->sa_flags & SA_64REGSET)
592 ps->ps_64regset |= bit;
593 else
594 ps->ps_64regset &= ~bit;
1c79356b
A
595 if ((sa->sa_flags & SA_RESTART) == 0)
596 ps->ps_sigintr |= bit;
597 else
598 ps->ps_sigintr &= ~bit;
599 if (sa->sa_flags & SA_ONSTACK)
600 ps->ps_sigonstack |= bit;
601 else
602 ps->ps_sigonstack &= ~bit;
603 if (sa->sa_flags & SA_USERTRAMP)
604 ps->ps_usertramp |= bit;
605 else
606 ps->ps_usertramp &= ~bit;
9bccf70c
A
607 if (sa->sa_flags & SA_RESETHAND)
608 ps->ps_sigreset |= bit;
609 else
610 ps->ps_sigreset &= ~bit;
611 if (sa->sa_flags & SA_NODEFER)
612 ps->ps_signodefer |= bit;
613 else
614 ps->ps_signodefer &= ~bit;
1c79356b
A
615 if (signum == SIGCHLD) {
616 if (sa->sa_flags & SA_NOCLDSTOP)
b0d623f7 617 OSBitOrAtomic(P_NOCLDSTOP, &p->p_flag);
1c79356b 618 else
b0d623f7 619 OSBitAndAtomic(~((uint32_t)P_NOCLDSTOP), &p->p_flag);
9bccf70c 620 if ((sa->sa_flags & SA_NOCLDWAIT) || (sa->sa_handler == SIG_IGN))
b0d623f7 621 OSBitOrAtomic(P_NOCLDWAIT, &p->p_flag);
9bccf70c 622 else
b0d623f7 623 OSBitAndAtomic(~((uint32_t)P_NOCLDWAIT), &p->p_flag);
1c79356b 624 }
9bccf70c 625
1c79356b
A
626 /*
627 * Set bit in p_sigignore for signals that are set to SIG_IGN,
628 * and for signals set to SIG_DFL where the default is to ignore.
629 * However, don't put SIGCONT in p_sigignore,
630 * as we have to restart the process.
631 */
632 if (sa->sa_handler == SIG_IGN ||
633 (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
1c79356b 634
b0d623f7 635 clear_procsiglist(p, bit, in_sigstart);
1c79356b
A
636 if (signum != SIGCONT)
637 p->p_sigignore |= bit; /* easier in psignal */
638 p->p_sigcatch &= ~bit;
639 } else {
640 p->p_sigignore &= ~bit;
641 if (sa->sa_handler == SIG_DFL)
642 p->p_sigcatch &= ~bit;
643 else
644 p->p_sigcatch |= bit;
645 }
9bccf70c 646 return(0);
1c79356b
A
647}
648
649/*
650 * Initialize signal state for process 0;
651 * set to ignore signals that are ignored by default.
652 */
653void
2d21ac55 654siginit(proc_t p)
1c79356b 655{
2d21ac55 656 int i;
1c79356b
A
657
658 for (i = 0; i < NSIG; i++)
659 if (sigprop[i] & SA_IGNORE && i != SIGCONT)
660 p->p_sigignore |= sigmask(i);
661}
662
663/*
664 * Reset signals for an exec of the specified process.
665 */
666void
2d21ac55 667execsigs(proc_t p, thread_t thread)
1c79356b 668{
2d21ac55
A
669 struct sigacts *ps = p->p_sigacts;
670 int nc, mask;
671 struct uthread *ut;
1c79356b 672
2d21ac55 673 ut = (struct uthread *)get_bsdthread_info(thread);
b0d623f7
A
674
675 /*
676 * transfer saved signal states from the process
677 * back to the current thread.
678 *
679 * NOTE: We do this without the process locked,
680 * because we are guaranteed to be single-threaded
681 * by this point in exec and the p_siglist is
682 * only accessed by threads inside the process.
683 */
684 ut->uu_siglist |= p->p_siglist;
685 p->p_siglist = 0;
686
1c79356b
A
687 /*
688 * Reset caught signals. Held signals remain held
689 * through p_sigmask (unless they were caught,
690 * and are now ignored by default).
691 */
692 while (p->p_sigcatch) {
693 nc = ffs((long)p->p_sigcatch);
694 mask = sigmask(nc);
695 p->p_sigcatch &= ~mask;
696 if (sigprop[nc] & SA_IGNORE) {
697 if (nc != SIGCONT)
698 p->p_sigignore |= mask;
b0d623f7 699 ut->uu_siglist &= ~mask;
1c79356b
A
700 }
701 ps->ps_sigact[nc] = SIG_DFL;
702 }
b0d623f7 703
1c79356b
A
704 /*
705 * Reset stack state to the user stack.
706 * Clear set of signals caught on the signal stack.
707 */
2d21ac55
A
708 /* thread */
709 ut->uu_sigstk.ss_flags = SA_DISABLE;
710 ut->uu_sigstk.ss_size = 0;
711 ut->uu_sigstk.ss_sp = USER_ADDR_NULL;
712 ut->uu_flag &= ~UT_ALTSTACK;
713 /* process */
0c530ab8 714 ps->ps_sigonstack = 0;
1c79356b
A
715}
716
717/*
718 * Manipulate signal mask.
719 * Note that we receive new mask, not pointer,
720 * and return old mask as return value;
721 * the library stub does the rest.
722 */
1c79356b 723int
b0d623f7 724sigprocmask(proc_t p, struct sigprocmask_args *uap, __unused int32_t *retval)
1c79356b
A
725{
726 int error = 0;
9bccf70c 727 sigset_t oldmask, nmask;
91447636 728 user_addr_t omask = uap->omask;
9bccf70c 729 struct uthread *ut;
1c79356b 730
91447636 731 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
732 oldmask = ut->uu_sigmask;
733
91447636 734 if (uap->mask == USER_ADDR_NULL) {
9bccf70c
A
735 /* just want old mask */
736 goto out;
737 }
91447636 738 error = copyin(uap->mask, &nmask, sizeof(sigset_t));
9bccf70c
A
739 if (error)
740 goto out;
1c79356b
A
741
742 switch (uap->how) {
743 case SIG_BLOCK:
9bccf70c 744 block_procsigmask(p, (nmask & ~sigcantmask));
91447636 745 signal_setast(current_thread());
1c79356b
A
746 break;
747
748 case SIG_UNBLOCK:
9bccf70c 749 unblock_procsigmask(p, (nmask & ~sigcantmask));
91447636 750 signal_setast(current_thread());
1c79356b
A
751 break;
752
753 case SIG_SETMASK:
9bccf70c 754 set_procsigmask(p, (nmask & ~sigcantmask));
91447636 755 signal_setast(current_thread());
1c79356b
A
756 break;
757
758 default:
759 error = EINVAL;
760 break;
761 }
9bccf70c 762out:
91447636 763 if (!error && omask != USER_ADDR_NULL)
9bccf70c 764 copyout(&oldmask, omask, sizeof(sigset_t));
1c79356b
A
765 return (error);
766}
767
1c79356b 768int
b0d623f7 769sigpending(__unused proc_t p, struct sigpending_args *uap, __unused int32_t *retval)
1c79356b 770{
9bccf70c
A
771 struct uthread *ut;
772 sigset_t pendlist;
1c79356b 773
91447636 774 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
775 pendlist = ut->uu_siglist;
776
777 if (uap->osv)
778 copyout(&pendlist, uap->osv, sizeof(sigset_t));
779 return(0);
1c79356b
A
780}
781
1c79356b
A
782/*
783 * Suspend process until signal, providing mask to be set
784 * in the meantime. Note nonstandard calling convention:
785 * libc stub passes mask, not pointer, to save a copyin.
786 */
787
91447636
A
788static int
789sigcontinue(__unused int error)
1c79356b 790{
91447636 791// struct uthread *ut = get_bsdthread_info(current_thread());
2d21ac55
A
792 unix_syscall_return(EINTR);
793}
794
795int
b0d623f7 796sigsuspend(proc_t p, struct sigsuspend_args *uap, int32_t *retval)
2d21ac55
A
797{
798 __pthread_testcancel(1);
799 return(sigsuspend_nocancel(p, (struct sigsuspend_nocancel_args *)uap, retval));
1c79356b
A
800}
801
1c79356b 802int
b0d623f7 803sigsuspend_nocancel(proc_t p, struct sigsuspend_nocancel_args *uap, __unused int32_t *retval)
1c79356b 804{
9bccf70c
A
805 struct uthread *ut;
806
91447636 807 ut = (struct uthread *)get_bsdthread_info(current_thread());
1c79356b
A
808
809 /*
810 * When returning from sigpause, we want
811 * the old mask to be restored after the
812 * signal handler has finished. Thus, we
813 * save it here and mark the sigacts structure
814 * to indicate this.
815 */
9bccf70c 816 ut->uu_oldmask = ut->uu_sigmask;
91447636 817 ut->uu_flag |= UT_SAS_OLDMASK;
9bccf70c 818 ut->uu_sigmask = (uap->mask & ~sigcantmask);
1c79356b
A
819 (void) tsleep0((caddr_t) p, PPAUSE|PCATCH, "pause", 0, sigcontinue);
820 /* always return EINTR rather than ERESTART... */
821 return (EINTR);
822}
823
9bccf70c
A
824
825int
2d21ac55
A
826__disable_threadsignal(__unused proc_t p,
827 __unused struct __disable_threadsignal_args *uap,
b0d623f7 828 __unused int32_t *retval)
9bccf70c
A
829{
830 struct uthread *uth;
831
91447636 832 uth = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
833
834 /* No longer valid to have any signal delivered */
2d21ac55 835 uth->uu_flag |= (UT_NO_SIGMASK | UT_CANCELDISABLE);
9bccf70c
A
836
837 return(0);
838
839}
840
2d21ac55
A
841void
842__pthread_testcancel(int presyscall)
843{
844
845 thread_t self = current_thread();
846 struct uthread * uthread;
847
848 uthread = (struct uthread *)get_bsdthread_info(self);
849
850
851 uthread->uu_flag &= ~UT_NOTCANCELPT;
852
853 if ((uthread->uu_flag & (UT_CANCELDISABLE | UT_CANCEL | UT_CANCELED)) == UT_CANCEL) {
854 if(presyscall != 0) {
855 unix_syscall_return(EINTR);
856 /* NOTREACHED */
857 } else
858 thread_abort_safely(self);
859 }
860}
861
862
9bccf70c 863
91447636 864int
2d21ac55 865__pthread_markcancel(__unused proc_t p,
b0d623f7 866 struct __pthread_markcancel_args *uap, __unused int32_t *retval)
9bccf70c
A
867{
868 thread_act_t target_act;
869 int error = 0;
9bccf70c
A
870 struct uthread *uth;
871
91447636 872 target_act = (thread_act_t)port_name_to_thread(uap->thread_port);
9bccf70c
A
873
874 if (target_act == THR_ACT_NULL)
875 return (ESRCH);
91447636
A
876
877 uth = (struct uthread *)get_bsdthread_info(target_act);
878
879 /* if the thread is in vfork do not cancel */
2d21ac55 880 if ((uth->uu_flag & (UT_VFORK | UT_CANCEL | UT_CANCELED )) == 0) {
91447636
A
881 uth->uu_flag |= (UT_CANCEL | UT_NO_SIGMASK);
882 if (((uth->uu_flag & UT_NOTCANCELPT) == 0)
883 && ((uth->uu_flag & UT_CANCELDISABLE) == 0))
884 thread_abort_safely(target_act);
885 }
886
887 thread_deallocate(target_act);
888 return (error);
889}
890
891/* if action =0 ; return the cancellation state ,
892 * if marked for cancellation, make the thread canceled
893 * if action = 1 ; Enable the cancel handling
894 * if action = 2; Disable the cancel handling
895 */
896int
2d21ac55 897__pthread_canceled(__unused proc_t p,
b0d623f7 898 struct __pthread_canceled_args *uap, __unused int32_t *retval)
91447636 899{
2d21ac55 900 thread_act_t thread;
91447636
A
901 struct uthread *uth;
902 int action = uap->action;
903
2d21ac55
A
904 thread = current_thread();
905 uth = (struct uthread *)get_bsdthread_info(thread);
91447636
A
906
907 switch (action) {
908 case 1:
909 uth->uu_flag &= ~UT_CANCELDISABLE;
910 return(0);
911 case 2:
912 uth->uu_flag |= UT_CANCELDISABLE;
913 return(0);
914 case 0:
915 default:
916 /* if the thread is in vfork do not cancel */
917 if((uth->uu_flag & ( UT_CANCELDISABLE | UT_CANCEL | UT_CANCELED)) == UT_CANCEL) {
918 uth->uu_flag &= ~UT_CANCEL;
919 uth->uu_flag |= (UT_CANCELED | UT_NO_SIGMASK);
920 return(0);
921 }
922 return(EINVAL);
923 }
924 return(EINVAL);
925}
926
927void
928__posix_sem_syscall_return(kern_return_t kern_result)
929{
930 int error = 0;
931
932 if (kern_result == KERN_SUCCESS)
933 error = 0;
934 else if (kern_result == KERN_ABORTED)
935 error = EINTR;
936 else if (kern_result == KERN_OPERATION_TIMED_OUT)
937 error = ETIMEDOUT;
938 else
939 error = EINVAL;
940 unix_syscall_return(error);
941 /* does not return */
942}
943
b0d623f7 944#if OLD_SEMWAIT_SIGNAL
2d21ac55
A
945/*
946 * Returns: 0 Success
947 * EINTR
948 * ETIMEDOUT
949 * EINVAL
b0d623f7 950 * EFAULT if timespec is NULL
2d21ac55
A
951 */
952int
b0d623f7
A
953__old_semwait_signal(proc_t p, struct __old_semwait_signal_args *uap,
954 int32_t *retval)
2d21ac55
A
955{
956 __pthread_testcancel(0);
b0d623f7 957 return(__old_semwait_signal_nocancel(p, (struct __old_semwait_signal_nocancel_args *)uap, retval));
2d21ac55 958}
91447636
A
959
960int
b0d623f7
A
961__old_semwait_signal_nocancel(proc_t p, struct __old_semwait_signal_nocancel_args *uap,
962 __unused int32_t *retval)
91447636 963{
b0d623f7 964
91447636 965 kern_return_t kern_result;
b0d623f7 966 int error;
91447636
A
967 mach_timespec_t then;
968 struct timespec now;
b0d623f7
A
969 struct user_timespec ts;
970 boolean_t truncated_timeout = FALSE;
971
91447636 972 if(uap->timeout) {
b0d623f7
A
973
974 if (IS_64BIT_PROCESS(p)) {
975 struct user64_timespec ts64;
976 error = copyin(uap->ts, &ts64, sizeof(ts64));
977 ts.tv_sec = ts64.tv_sec;
978 ts.tv_nsec = ts64.tv_nsec;
979 } else {
980 struct user32_timespec ts32;
981 error = copyin(uap->ts, &ts32, sizeof(ts32));
982 ts.tv_sec = ts32.tv_sec;
983 ts.tv_nsec = ts32.tv_nsec;
984 }
985
986 if (error) {
987 return error;
988 }
989
990 if ((ts.tv_sec & 0xFFFFFFFF00000000ULL) != 0) {
991 ts.tv_sec = 0xFFFFFFFF;
992 ts.tv_nsec = 0;
993 truncated_timeout = TRUE;
994 }
995
91447636 996 if (uap->relative) {
b0d623f7
A
997 then.tv_sec = ts.tv_sec;
998 then.tv_nsec = ts.tv_nsec;
91447636
A
999 } else {
1000 nanotime(&now);
b0d623f7 1001
2d21ac55 1002 /* if time has elapsed, set time to null timepsec to bailout rightaway */
b0d623f7
A
1003 if (now.tv_sec == ts.tv_sec ?
1004 now.tv_nsec > ts.tv_nsec :
1005 now.tv_sec > ts.tv_sec) {
2d21ac55
A
1006 then.tv_sec = 0;
1007 then.tv_nsec = 0;
b0d623f7
A
1008 } else {
1009 then.tv_sec = ts.tv_sec - now.tv_sec;
1010 then.tv_nsec = ts.tv_nsec - now.tv_nsec;
1011 if (then.tv_nsec < 0) {
1012 then.tv_nsec += NSEC_PER_SEC;
1013 then.tv_sec--;
1014 }
2d21ac55 1015 }
91447636 1016 }
b0d623f7 1017
2d21ac55
A
1018 if (uap->mutex_sem == 0)
1019 kern_result = semaphore_timedwait_trap_internal((mach_port_name_t)uap->cond_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
91447636
A
1020 else
1021 kern_result = semaphore_timedwait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
b0d623f7 1022
91447636 1023 } else {
b0d623f7 1024
2d21ac55 1025 if (uap->mutex_sem == 0)
91447636
A
1026 kern_result = semaphore_wait_trap_internal(uap->cond_sem, __posix_sem_syscall_return);
1027 else
b0d623f7 1028
91447636
A
1029 kern_result = semaphore_wait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, __posix_sem_syscall_return);
1030 }
b0d623f7
A
1031
1032 if (kern_result == KERN_SUCCESS && !truncated_timeout)
91447636 1033 return(0);
b0d623f7
A
1034 else if (kern_result == KERN_SUCCESS && truncated_timeout)
1035 return(EINTR); /* simulate an exceptional condition because Mach doesn't support a longer timeout */
1036 else if (kern_result == KERN_ABORTED)
1037 return(EINTR);
1038 else if (kern_result == KERN_OPERATION_TIMED_OUT)
1039 return(ETIMEDOUT);
1040 else
1041 return(EINVAL);
1042}
1043#endif /* OLD_SEMWAIT_SIGNAL*/
1044
1045/*
1046 * Returns: 0 Success
1047 * EINTR
1048 * ETIMEDOUT
1049 * EINVAL
1050 * EFAULT if timespec is NULL
1051 */
1052int
1053__semwait_signal(proc_t p, struct __semwait_signal_args *uap,
1054 int32_t *retval)
1055{
1056 __pthread_testcancel(0);
1057 return(__semwait_signal_nocancel(p, (struct __semwait_signal_nocancel_args *)uap, retval));
1058}
1059
1060int
1061__semwait_signal_nocancel(__unused proc_t p, struct __semwait_signal_nocancel_args *uap,
1062 __unused int32_t *retval)
1063{
1064
1065 kern_return_t kern_result;
1066 mach_timespec_t then;
1067 struct timespec now;
1068 struct user_timespec ts;
1069 boolean_t truncated_timeout = FALSE;
1070
1071 if(uap->timeout) {
1072
1073 ts.tv_sec = uap->tv_sec;
1074 ts.tv_nsec = uap->tv_nsec;
1075
1076 if ((ts.tv_sec & 0xFFFFFFFF00000000ULL) != 0) {
1077 ts.tv_sec = 0xFFFFFFFF;
1078 ts.tv_nsec = 0;
1079 truncated_timeout = TRUE;
1080 }
1081
1082 if (uap->relative) {
1083 then.tv_sec = ts.tv_sec;
1084 then.tv_nsec = ts.tv_nsec;
1085 } else {
1086 nanotime(&now);
1087
1088 /* if time has elapsed, set time to null timepsec to bailout rightaway */
1089 if (now.tv_sec == ts.tv_sec ?
1090 now.tv_nsec > ts.tv_nsec :
1091 now.tv_sec > ts.tv_sec) {
1092 then.tv_sec = 0;
1093 then.tv_nsec = 0;
1094 } else {
1095 then.tv_sec = ts.tv_sec - now.tv_sec;
1096 then.tv_nsec = ts.tv_nsec - now.tv_nsec;
1097 if (then.tv_nsec < 0) {
1098 then.tv_nsec += NSEC_PER_SEC;
1099 then.tv_sec--;
1100 }
1101 }
1102 }
1103
1104 if (uap->mutex_sem == 0)
1105 kern_result = semaphore_timedwait_trap_internal((mach_port_name_t)uap->cond_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
1106 else
1107 kern_result = semaphore_timedwait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
1108
1109 } else {
1110
1111 if (uap->mutex_sem == 0)
1112 kern_result = semaphore_wait_trap_internal(uap->cond_sem, __posix_sem_syscall_return);
1113 else
1114
1115 kern_result = semaphore_wait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, __posix_sem_syscall_return);
1116 }
1117
1118 if (kern_result == KERN_SUCCESS && !truncated_timeout)
1119 return(0);
1120 else if (kern_result == KERN_SUCCESS && truncated_timeout)
1121 return(EINTR); /* simulate an exceptional condition because Mach doesn't support a longer timeout */
91447636
A
1122 else if (kern_result == KERN_ABORTED)
1123 return(EINTR);
1124 else if (kern_result == KERN_OPERATION_TIMED_OUT)
1125 return(ETIMEDOUT);
1126 else
1127 return(EINVAL);
1128}
1129
b0d623f7 1130
91447636 1131int
2d21ac55 1132__pthread_kill(__unused proc_t p, struct __pthread_kill_args *uap,
b0d623f7 1133 __unused int32_t *retval)
91447636
A
1134{
1135 thread_t target_act;
1136 int error = 0;
1137 int signum = uap->sig;
1138 struct uthread *uth;
1139
1140 target_act = (thread_t)port_name_to_thread(uap->thread_port);
1141
1142 if (target_act == THREAD_NULL)
1143 return (ESRCH);
9bccf70c
A
1144 if ((u_int)signum >= NSIG) {
1145 error = EINVAL;
1146 goto out;
1147 }
1148
1149 uth = (struct uthread *)get_bsdthread_info(target_act);
55e303ae 1150
91447636 1151 if (uth->uu_flag & UT_NO_SIGMASK) {
9bccf70c
A
1152 error = ESRCH;
1153 goto out;
1154 }
1155
1156 if (signum)
1157 psignal_uthread(target_act, signum);
1158out:
91447636 1159 thread_deallocate(target_act);
9bccf70c
A
1160 return (error);
1161}
1162
1163
9bccf70c 1164int
2d21ac55 1165__pthread_sigmask(__unused proc_t p, struct __pthread_sigmask_args *uap,
b0d623f7 1166 __unused int32_t *retval)
9bccf70c 1167{
91447636
A
1168 user_addr_t set = uap->set;
1169 user_addr_t oset = uap->oset;
1170 sigset_t nset;
9bccf70c
A
1171 int error = 0;
1172 struct uthread *ut;
1173 sigset_t oldset;
1174
91447636 1175 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
1176 oldset = ut->uu_sigmask;
1177
91447636 1178 if (set == USER_ADDR_NULL) {
9bccf70c
A
1179 /* need only old mask */
1180 goto out;
1181 }
1182
91447636 1183 error = copyin(set, &nset, sizeof(sigset_t));
9bccf70c
A
1184 if (error)
1185 goto out;
1186
1187 switch (uap->how) {
1188 case SIG_BLOCK:
1189 ut->uu_sigmask |= (nset & ~sigcantmask);
1190 break;
1191
1192 case SIG_UNBLOCK:
1193 ut->uu_sigmask &= ~(nset);
91447636 1194 signal_setast(current_thread());
9bccf70c
A
1195 break;
1196
1197 case SIG_SETMASK:
1198 ut->uu_sigmask = (nset & ~sigcantmask);
91447636 1199 signal_setast(current_thread());
9bccf70c
A
1200 break;
1201
1202 default:
1203 error = EINVAL;
1204
1205 }
1206out:
91447636
A
1207 if (!error && oset != USER_ADDR_NULL)
1208 copyout(&oldset, oset, sizeof(sigset_t));
9bccf70c
A
1209
1210 return(error);
1211}
1212
2d21ac55
A
1213/*
1214 * Returns: 0 Success
1215 * EINVAL
1216 * copyin:EFAULT
1217 * copyout:EFAULT
1218 */
1219int
b0d623f7 1220__sigwait(proc_t p, struct __sigwait_args *uap, int32_t *retval)
2d21ac55
A
1221{
1222 __pthread_testcancel(1);
1223 return(__sigwait_nocancel(p, (struct __sigwait_nocancel_args *)uap, retval));
1224}
9bccf70c 1225
9bccf70c 1226int
b0d623f7 1227__sigwait_nocancel(proc_t p, struct __sigwait_nocancel_args *uap, __unused int32_t *retval)
9bccf70c 1228{
9bccf70c
A
1229 struct uthread *ut;
1230 struct uthread *uth;
9bccf70c
A
1231 int error = 0;
1232 sigset_t mask;
1233 sigset_t siglist;
1234 sigset_t sigw=0;
1235 int signum;
1236
91447636 1237 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c 1238
91447636 1239 if (uap->set == USER_ADDR_NULL)
9bccf70c
A
1240 return(EINVAL);
1241
91447636 1242 error = copyin(uap->set, &mask, sizeof(sigset_t));
9bccf70c
A
1243 if (error)
1244 return(error);
1245
1246 siglist = (mask & ~sigcantmask);
1247
1248 if (siglist == 0)
1249 return(EINVAL);
1250
2d21ac55
A
1251 proc_lock(p);
1252 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
1253 proc_unlock(p);
9bccf70c
A
1254 return(EINVAL);
1255 } else {
2d21ac55 1256 proc_signalstart(p, 1);
9bccf70c 1257 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
91447636 1258 if ( (sigw = uth->uu_siglist & siglist) ) {
9bccf70c
A
1259 break;
1260 }
1261 }
2d21ac55 1262 proc_signalend(p, 1);
9bccf70c 1263 }
2d21ac55 1264
9bccf70c
A
1265 if (sigw) {
1266 /* The signal was pending on a thread */
1267 goto sigwait1;
1268 }
1269 /*
1270 * When returning from sigwait, we want
1271 * the old mask to be restored after the
1272 * signal handler has finished. Thus, we
1273 * save it here and mark the sigacts structure
1274 * to indicate this.
1275 */
2d21ac55 1276 uth = ut; /* wait for it to be delivered to us */
9bccf70c 1277 ut->uu_oldmask = ut->uu_sigmask;
91447636 1278 ut->uu_flag |= UT_SAS_OLDMASK;
2d21ac55
A
1279 if (siglist == (sigset_t)0) {
1280 proc_unlock(p);
9bccf70c 1281 return(EINVAL);
2d21ac55 1282 }
9bccf70c
A
1283 /* SIGKILL and SIGSTOP are not maskable as well */
1284 ut->uu_sigmask = ~(siglist|sigcantmask);
1285 ut->uu_sigwait = siglist;
2d21ac55 1286
9bccf70c 1287 /* No Continuations for now */
2d21ac55 1288 error = msleep((caddr_t)&ut->uu_sigwait, &p->p_mlock, PPAUSE|PCATCH, "pause", 0);
9bccf70c 1289
b0d623f7 1290 if (error == ERESTART)
9bccf70c
A
1291 error = 0;
1292
1293 sigw = (ut->uu_sigwait & siglist);
1294 ut->uu_sigmask = ut->uu_oldmask;
1295 ut->uu_oldmask = 0;
91447636 1296 ut->uu_flag &= ~UT_SAS_OLDMASK;
9bccf70c
A
1297sigwait1:
1298 ut->uu_sigwait = 0;
1299 if (!error) {
1300 signum = ffs((unsigned int)sigw);
1301 if (!signum)
1302 panic("sigwait with no signal wakeup");
2d21ac55
A
1303 /* Clear the pending signal in the thread it was delivered */
1304 uth->uu_siglist &= ~(sigmask(signum));
b0d623f7
A
1305
1306#if CONFIG_DTRACE
1307 DTRACE_PROC2(signal__clear, int, signum, siginfo_t *, &(ut->t_dtrace_siginfo));
1308#endif
1309
2d21ac55 1310 proc_unlock(p);
91447636 1311 if (uap->sig != USER_ADDR_NULL)
9bccf70c 1312 error = copyout(&signum, uap->sig, sizeof(int));
2d21ac55
A
1313 } else
1314 proc_unlock(p);
9bccf70c
A
1315
1316 return(error);
1317
1318}
1319
1c79356b 1320int
b0d623f7 1321sigaltstack(__unused proc_t p, struct sigaltstack_args *uap, __unused int32_t *retval)
1c79356b 1322{
b0d623f7
A
1323 struct kern_sigaltstack ss;
1324 struct kern_sigaltstack *pstk;
1c79356b 1325 int error;
2d21ac55
A
1326 struct uthread *uth;
1327 int onstack;
1c79356b 1328
0c530ab8 1329 uth = (struct uthread *)get_bsdthread_info(current_thread());
0c530ab8 1330
2d21ac55
A
1331 pstk = &uth->uu_sigstk;
1332 if ((uth->uu_flag & UT_ALTSTACK) == 0)
1333 uth->uu_sigstk.ss_flags |= SA_DISABLE;
1334 onstack = pstk->ss_flags & SA_ONSTACK;
91447636
A
1335 if (uap->oss) {
1336 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
1337 struct user64_sigaltstack ss64;
1338 sigaltstack_kern_to_user64(pstk, &ss64);
1339 error = copyout(&ss64, uap->oss, sizeof(ss64));
91447636 1340 } else {
b0d623f7
A
1341 struct user32_sigaltstack ss32;
1342 sigaltstack_kern_to_user32(pstk, &ss32);
1343 error = copyout(&ss32, uap->oss, sizeof(ss32));
91447636
A
1344 }
1345 if (error)
1346 return (error);
1347 }
1348 if (uap->nss == USER_ADDR_NULL)
1c79356b 1349 return (0);
91447636 1350 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
1351 struct user64_sigaltstack ss64;
1352 error = copyin(uap->nss, &ss64, sizeof(ss64));
1353 sigaltstack_user64_to_kern(&ss64, &ss);
91447636 1354 } else {
b0d623f7
A
1355 struct user32_sigaltstack ss32;
1356 error = copyin(uap->nss, &ss32, sizeof(ss32));
1357 sigaltstack_user32_to_kern(&ss32, &ss);
91447636
A
1358 }
1359 if (error)
1c79356b 1360 return (error);
9bccf70c
A
1361 if ((ss.ss_flags & ~SA_DISABLE) != 0) {
1362 return(EINVAL);
1363 }
1364
1c79356b 1365 if (ss.ss_flags & SA_DISABLE) {
2d21ac55
A
1366 /* if we are here we are not in the signal handler ;so no need to check */
1367 if (uth->uu_sigstk.ss_flags & SA_ONSTACK)
1368 return (EINVAL);
1369 uth->uu_flag &= ~UT_ALTSTACK;
1370 uth->uu_sigstk.ss_flags = ss.ss_flags;
1c79356b
A
1371 return (0);
1372 }
2d21ac55
A
1373 if (onstack)
1374 return (EPERM);
55e303ae
A
1375/* The older stacksize was 8K, enforce that one so no compat problems */
1376#define OLDMINSIGSTKSZ 8*1024
1377 if (ss.ss_size < OLDMINSIGSTKSZ)
1c79356b 1378 return (ENOMEM);
2d21ac55
A
1379 uth->uu_flag |= UT_ALTSTACK;
1380 uth->uu_sigstk= ss;
1c79356b
A
1381 return (0);
1382}
1383
1c79356b 1384int
b0d623f7 1385kill(proc_t cp, struct kill_args *uap, __unused int32_t *retval)
1c79356b 1386{
2d21ac55 1387 proc_t p;
91447636 1388 kauth_cred_t uc = kauth_cred_get();
2d21ac55 1389 int posix = uap->posix; /* !0 if posix behaviour desired */
91447636
A
1390
1391 AUDIT_ARG(pid, uap->pid);
1392 AUDIT_ARG(signum, uap->signum);
1c79356b
A
1393
1394 if ((u_int)uap->signum >= NSIG)
1395 return (EINVAL);
1396 if (uap->pid > 0) {
1397 /* kill single process */
2d21ac55 1398 if ((p = proc_find(uap->pid)) == NULL) {
55e303ae
A
1399 if ((p = pzfind(uap->pid)) != NULL) {
1400 /*
1401 * IEEE Std 1003.1-2001: return success
1402 * when killing a zombie.
1403 */
1404 return (0);
1405 }
1c79356b 1406 return (ESRCH);
55e303ae 1407 }
e5568f75 1408 AUDIT_ARG(process, p);
2d21ac55
A
1409 if (!cansignal(cp, uc, p, uap->signum, 0)) {
1410 proc_rele(p);
ff6e181a
A
1411 return(EPERM);
1412 }
1c79356b
A
1413 if (uap->signum)
1414 psignal(p, uap->signum);
2d21ac55 1415 proc_rele(p);
1c79356b
A
1416 return (0);
1417 }
1418 switch (uap->pid) {
1419 case -1: /* broadcast signal */
2d21ac55 1420 return (killpg1(cp, uap->signum, 0, 1, posix));
1c79356b 1421 case 0: /* signal own process group */
2d21ac55 1422 return (killpg1(cp, uap->signum, 0, 0, posix));
1c79356b 1423 default: /* negative explicit process group */
2d21ac55 1424 return (killpg1(cp, uap->signum, -(uap->pid), 0, posix));
1c79356b
A
1425 }
1426 /* NOTREACHED */
1427}
1428
2d21ac55
A
1429static int
1430killpg1_filt(proc_t p, void * arg)
1431{
1432 struct killpg1_filtargs * kfargp = (struct killpg1_filtargs *)arg;
1433 proc_t cp = kfargp->cp;
1434 int posix = kfargp->posix;
1435
1436
1437 if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
1438 (!posix && p == cp))
1439 return(0);
1440 else
1441 return(1);
1442}
1443
1444
1445static int
1446killpg1_pgrpfilt(proc_t p, __unused void * arg)
1447{
1448 if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
1449 (p->p_stat == SZOMB))
1450 return(0);
1451 else
1452 return(1);
1453}
1454
1455
1456
1457static int
1458killpg1_callback(proc_t p, void * arg)
1459{
1460 struct killpg1_iterargs * kargp = (struct killpg1_iterargs *)arg;
1461 proc_t cp = kargp->cp;
1462 kauth_cred_t uc = kargp->uc; /* refcounted by the caller safe to use internal fields */
1463 int signum = kargp->signum;
1464 int * nfoundp = kargp->nfoundp;
1465 int n;
b0d623f7
A
1466 int zombie = 0;
1467 int error = 0;
2d21ac55 1468
b0d623f7
A
1469 if ((kargp->zombie != 0) && ((p->p_listflag & P_LIST_EXITED) == P_LIST_EXITED))
1470 zombie = 1;
2d21ac55 1471
b0d623f7
A
1472 if (zombie != 0) {
1473 proc_list_lock();
1474 error = cansignal(cp, uc, p, signum, zombie);
1475 proc_list_unlock();
1476
1477 if (error != 0 && nfoundp != NULL) {
1478 n = *nfoundp;
1479 *nfoundp = n+1;
1480 }
1481 } else {
1482 if (cansignal(cp, uc, p, signum, 0) == 0)
1483 return(PROC_RETURNED);
2d21ac55 1484
b0d623f7
A
1485 if (nfoundp != NULL) {
1486 n = *nfoundp;
1487 *nfoundp = n+1;
1488 }
1489 if (signum != 0)
1490 psignal(p, signum);
2d21ac55 1491 }
2d21ac55
A
1492
1493 return(PROC_RETURNED);
2d21ac55 1494}
1c79356b
A
1495
1496/*
1497 * Common code for kill process group/broadcast kill.
1498 * cp is calling process.
1499 */
1500int
2d21ac55 1501killpg1(proc_t cp, int signum, int pgid, int all, int posix)
1c79356b 1502{
2d21ac55 1503 kauth_cred_t uc;
1c79356b
A
1504 struct pgrp *pgrp;
1505 int nfound = 0;
2d21ac55
A
1506 struct killpg1_iterargs karg;
1507 struct killpg1_filtargs kfarg;
1508 int error = 0;
1c79356b 1509
2d21ac55 1510 uc = kauth_cred_proc_ref(cp);
1c79356b
A
1511 if (all) {
1512 /*
1513 * broadcast
1514 */
2d21ac55
A
1515 kfarg.posix = posix;
1516 kfarg.cp = cp;
1517
1518 karg.cp = cp;
1519 karg.uc = uc;
1520 karg.nfoundp = &nfound;
1521 karg.signum = signum;
b0d623f7 1522 karg.zombie = 1;
2d21ac55 1523
b0d623f7 1524 proc_iterate((PROC_ALLPROCLIST | PROC_ZOMBPROCLIST), killpg1_callback, &karg, killpg1_filt, (void *)&kfarg);
2d21ac55 1525
1c79356b 1526 } else {
2d21ac55 1527 if (pgid == 0) {
1c79356b
A
1528 /*
1529 * zero pgid means send to my process group.
1530 */
2d21ac55
A
1531 pgrp = proc_pgrp(cp);
1532 } else {
1c79356b 1533 pgrp = pgfind(pgid);
2d21ac55
A
1534 if (pgrp == NULL) {
1535 error = ESRCH;
1536 goto out;
1537 }
1c79356b 1538 }
2d21ac55
A
1539
1540 karg.nfoundp = &nfound;
1541 karg.uc = uc;
1542 karg.signum = signum;
1543 karg.cp = cp;
b0d623f7 1544 karg.zombie = 0;
2d21ac55
A
1545
1546
1547 /* PGRP_DROPREF drops the pgrp refernce */
1548 pgrp_iterate(pgrp, PGRP_BLOCKITERATE | PGRP_DROPREF, killpg1_callback, &karg,
1549 killpg1_pgrpfilt, NULL);
1c79356b 1550 }
2d21ac55
A
1551 error = (nfound ? 0 : (posix ? EPERM : ESRCH));
1552out:
1553 kauth_cred_unref(&uc);
1554 return (error);
1c79356b
A
1555}
1556
2d21ac55 1557
1c79356b
A
1558/*
1559 * Send a signal to a process group.
1560 */
1561void
2d21ac55 1562gsignal(int pgid, int signum)
1c79356b
A
1563{
1564 struct pgrp *pgrp;
1565
2d21ac55 1566 if (pgid && (pgrp = pgfind(pgid))) {
1c79356b 1567 pgsignal(pgrp, signum, 0);
2d21ac55
A
1568 pg_rele(pgrp);
1569 }
1c79356b
A
1570}
1571
1572/*
2d21ac55 1573 * Send a signal to a process group. If checkctty is 1,
1c79356b
A
1574 * limit to members which have a controlling terminal.
1575 */
2d21ac55
A
1576
1577static int
1578pgsignal_filt(proc_t p, void * arg)
1c79356b 1579{
b0d623f7 1580 int checkctty = *(int*)arg;
1c79356b 1581
2d21ac55
A
1582 if ((checkctty == 0) || p->p_flag & P_CONTROLT)
1583 return(1);
1584 else
1585 return(0);
1c79356b
A
1586}
1587
2d21ac55
A
1588
1589static int
1590pgsignal_callback(proc_t p, void * arg)
9bccf70c 1591{
b0d623f7 1592 int signum = *(int*)arg;
9bccf70c 1593
2d21ac55
A
1594 psignal(p, signum);
1595 return(PROC_RETURNED);
1596}
1597
1598
1599void
1600pgsignal(struct pgrp *pgrp, int signum, int checkctty)
1601{
1602 if (pgrp != PGRP_NULL) {
b0d623f7 1603 pgrp_iterate(pgrp, PGRP_BLOCKITERATE, pgsignal_callback, &signum, pgsignal_filt, &checkctty);
2d21ac55 1604 }
9bccf70c
A
1605}
1606
2d21ac55
A
1607
1608void
1609tty_pgsignal(struct tty *tp, int signum, int checkctty)
1610{
1611 struct pgrp * pg;
1612
1613 pg = tty_pgrp(tp);
1614 if (pg != PGRP_NULL) {
b0d623f7 1615 pgrp_iterate(pg, PGRP_BLOCKITERATE, pgsignal_callback, &signum, pgsignal_filt, &checkctty);
2d21ac55
A
1616 pg_rele(pg);
1617 }
1618}
1c79356b
A
1619/*
1620 * Send a signal caused by a trap to a specific thread.
1621 */
1622void
2d21ac55 1623threadsignal(thread_t sig_actthread, int signum, mach_exception_code_t code)
1c79356b 1624{
2d21ac55
A
1625 struct uthread *uth;
1626 struct task * sig_task;
1627 proc_t p;
1c79356b
A
1628 int mask;
1629
1630 if ((u_int)signum >= NSIG || signum == 0)
1631 return;
1632
1633 mask = sigmask(signum);
1634 if ((mask & threadmask) == 0)
1635 return;
1636 sig_task = get_threadtask(sig_actthread);
2d21ac55 1637 p = (proc_t)(get_bsdtask_info(sig_task));
1c79356b 1638
0b4e3aa0 1639 uth = get_bsdthread_info(sig_actthread);
91447636 1640 if (uth && (uth->uu_flag & UT_VFORK))
0b4e3aa0
A
1641 p = uth->uu_proc;
1642
2d21ac55
A
1643 proc_lock(p);
1644 if (!(p->p_lflag & P_LTRACED) && (p->p_sigignore & mask)) {
1645 proc_unlock(p);
1c79356b 1646 return;
2d21ac55 1647 }
1c79356b 1648
9bccf70c 1649 uth->uu_siglist |= mask;
1c79356b 1650 uth->uu_code = code;
2d21ac55
A
1651 proc_unlock(p);
1652
1c79356b 1653 /* mark on process as well */
1c79356b
A
1654 signal_setast(sig_actthread);
1655}
1656
2d21ac55
A
1657static kern_return_t
1658get_signalthread(proc_t p, int signum, thread_t * thr)
1c79356b 1659{
2d21ac55
A
1660 struct uthread *uth;
1661 sigset_t mask = sigmask(signum);
1662 thread_t sig_thread;
1663 struct task * sig_task = p->task;
1664 kern_return_t kret;
1665
1666 *thr = THREAD_NULL;
1667
1668 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
1669 sig_thread = p->p_vforkact;
1670 kret = check_actforsig(sig_task, sig_thread, 1);
1671 if (kret == KERN_SUCCESS) {
1672 *thr = sig_thread;
1673 return(KERN_SUCCESS);
1674 }else
1675 return(KERN_FAILURE);
1676 }
1677
1678 proc_lock(p);
1679 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
1680 if(((uth->uu_flag & UT_NO_SIGMASK)== 0) &&
1681 (((uth->uu_sigmask & mask) == 0) || (uth->uu_sigwait & mask))) {
1682 if (check_actforsig(p->task, uth->uu_context.vc_thread, 1) == KERN_SUCCESS) {
1683 *thr = uth->uu_context.vc_thread;
1684 proc_unlock(p);
1685 return(KERN_SUCCESS);
1686 }
1687 }
1688 }
1689 proc_unlock(p);
1690 if (get_signalact(p->task, thr, 1) == KERN_SUCCESS) {
1691 return(KERN_SUCCESS);
1692 }
1693
1694 return(KERN_FAILURE);
1c79356b
A
1695}
1696
2d21ac55
A
1697/*
1698 * Send the signal to the process. If the signal has an action, the action
1699 * is usually performed by the target process rather than the caller; we add
1700 * the signal to the set of pending signals for the process.
1701 *
1702 * Exceptions:
1703 * o When a stop signal is sent to a sleeping process that takes the
1704 * default action, the process is stopped without awakening it.
1705 * o SIGCONT restarts stopped processes (or puts them back to sleep)
1706 * regardless of the signal action (eg, blocked or ignored).
1707 *
1708 * Other ignored signals are discarded immediately.
1709 */
1710static void
1711psignal_internal(proc_t p, task_t task, thread_t thread, int flavor, int signum)
0b4e3aa0 1712{
2d21ac55
A
1713 int prop;
1714 sig_t action = NULL;
1715 proc_t sig_proc;
1716 thread_t sig_thread;
1717 register task_t sig_task;
0b4e3aa0 1718 int mask;
9bccf70c 1719 struct uthread *uth;
2d21ac55
A
1720 kern_return_t kret;
1721 uid_t r_uid;
1722 proc_t pp;
1723 kauth_cred_t my_cred;
0b4e3aa0
A
1724
1725 if ((u_int)signum >= NSIG || signum == 0)
1726 panic("psignal signal number");
1727 mask = sigmask(signum);
1728 prop = sigprop[signum];
1729
1730#if SIGNAL_DEBUG
2d21ac55 1731 if(rdebug_proc && (p != PROC_NULL) && (p == rdebug_proc)) {
0b4e3aa0
A
1732 ram_printf(3);
1733 }
1734#endif /* SIGNAL_DEBUG */
1735
1c79356b
A
1736 /*
1737 * We will need the task pointer later. Grab it now to
1738 * check for a zombie process. Also don't send signals
1739 * to kernel internal tasks.
1740 */
2d21ac55
A
1741 if (flavor & PSIG_VFORK) {
1742 sig_task = task;
1743 sig_thread = thread;
6d2010ae 1744 sig_proc = p;
2d21ac55
A
1745 } else if (flavor & PSIG_THREAD) {
1746 sig_task = get_threadtask(thread);
1747 sig_thread = thread;
1748 sig_proc = (proc_t)get_bsdtask_info(sig_task);
1749 } else {
1750 sig_task = p->task;
2d21ac55 1751 sig_thread = (struct thread *)0;
6d2010ae 1752 sig_proc = p;
2d21ac55 1753 }
6d2010ae
A
1754
1755 if ((sig_task == TASK_NULL) || is_kerneltask(sig_task))
1c79356b
A
1756 return;
1757
1758 /*
1759 * do not send signals to the process that has the thread
1760 * doing a reboot(). Not doing so will mark that thread aborted
6d2010ae
A
1761 * and can cause IO failures wich will cause data loss. There's
1762 * also no need to send a signal to a process that is in the middle
1763 * of being torn down.
1c79356b 1764 */
6d2010ae
A
1765 if (ISSET(sig_proc->p_flag, P_REBOOT) ||
1766 ISSET(sig_proc->p_lflag, P_LEXIT))
1c79356b
A
1767 return;
1768
2d21ac55
A
1769 if( (flavor & (PSIG_VFORK | PSIG_THREAD)) == 0) {
1770 proc_knote(sig_proc, NOTE_SIGNAL | signum);
1771 }
1772
2d21ac55
A
1773 if ((flavor & PSIG_LOCKED)== 0)
1774 proc_signalstart(sig_proc, 0);
9bccf70c
A
1775
1776 /*
1777 * Deliver the signal to the first thread in the task. This
1778 * allows single threaded applications which use signals to
1779 * be able to be linked with multithreaded libraries. We have
55e303ae 1780 * an implicit reference to the current thread, but need
9bccf70c
A
1781 * an explicit one otherwise. The thread reference keeps
1782 * the corresponding task data structures around too. This
1783 * reference is released by thread_deallocate.
1c79356b 1784 */
9bccf70c 1785
9bccf70c 1786
2d21ac55
A
1787 if (((flavor & PSIG_VFORK) == 0) && ((sig_proc->p_lflag & P_LTRACED) == 0) && (sig_proc->p_sigignore & mask)) {
1788 DTRACE_PROC3(signal__discard, thread_t, sig_thread, proc_t, sig_proc, int, signum);
1789 goto psigout;
1790 }
9bccf70c 1791
2d21ac55
A
1792 if (flavor & PSIG_VFORK) {
1793 action = SIG_DFL;
1794 act_set_astbsd(sig_thread);
1795 kret = KERN_SUCCESS;
1796 } else if (flavor & PSIG_THREAD) {
1797 /* If successful return with ast set */
1798 kret = check_actforsig(sig_task, sig_thread, 1);
1799 } else {
1800 /* If successful return with ast set */
1801 kret = get_signalthread(sig_proc, signum, &sig_thread);
1802 }
1803 if (kret != KERN_SUCCESS) {
9bccf70c
A
1804#if SIGNAL_DEBUG
1805 ram_printf(1);
1806#endif /* SIGNAL_DEBUG */
1807 goto psigout;
1c79356b
A
1808 }
1809
2d21ac55
A
1810
1811 uth = get_bsdthread_info(sig_thread);
1c79356b
A
1812
1813 /*
1814 * If proc is traced, always give parent a chance.
1815 */
2d21ac55
A
1816
1817 if ((flavor & PSIG_VFORK) == 0) {
1818 if (sig_proc->p_lflag & P_LTRACED)
1c79356b 1819 action = SIG_DFL;
2d21ac55
A
1820 else {
1821 /*
1822 * If the signal is being ignored,
1823 * then we forget about it immediately.
1824 * (Note: we don't set SIGCONT in p_sigignore,
1825 * and if it is set to SIG_IGN,
1826 * action will be SIG_DFL here.)
1827 */
1828 if (sig_proc->p_sigignore & mask)
1829 goto psigout;
1830 if (uth->uu_sigwait & mask)
1831 action = KERN_SIG_WAIT;
1832 else if (uth->uu_sigmask & mask)
1833 action = KERN_SIG_HOLD;
1834 else if (sig_proc->p_sigcatch & mask)
1835 action = KERN_SIG_CATCH;
1836 else
1837 action = SIG_DFL;
1838 }
1c79356b
A
1839 }
1840
1c79356b 1841
2d21ac55
A
1842 proc_lock(sig_proc);
1843
1844 if (sig_proc->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) &&
1845 (sig_proc->p_lflag & P_LTRACED) == 0)
1846 sig_proc->p_nice = NZERO;
1847
1848 if (prop & SA_CONT)
9bccf70c 1849 uth->uu_siglist &= ~stopsigmask;
1c79356b
A
1850
1851 if (prop & SA_STOP) {
2d21ac55 1852 struct pgrp *pg;
1c79356b
A
1853 /*
1854 * If sending a tty stop signal to a member of an orphaned
1855 * process group, discard the signal here if the action
1856 * is default; don't stop the process below if sleeping,
1857 * and don't clear any pending SIGCONT.
1858 */
2d21ac55
A
1859 proc_unlock(sig_proc);
1860 pg = proc_pgrp(sig_proc);
1861 if (prop & SA_TTYSTOP && pg->pg_jobc == 0 &&
1862 action == SIG_DFL) {
1863 pg_rele(pg);
1c79356b 1864 goto psigout;
2d21ac55
A
1865 }
1866 pg_rele(pg);
1867 proc_lock(sig_proc);
9bccf70c 1868 uth->uu_siglist &= ~contsigmask;
1c79356b 1869 }
2d21ac55 1870
9bccf70c 1871 uth->uu_siglist |= mask;
2d21ac55
A
1872 /*
1873 * Repost AST incase sigthread has processed
1874 * ast and missed signal post.
1875 */
1876 if (action == KERN_SIG_CATCH)
1877 act_set_astbsd(sig_thread);
1c79356b 1878
9bccf70c 1879
1c79356b
A
1880 /*
1881 * Defer further processing for signals which are held,
1882 * except that stopped processes must be continued by SIGCONT.
1883 */
2d21ac55
A
1884 /* vfork will not go thru as action is SIG_DFL */
1885 if ((action == KERN_SIG_HOLD) && ((prop & SA_CONT) == 0 || sig_proc->p_stat != SSTOP)) {
1886 proc_unlock(sig_proc);
1c79356b 1887 goto psigout;
9bccf70c
A
1888 }
1889 /*
1890 * SIGKILL priority twiddling moved here from above because
1891 * it needs sig_thread. Could merge it into large switch
1892 * below if we didn't care about priority for tracing
1893 * as SIGKILL's action is always SIG_DFL.
1894 */
2d21ac55
A
1895 if ((signum == SIGKILL) && (sig_proc->p_nice > NZERO)) {
1896 sig_proc->p_nice = NZERO;
9bccf70c
A
1897 }
1898
1899 /*
1900 * Process is traced - wake it up (if not already
1901 * stopped) so that it can discover the signal in
1902 * issig() and stop for the parent.
1903 */
2d21ac55
A
1904 if (sig_proc->p_lflag & P_LTRACED) {
1905 if (sig_proc->p_stat != SSTOP)
1906 goto runlocked;
1907 else {
1908 proc_unlock(sig_proc);
9bccf70c 1909 goto psigout;
2d21ac55 1910 }
9bccf70c 1911 }
2d21ac55
A
1912 if ((flavor & PSIG_VFORK) != 0)
1913 goto runlocked;
9bccf70c 1914
91447636 1915 if (action == KERN_SIG_WAIT) {
b0d623f7
A
1916#if CONFIG_DTRACE
1917 /*
1918 * DTrace proc signal-clear returns a siginfo_t. Collect the needed info.
1919 */
1920 r_uid = kauth_getruid(); /* per thread credential; protected by our thread context */
1921
1922 bzero((caddr_t)&(uth->t_dtrace_siginfo), sizeof(uth->t_dtrace_siginfo));
1923
1924 uth->t_dtrace_siginfo.si_signo = signum;
1925 uth->t_dtrace_siginfo.si_pid = current_proc()->p_pid;
1926 uth->t_dtrace_siginfo.si_status = W_EXITCODE(signum, 0);
1927 uth->t_dtrace_siginfo.si_uid = r_uid;
1928 uth->t_dtrace_siginfo.si_code = 0;
1929#endif
9bccf70c
A
1930 uth->uu_sigwait = mask;
1931 uth->uu_siglist &= ~mask;
9bccf70c
A
1932 wakeup(&uth->uu_sigwait);
1933 /* if it is SIGCONT resume whole process */
91447636 1934 if (prop & SA_CONT) {
b0d623f7 1935 OSBitOrAtomic(P_CONTINUED, &sig_proc->p_flag);
2d21ac55
A
1936 sig_proc->p_contproc = current_proc()->p_pid;
1937
1938 proc_unlock(sig_proc);
9bccf70c 1939 (void) task_resume(sig_task);
2d21ac55 1940 goto psigout;
91447636 1941 }
2d21ac55 1942 proc_unlock(sig_proc);
9bccf70c
A
1943 goto psigout;
1944 }
1945
1946 if (action != SIG_DFL) {
1947 /*
1948 * User wants to catch the signal.
1949 * Wake up the thread, but don't un-suspend it
1950 * (except for SIGCONT).
1951 */
55e303ae 1952 if (prop & SA_CONT) {
b0d623f7 1953 OSBitOrAtomic(P_CONTINUED, &sig_proc->p_flag);
2d21ac55
A
1954 proc_unlock(sig_proc);
1955 (void) task_resume(sig_task);
1956 proc_lock(sig_proc);
1957 sig_proc->p_stat = SRUN;
1958 } else if (sig_proc->p_stat == SSTOP) {
1959 proc_unlock(sig_proc);
9bccf70c 1960 goto psigout;
9bccf70c 1961 }
9bccf70c 1962 /*
2d21ac55
A
1963 * Fill out siginfo structure information to pass to the
1964 * signalled process/thread sigaction handler, when it
1965 * wakes up. si_code is 0 because this is an ordinary
1966 * signal, not a SIGCHLD, and so si_status is the signal
1967 * number itself, instead of the child process exit status.
1968 * We shift this left because it will be shifted right before
1969 * it is passed to user space. kind of ugly to use W_EXITCODE
1970 * this way, but it beats defining a new macro.
1971 *
1972 * Note: Avoid the SIGCHLD recursion case!
9bccf70c 1973 */
2d21ac55
A
1974 if (signum != SIGCHLD) {
1975 proc_unlock(sig_proc);
1976 r_uid = kauth_getruid();
1977 proc_lock(sig_proc);
1978
1979 sig_proc->si_pid = current_proc()->p_pid;
1980 sig_proc->si_status = W_EXITCODE(signum, 0);
1981 sig_proc->si_uid = r_uid;
1982 sig_proc->si_code = 0;
91447636 1983 }
1c79356b 1984
2d21ac55 1985 goto runlocked;
1c79356b
A
1986 } else {
1987 /* Default action - varies */
1988 if (mask & stopsigmask) {
1989 /*
1990 * These are the signals which by default
1991 * stop a process.
1992 *
1993 * Don't clog system with children of init
1994 * stopped from the keyboard.
1995 */
2d21ac55
A
1996 if (!(prop & SA_STOP) && sig_proc->p_pptr == initproc) {
1997 proc_unlock(sig_proc);
1998 psignal_locked(sig_proc, SIGKILL);
1999 proc_lock(sig_proc);
9bccf70c 2000 uth->uu_siglist &= ~mask;
2d21ac55
A
2001 proc_unlock(sig_proc);
2002 goto psigout;
1c79356b
A
2003 }
2004
2005 /*
9bccf70c
A
2006 * Stop the task
2007 * if task hasn't already been stopped by
2008 * a signal.
1c79356b 2009 */
2d21ac55
A
2010 uth->uu_siglist &= ~mask;
2011 if (sig_proc->p_stat != SSTOP) {
2012 sig_proc->p_xstat = signum;
2013 sig_proc->p_stat = SSTOP;
b0d623f7 2014 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &sig_proc->p_flag);
2d21ac55
A
2015 sig_proc->p_lflag &= ~P_LWAITED;
2016 proc_unlock(sig_proc);
2017
2018 pp = proc_parentholdref(sig_proc);
2019 stop(sig_proc, pp);
2020 if (( pp != PROC_NULL) && ((pp->p_flag & P_NOCLDSTOP) == 0)) {
2021
2022 my_cred = kauth_cred_proc_ref(sig_proc);
6d2010ae 2023 r_uid = kauth_cred_getruid(my_cred);
2d21ac55
A
2024 kauth_cred_unref(&my_cred);
2025
2026 proc_lock(sig_proc);
2027 pp->si_pid = sig_proc->p_pid;
2028 /*
2029 * POSIX: sigaction for a stopped child
2030 * when sent to the parent must set the
2031 * child's signal number into si_status.
2032 */
2033 if (signum != SIGSTOP)
2034 pp->si_status = WEXITSTATUS(sig_proc->p_xstat);
2035 else
2036 pp->si_status = W_EXITCODE(signum, signum);
9bccf70c 2037 pp->si_code = CLD_STOPPED;
2d21ac55
A
2038 pp->si_uid = r_uid;
2039 proc_unlock(sig_proc);
2040
9bccf70c 2041 psignal(pp, SIGCHLD);
1c79356b 2042 }
2d21ac55
A
2043 if (pp != PROC_NULL)
2044 proc_parentdropref(pp, 0);
2045 } else
2046 proc_unlock(sig_proc);
2047 goto psigout;
1c79356b
A
2048 }
2049
2d21ac55
A
2050 DTRACE_PROC3(signal__send, thread_t, sig_thread, proc_t, p, int, signum);
2051
2052 /*
2053 * enters switch with sig_proc lock held but dropped when
2054 * gets out of switch
2055 */
1c79356b
A
2056 switch (signum) {
2057 /*
2058 * Signals ignored by default have been dealt
2059 * with already, since their bits are on in
2060 * p_sigignore.
2061 */
2062
2063 case SIGKILL:
2064 /*
2065 * Kill signal always sets process running and
2066 * unsuspends it.
2067 */
2068 /*
2069 * Process will be running after 'run'
2070 */
2d21ac55
A
2071 sig_proc->p_stat = SRUN;
2072 proc_unlock(sig_proc);
6d2010ae
A
2073 /*
2074 * In scenarios where suspend/resume are racing
2075 * the signal we are missing AST_BSD by the time
2076 * we get here, set again to avoid races. This
2077 * was the scenario with spindump enabled shutdowns.
2078 * We would need to cover this approp down the line.
2079 */
2080 act_set_astbsd(sig_thread);
2d21ac55 2081 thread_abort(sig_thread);
1c79356b 2082
2d21ac55 2083 goto psigout;
1c79356b
A
2084
2085 case SIGCONT:
2086 /*
2087 * Let the process run. If it's sleeping on an
2088 * event, it remains so.
2089 */
b0d623f7 2090 OSBitOrAtomic(P_CONTINUED, &sig_proc->p_flag);
2d21ac55
A
2091 sig_proc->p_contproc = sig_proc->p_pid;
2092
2093 proc_unlock(sig_proc);
2094 (void) task_resume(sig_task);
2095 proc_lock(sig_proc);
2096 /*
2097 * When processing a SIGCONT, we need to check
2098 * to see if there are signals pending that
2099 * were not delivered because we had been
2100 * previously stopped. If that's the case,
2101 * we need to thread_abort_safely() to trigger
2102 * interruption of the current system call to
2103 * cause their handlers to fire. If it's only
2104 * the SIGCONT, then don't wake up.
2105 */
2106 if (((flavor & (PSIG_VFORK|PSIG_THREAD)) == 0) && (((uth->uu_siglist & ~uth->uu_sigmask) & ~sig_proc->p_sigignore) & ~mask)) {
2107 uth->uu_siglist &= ~mask;
2108 sig_proc->p_stat = SRUN;
2109 goto runlocked;
1c79356b 2110 }
2d21ac55 2111
9bccf70c 2112 uth->uu_siglist &= ~mask;
2d21ac55
A
2113 sig_proc->p_stat = SRUN;
2114 proc_unlock(sig_proc);
2115 goto psigout;
1c79356b
A
2116
2117 default:
2d21ac55
A
2118 /*
2119 * A signal which has a default action of killing
2120 * the process, and for which there is no handler,
2121 * needs to act like SIGKILL
2122 */
2123 if (((flavor & (PSIG_VFORK|PSIG_THREAD)) == 0) && (action == SIG_DFL) && (prop & SA_KILL)) {
2124 sig_proc->p_stat = SRUN;
2125 proc_unlock(sig_proc);
2126 thread_abort(sig_thread);
2127 goto psigout;
2128 }
2129
1c79356b
A
2130 /*
2131 * All other signals wake up the process, but don't
2132 * resume it.
2133 */
2d21ac55
A
2134 if (sig_proc->p_stat == SSTOP) {
2135 proc_unlock(sig_proc);
2136 goto psigout;
2137 }
2138 goto runlocked;
1c79356b
A
2139 }
2140 }
2141 /*NOTREACHED*/
2d21ac55
A
2142
2143runlocked:
1c79356b
A
2144 /*
2145 * If we're being traced (possibly because someone attached us
2146 * while we were stopped), check for a signal from the debugger.
2147 */
2d21ac55
A
2148 if (sig_proc->p_stat == SSTOP) {
2149 if ((sig_proc->p_lflag & P_LTRACED) != 0 && sig_proc->p_xstat != 0)
2150 uth->uu_siglist |= sigmask(sig_proc->p_xstat);
2151 if ((flavor & PSIG_VFORK) != 0) {
2152 sig_proc->p_stat = SRUN;
9bccf70c 2153 }
2d21ac55 2154 proc_unlock(sig_proc);
9bccf70c
A
2155 } else {
2156 /*
2157 * setrunnable(p) in BSD and
2158 * Wake up the thread if it is interruptible.
2159 */
2d21ac55
A
2160 sig_proc->p_stat = SRUN;
2161 proc_unlock(sig_proc);
2162 if ((flavor & PSIG_VFORK) == 0)
2163 thread_abort_safely(sig_thread);
2164 }
2165psigout:
2166 if ((flavor & PSIG_LOCKED)== 0) {
2167 proc_signalend(sig_proc, 0);
1c79356b 2168 }
1c79356b
A
2169}
2170
2d21ac55
A
2171void
2172psignal(proc_t p, int signum)
1c79356b 2173{
2d21ac55
A
2174 psignal_internal(p, NULL, NULL, 0, signum);
2175}
1c79356b 2176
2d21ac55
A
2177void
2178psignal_locked(proc_t p, int signum)
2179{
2180 psignal_internal(p, NULL, NULL, PSIG_LOCKED, signum);
1c79356b
A
2181}
2182
2d21ac55
A
2183void
2184psignal_vfork(proc_t p, task_t new_task, thread_t thread, int signum)
1c79356b 2185{
2d21ac55
A
2186 psignal_internal(p, new_task, thread, PSIG_VFORK, signum);
2187}
1c79356b 2188
2d21ac55
A
2189static void
2190psignal_uthread(thread_t thread, int signum)
2191{
2192 psignal_internal(PROC_NULL, TASK_NULL, thread, PSIG_THREAD, signum);
1c79356b
A
2193}
2194
2d21ac55 2195
1c79356b
A
2196/*
2197 * If the current process has received a signal (should be caught or cause
2198 * termination, should interrupt current syscall), return the signal number.
2199 * Stop signals with default action are processed immediately, then cleared;
2200 * they aren't returned. This is checked after each entry to the system for
2201 * a syscall or trap (though this can usually be done without calling issignal
2202 * by checking the pending signal masks in the CURSIG macro.) The normal call
2203 * sequence is
2204 *
2205 * while (signum = CURSIG(curproc))
2206 * postsig(signum);
2207 */
2208int
2d21ac55 2209issignal(proc_t p)
1c79356b 2210{
2d21ac55 2211 int signum, mask, prop, sigbits;
91447636 2212 thread_t cur_act;
1c79356b 2213 struct uthread * ut;
2d21ac55
A
2214 proc_t pp;
2215 kauth_cred_t my_cred;
2216 int retval = 0;
2217 uid_t r_uid;
1c79356b 2218
91447636 2219 cur_act = current_thread();
1c79356b 2220
9bccf70c
A
2221#if SIGNAL_DEBUG
2222 if(rdebug_proc && (p == rdebug_proc)) {
2223 ram_printf(3);
2224 }
2225#endif /* SIGNAL_DEBUG */
2d21ac55 2226 proc_lock(p);
1c79356b 2227
1c79356b
A
2228 /*
2229 * Try to grab the signal lock.
2230 */
2231 if (sig_try_locked(p) <= 0) {
2d21ac55
A
2232 proc_unlock(p);
2233 return(0);
1c79356b
A
2234 }
2235
2d21ac55
A
2236 proc_signalstart(p, 1);
2237
1c79356b
A
2238 ut = get_bsdthread_info(cur_act);
2239 for(;;) {
9bccf70c 2240 sigbits = ut->uu_siglist & ~ut->uu_sigmask;
1c79356b 2241
2d21ac55 2242 if (p->p_lflag & P_LPPWAIT)
1c79356b
A
2243 sigbits &= ~stopsigmask;
2244 if (sigbits == 0) { /* no signal to send */
2d21ac55
A
2245 retval = 0;
2246 goto out;
1c79356b 2247 }
2d21ac55 2248
1c79356b
A
2249 signum = ffs((long)sigbits);
2250 mask = sigmask(signum);
2251 prop = sigprop[signum];
2252
1c79356b
A
2253 /*
2254 * We should see pending but ignored signals
2d21ac55 2255 * only if P_LTRACED was on when they were posted.
1c79356b 2256 */
2d21ac55 2257 if (mask & p->p_sigignore && (p->p_lflag & P_LTRACED) == 0) {
9bccf70c 2258 ut->uu_siglist &= ~mask; /* take the signal! */
1c79356b
A
2259 continue;
2260 }
2d21ac55
A
2261 if (p->p_lflag & P_LTRACED && (p->p_lflag & P_LPPWAIT) == 0) {
2262 task_t task;
1c79356b
A
2263 /*
2264 * If traced, always stop, and stay
2265 * stopped until released by the debugger.
2266 */
2267 /* ptrace debugging */
2268 p->p_xstat = signum;
2d21ac55
A
2269
2270 if (p->p_lflag & P_LSIGEXC) {
9bccf70c
A
2271 p->sigwait = TRUE;
2272 p->sigwait_thread = cur_act;
2273 p->p_stat = SSTOP;
b0d623f7 2274 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
2d21ac55 2275 p->p_lflag &= ~P_LWAITED;
9bccf70c 2276 ut->uu_siglist &= ~mask; /* clear the old signal */
2d21ac55
A
2277 proc_signalend(p, 1);
2278 proc_unlock(p);
9bccf70c 2279 do_bsdexception(EXC_SOFTWARE, EXC_SOFT_SIGNAL, signum);
2d21ac55
A
2280 proc_lock(p);
2281 proc_signalstart(p, 1);
9bccf70c 2282 } else {
2d21ac55
A
2283 proc_unlock(p);
2284 my_cred = kauth_cred_proc_ref(p);
6d2010ae 2285 r_uid = kauth_cred_getruid(my_cred);
2d21ac55
A
2286 kauth_cred_unref(&my_cred);
2287
2288 pp = proc_parentholdref(p);
2289 if (pp != PROC_NULL) {
2290 proc_lock(pp);
2291
2292 pp->si_pid = p->p_pid;
2293 pp->si_status = p->p_xstat;
2294 pp->si_code = CLD_TRAPPED;
2295 pp->si_uid = r_uid;
2296
2297 proc_unlock(pp);
2298 }
2299
9bccf70c
A
2300 /*
2301 * XXX Have to really stop for debuggers;
2302 * XXX stop() doesn't do the right thing.
2303 * XXX Inline the task_suspend because we
2304 * XXX have to diddle Unix state in the
2305 * XXX middle of it.
2306 */
2307 task = p->task;
2d21ac55
A
2308 task_suspend(task);
2309
2310 proc_lock(p);
9bccf70c
A
2311 p->sigwait = TRUE;
2312 p->sigwait_thread = cur_act;
2313 p->p_stat = SSTOP;
b0d623f7 2314 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
2d21ac55 2315 p->p_lflag &= ~P_LWAITED;
9bccf70c 2316 ut->uu_siglist &= ~mask; /* clear the old signal */
9bccf70c 2317
2d21ac55
A
2318 proc_signalend(p, 1);
2319 proc_unlock(p);
2320
2321 if (pp != PROC_NULL) {
2322 psignal(pp, SIGCHLD);
2323 proc_list_lock();
2324 wakeup((caddr_t)pp);
2325 proc_parentdropref(pp, 1);
2326 proc_list_unlock();
2327 }
2328
9bccf70c
A
2329 assert_wait((caddr_t)&p->sigwait, (THREAD_INTERRUPTIBLE));
2330 thread_block(THREAD_CONTINUE_NULL);
2d21ac55
A
2331 proc_lock(p);
2332 proc_signalstart(p, 1);
9bccf70c
A
2333 }
2334
1c79356b
A
2335 p->sigwait = FALSE;
2336 p->sigwait_thread = NULL;
2337 wakeup((caddr_t)&p->sigwait_thread);
2338
2339 /*
2340 * This code is to detect when gdb is killed
2341 * even as the traced program is attached.
2342 * pgsignal would get the SIGKILL to traced program
2343 * That's what we are trying to see (I hope)
2344 */
9bccf70c 2345 if (ut->uu_siglist & sigmask(SIGKILL)) {
1c79356b
A
2346 /*
2347 * Wait event may still be outstanding;
2348 * clear it, since sig_lock_to_exit will
2349 * wait.
2350 */
91447636 2351 clear_wait(current_thread(), THREAD_INTERRUPTED);
1c79356b
A
2352 sig_lock_to_exit(p);
2353 /*
2354 * Since this thread will be resumed
2355 * to allow the current syscall to
2356 * be completed, must save u_qsave
2357 * before calling exit(). (Since exit()
2358 * calls closef() which can trash u_qsave.)
2359 */
2d21ac55
A
2360 proc_signalend(p, 1);
2361 proc_unlock(p);
b0d623f7
A
2362 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_FRCEXIT) | DBG_FUNC_NONE,
2363 p->p_pid, W_EXITCODE(0, SIGKILL), 2, 0, 0);
2d21ac55 2364 exit1(p, W_EXITCODE(0, SIGKILL), (int *)NULL);
1c79356b
A
2365 return(0);
2366 }
2367
2368 /*
2369 * We may have to quit
2370 */
91447636 2371 if (thread_should_abort(current_thread())) {
2d21ac55
A
2372 retval = 0;
2373 goto out;
1c79356b
A
2374 }
2375 /*
2376 * If parent wants us to take the signal,
2377 * then it will leave it in p->p_xstat;
2378 * otherwise we just look for signals again.
2379 */
2380 signum = p->p_xstat;
2381 if (signum == 0)
2382 continue;
2383 /*
2384 * Put the new signal into p_siglist. If the
2385 * signal is being masked, look for other signals.
2386 */
2387 mask = sigmask(signum);
9bccf70c 2388 ut->uu_siglist |= mask;
9bccf70c 2389 if (ut->uu_sigmask & mask)
1c79356b
A
2390 continue;
2391 }
2392
2393 /*
2394 * Decide whether the signal should be returned.
2395 * Return the signal's number, or fall through
2396 * to clear it from the pending mask.
2397 */
2398
2399 switch ((long)p->p_sigacts->ps_sigact[signum]) {
2400
2401 case (long)SIG_DFL:
2402 /*
2403 * Don't take default actions on system processes.
2404 */
2d21ac55 2405 if (p->p_ppid == 0) {
1c79356b
A
2406#if DIAGNOSTIC
2407 /*
2408 * Are you sure you want to ignore SIGSEGV
2409 * in init? XXX
2410 */
2411 printf("Process (pid %d) got signal %d\n",
2412 p->p_pid, signum);
2413#endif
2414 break; /* == ignore */
2415 }
2416
2417 /*
2418 * If there is a pending stop signal to process
2419 * with default action, stop here,
2420 * then clear the signal. However,
2421 * if process is member of an orphaned
2422 * process group, ignore tty stop signals.
2423 */
2424 if (prop & SA_STOP) {
2d21ac55
A
2425 struct pgrp * pg;
2426
2427 proc_unlock(p);
2428 pg = proc_pgrp(p);
2429 if (p->p_lflag & P_LTRACED ||
2430 (pg->pg_jobc == 0 &&
2431 prop & SA_TTYSTOP)) {
2432 proc_lock(p);
2433 pg_rele(pg);
1c79356b 2434 break; /* == ignore */
2d21ac55
A
2435 }
2436 pg_rele(pg);
9bccf70c 2437 if (p->p_stat != SSTOP) {
2d21ac55 2438 proc_lock(p);
9bccf70c 2439 p->p_xstat = signum;
2d21ac55
A
2440
2441 p->p_stat = SSTOP;
2442 p->p_lflag &= ~P_LWAITED;
2443 proc_unlock(p);
2444
2445 pp = proc_parentholdref(p);
2446 stop(p, pp);
2447 if ((pp != PROC_NULL) && ((pp->p_flag & P_NOCLDSTOP) == 0)) {
2448 my_cred = kauth_cred_proc_ref(p);
6d2010ae 2449 r_uid = kauth_cred_getruid(my_cred);
2d21ac55
A
2450 kauth_cred_unref(&my_cred);
2451
2452 proc_lock(pp);
9bccf70c 2453 pp->si_pid = p->p_pid;
2d21ac55 2454 pp->si_status = WEXITSTATUS(p->p_xstat);
9bccf70c 2455 pp->si_code = CLD_STOPPED;
2d21ac55
A
2456 pp->si_uid = r_uid;
2457 proc_unlock(pp);
2458
9bccf70c
A
2459 psignal(pp, SIGCHLD);
2460 }
2d21ac55
A
2461 if (pp != PROC_NULL)
2462 proc_parentdropref(pp, 0);
1c79356b 2463 }
2d21ac55 2464 proc_lock(p);
1c79356b
A
2465 break;
2466 } else if (prop & SA_IGNORE) {
2467 /*
2468 * Except for SIGCONT, shouldn't get here.
2469 * Default action is to ignore; drop it.
2470 */
2471 break; /* == ignore */
2472 } else {
9bccf70c 2473 ut->uu_siglist &= ~mask; /* take the signal! */
2d21ac55
A
2474 retval = signum;
2475 goto out;
1c79356b 2476 }
2d21ac55 2477
1c79356b 2478 /*NOTREACHED*/
2d21ac55 2479 break;
1c79356b
A
2480
2481 case (long)SIG_IGN:
2482 /*
2483 * Masking above should prevent us ever trying
2484 * to take action on an ignored signal other
2485 * than SIGCONT, unless process is traced.
2486 */
2487 if ((prop & SA_CONT) == 0 &&
2d21ac55 2488 (p->p_lflag & P_LTRACED) == 0)
1c79356b
A
2489 printf("issignal\n");
2490 break; /* == ignore */
2491
2492 default:
2493 /*
2494 * This signal has an action, let
2495 * postsig() process it.
2496 */
9bccf70c 2497 ut->uu_siglist &= ~mask; /* take the signal! */
2d21ac55
A
2498 retval = signum;
2499 goto out;
1c79356b 2500 }
9bccf70c 2501 ut->uu_siglist &= ~mask; /* take the signal! */
1c79356b
A
2502 }
2503 /* NOTREACHED */
2d21ac55 2504out:
6d2010ae 2505 proc_signalend(p, 1);
2d21ac55
A
2506 proc_unlock(p);
2507 return(retval);
1c79356b
A
2508}
2509
2510/* called from _sleep */
2511int
2d21ac55 2512CURSIG(proc_t p)
1c79356b 2513{
2d21ac55 2514 int signum, mask, prop, sigbits;
91447636 2515 thread_t cur_act;
1c79356b
A
2516 struct uthread * ut;
2517 int retnum = 0;
2518
1c79356b 2519
91447636 2520 cur_act = current_thread();
1c79356b
A
2521
2522 ut = get_bsdthread_info(cur_act);
2523
9bccf70c
A
2524 if (ut->uu_siglist == 0)
2525 return (0);
2526
2d21ac55 2527 if (((ut->uu_siglist & ~ut->uu_sigmask) == 0) && ((p->p_lflag & P_LTRACED) == 0))
9bccf70c
A
2528 return (0);
2529
2530 sigbits = ut->uu_siglist & ~ut->uu_sigmask;
1c79356b
A
2531
2532 for(;;) {
2d21ac55 2533 if (p->p_lflag & P_LPPWAIT)
1c79356b
A
2534 sigbits &= ~stopsigmask;
2535 if (sigbits == 0) { /* no signal to send */
2536 return (retnum);
2537 }
2538
2539 signum = ffs((long)sigbits);
2540 mask = sigmask(signum);
2541 prop = sigprop[signum];
6d2010ae 2542 sigbits &= ~mask; /* take the signal out */
1c79356b
A
2543
2544 /*
2545 * We should see pending but ignored signals
2d21ac55 2546 * only if P_LTRACED was on when they were posted.
1c79356b 2547 */
2d21ac55 2548 if (mask & p->p_sigignore && (p->p_lflag & P_LTRACED) == 0) {
1c79356b
A
2549 continue;
2550 }
6d2010ae 2551
2d21ac55 2552 if (p->p_lflag & P_LTRACED && (p->p_lflag & P_LPPWAIT) == 0) {
1c79356b
A
2553 return(signum);
2554 }
2555
2556 /*
2557 * Decide whether the signal should be returned.
2558 * Return the signal's number, or fall through
2559 * to clear it from the pending mask.
2560 */
2561
2562 switch ((long)p->p_sigacts->ps_sigact[signum]) {
2563
2564 case (long)SIG_DFL:
2565 /*
2566 * Don't take default actions on system processes.
2567 */
2d21ac55 2568 if (p->p_ppid == 0) {
1c79356b
A
2569#if DIAGNOSTIC
2570 /*
2571 * Are you sure you want to ignore SIGSEGV
2572 * in init? XXX
2573 */
2574 printf("Process (pid %d) got signal %d\n",
2575 p->p_pid, signum);
2576#endif
2577 break; /* == ignore */
2578 }
2579
2580 /*
2581 * If there is a pending stop signal to process
2582 * with default action, stop here,
2583 * then clear the signal. However,
2584 * if process is member of an orphaned
2585 * process group, ignore tty stop signals.
2586 */
2587 if (prop & SA_STOP) {
2d21ac55
A
2588 struct pgrp *pg;
2589
2590 pg = proc_pgrp(p);
2591
2592 if (p->p_lflag & P_LTRACED ||
2593 (pg->pg_jobc == 0 &&
2594 prop & SA_TTYSTOP)) {
2595 pg_rele(pg);
1c79356b 2596 break; /* == ignore */
2d21ac55
A
2597 }
2598 pg_rele(pg);
1c79356b
A
2599 retnum = signum;
2600 break;
2601 } else if (prop & SA_IGNORE) {
2602 /*
2603 * Except for SIGCONT, shouldn't get here.
2604 * Default action is to ignore; drop it.
2605 */
2606 break; /* == ignore */
2607 } else {
2608 return (signum);
2609 }
2610 /*NOTREACHED*/
2611
2612 case (long)SIG_IGN:
2613 /*
2614 * Masking above should prevent us ever trying
2615 * to take action on an ignored signal other
2616 * than SIGCONT, unless process is traced.
2617 */
2618 if ((prop & SA_CONT) == 0 &&
2d21ac55 2619 (p->p_lflag & P_LTRACED) == 0)
1c79356b
A
2620 printf("issignal\n");
2621 break; /* == ignore */
2622
2623 default:
2624 /*
2625 * This signal has an action, let
2626 * postsig() process it.
2627 */
2628 return (signum);
2629 }
1c79356b
A
2630 }
2631 /* NOTREACHED */
2632}
2633
2634/*
2635 * Put the argument process into the stopped state and notify the parent
2636 * via wakeup. Signals are handled elsewhere. The process must not be
2637 * on the run queue.
2638 */
2d21ac55
A
2639static void
2640stop(proc_t p, proc_t parent)
1c79356b 2641{
b0d623f7 2642 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
2d21ac55
A
2643 if ((parent != PROC_NULL) && (parent->p_stat != SSTOP)) {
2644 proc_list_lock();
2645 wakeup((caddr_t)parent);
2646 proc_list_unlock();
2647 }
1c79356b
A
2648 (void) task_suspend(p->task); /*XXX*/
2649}
2650
2651/*
2652 * Take the action for the specified signal
2653 * from the current set of pending signals.
2654 */
2655void
91447636 2656postsig(int signum)
1c79356b 2657{
2d21ac55 2658 proc_t p = current_proc();
91447636
A
2659 struct sigacts *ps = p->p_sigacts;
2660 user_addr_t catcher;
b0d623f7 2661 uint32_t code;
1c79356b 2662 int mask, returnmask;
9bccf70c 2663 struct uthread * ut;
1c79356b
A
2664
2665#if DIAGNOSTIC
2666 if (signum == 0)
2667 panic("postsig");
2668 /*
2669 * This must be called on master cpu
2670 */
2671 if (cpu_number() != master_cpu)
2672 panic("psig not on master");
2673#endif
2674
2d21ac55 2675 proc_lock(p);
1c79356b
A
2676 /*
2677 * Try to grab the signal lock.
2678 */
2679 if (sig_try_locked(p) <= 0) {
2d21ac55 2680 proc_unlock(p);
1c79356b
A
2681 return;
2682 }
2683
2d21ac55
A
2684 proc_signalstart(p, 1);
2685
91447636 2686 ut = (struct uthread *)get_bsdthread_info(current_thread());
1c79356b 2687 mask = sigmask(signum);
9bccf70c 2688 ut->uu_siglist &= ~mask;
91447636 2689 catcher = ps->ps_sigact[signum];
91447636 2690 if (catcher == SIG_DFL) {
1c79356b 2691 /*
91447636 2692 * Default catcher, where the default is to kill
1c79356b
A
2693 * the process. (Other cases were ignored above.)
2694 */
2d21ac55
A
2695 sig_lock_to_exit(p);
2696 p->p_acflag |= AXSIG;
2697 if (sigprop[signum] & SA_CORE) {
2698 p->p_sigacts->ps_sig = signum;
2699 proc_signalend(p, 1);
2700 proc_unlock(p);
2701 if (coredump(p) == 0)
2702 signum |= WCOREFLAG;
2703 } else {
2704 proc_signalend(p, 1);
2705 proc_unlock(p);
2706 }
2707
b0d623f7
A
2708#if CONFIG_DTRACE
2709 bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo));
2710
2711 ut->t_dtrace_siginfo.si_signo = signum;
2712 ut->t_dtrace_siginfo.si_pid = p->si_pid;
2713 ut->t_dtrace_siginfo.si_uid = p->si_uid;
2714 ut->t_dtrace_siginfo.si_status = WEXITSTATUS(p->si_status);
2d21ac55 2715
b0d623f7 2716 DTRACE_PROC3(signal__handle, int, signum, siginfo_t *, &(ut->t_dtrace_siginfo),
2d21ac55 2717 void (*)(void), SIG_DFL);
b0d623f7 2718#endif
2d21ac55 2719
b0d623f7
A
2720 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_FRCEXIT) | DBG_FUNC_NONE,
2721 p->p_pid, W_EXITCODE(0, signum), 3, 0, 0);
2d21ac55 2722 exit1(p, W_EXITCODE(0, signum), (int *)NULL);
1c79356b 2723 return;
1c79356b
A
2724 } else {
2725 /*
2726 * If we get here, the signal must be caught.
2727 */
2728#if DIAGNOSTIC
91447636 2729 if (catcher == SIG_IGN || (ut->uu_sigmask & mask))
1c79356b
A
2730 log(LOG_WARNING,
2731 "postsig: processing masked or ignored signal\n");
2732#endif
2d21ac55 2733
1c79356b
A
2734 /*
2735 * Set the new mask value and also defer further
2736 * occurences of this signal.
2737 *
2738 * Special case: user has done a sigpause. Here the
2739 * current mask is not of interest, but rather the
2740 * mask from before the sigpause is what we want
2741 * restored after the signal processing is completed.
2742 */
91447636 2743 if (ut->uu_flag & UT_SAS_OLDMASK) {
9bccf70c 2744 returnmask = ut->uu_oldmask;
91447636 2745 ut->uu_flag &= ~UT_SAS_OLDMASK;
9bccf70c 2746 ut->uu_oldmask = 0;
1c79356b 2747 } else
9bccf70c
A
2748 returnmask = ut->uu_sigmask;
2749 ut->uu_sigmask |= ps->ps_catchmask[signum];
2750 if ((ps->ps_signodefer & mask) == 0)
2751 ut->uu_sigmask |= mask;
2752 if ((signum != SIGILL) && (signum != SIGTRAP) && (ps->ps_sigreset & mask)) {
2753 if ((signum != SIGCONT) && (sigprop[signum] & SA_IGNORE))
2754 p->p_sigignore |= mask;
2755 ps->ps_sigact[signum] = SIG_DFL;
2756 ps->ps_siginfo &= ~mask;
2757 ps->ps_signodefer &= ~mask;
2758 }
9bccf70c 2759
1c79356b
A
2760 if (ps->ps_sig != signum) {
2761 code = 0;
2762 } else {
2763 code = ps->ps_code;
2764 ps->ps_code = 0;
2765 }
b0d623f7 2766 OSIncrementAtomicLong(&p->p_stats->p_ru.ru_nsignals);
91447636 2767 sendsig(p, catcher, signum, returnmask, code);
1c79356b 2768 }
2d21ac55
A
2769 proc_signalend(p, 1);
2770 proc_unlock(p);
1c79356b
A
2771}
2772
2773/*
2d21ac55
A
2774 * Attach a signal knote to the list of knotes for this process.
2775 *
2776 * Signal knotes share the knote list with proc knotes. This
2777 * could be avoided by using a signal-specific knote list, but
2778 * probably isn't worth the trouble.
1c79356b 2779 */
55e303ae
A
2780
2781static int
2782filt_sigattach(struct knote *kn)
2783{
2d21ac55
A
2784 proc_t p = current_proc(); /* can attach only to oneself */
2785
2786 proc_klist_lock();
55e303ae
A
2787
2788 kn->kn_ptr.p_proc = p;
2789 kn->kn_flags |= EV_CLEAR; /* automatically set */
2790
55e303ae 2791 KNOTE_ATTACH(&p->p_klist, kn);
2d21ac55
A
2792
2793 proc_klist_unlock();
55e303ae
A
2794
2795 return (0);
2796}
2797
2d21ac55
A
2798/*
2799 * remove the knote from the process list, if it hasn't already
2800 * been removed by exit processing.
2801 */
2802
55e303ae
A
2803static void
2804filt_sigdetach(struct knote *kn)
2805{
2d21ac55 2806 proc_t p = kn->kn_ptr.p_proc;
55e303ae 2807
2d21ac55
A
2808 proc_klist_lock();
2809 kn->kn_ptr.p_proc = NULL;
55e303ae 2810 KNOTE_DETACH(&p->p_klist, kn);
2d21ac55 2811 proc_klist_unlock();
55e303ae
A
2812}
2813
2814/*
2d21ac55
A
2815 * Post an event to the signal filter. Because we share the same list
2816 * as process knotes, we have to filter out and handle only signal events.
2817 *
2818 * We assume that we process fdfree() before we post the NOTE_EXIT for
2819 * a process during exit. Therefore, since signal filters can only be
2820 * set up "in-process", we should have already torn down the kqueue
2821 * hosting the EVFILT_SIGNAL knote and should never see NOTE_EXIT.
55e303ae
A
2822 */
2823static int
2824filt_signal(struct knote *kn, long hint)
2825{
2826
2827 if (hint & NOTE_SIGNAL) {
2828 hint &= ~NOTE_SIGNAL;
2829
91447636 2830 if (kn->kn_id == (unsigned int)hint)
55e303ae 2831 kn->kn_data++;
2d21ac55
A
2832 } else if (hint & NOTE_EXIT) {
2833 panic("filt_signal: detected NOTE_EXIT event");
55e303ae 2834 }
2d21ac55 2835
55e303ae
A
2836 return (kn->kn_data != 0);
2837}
2838
b0d623f7
A
2839static void
2840filt_signaltouch(struct knote *kn, struct kevent64_s *kev, long type)
2841{
2842 proc_klist_lock();
2843 switch (type) {
2844 case EVENT_REGISTER:
2845 kn->kn_sfflags = kev->fflags;
2846 kn->kn_sdata = kev->data;
2847 break;
2848 case EVENT_PROCESS:
2849 *kev = kn->kn_kevent;
2850 if (kn->kn_flags & EV_CLEAR) {
2851 kn->kn_data = 0;
2852 kn->kn_fflags = 0;
2853 }
2854 break;
2855 default:
2856 panic("filt_machporttouch() - invalid type (%ld)", type);
2857 break;
2858 }
2859 proc_klist_unlock();
2860}
2861
1c79356b 2862void
2d21ac55 2863bsd_ast(thread_t thread)
1c79356b 2864{
2d21ac55
A
2865 proc_t p = current_proc();
2866 struct uthread *ut = get_bsdthread_info(thread);
1c79356b 2867 int signum;
91447636 2868 user_addr_t pc;
91447636 2869 static int bsd_init_done = 0;
1c79356b
A
2870
2871 if (p == NULL)
2872 return;
2873
1c79356b
A
2874 if ((p->p_flag & P_OWEUPC) && (p->p_flag & P_PROFIL)) {
2875 pc = get_useraddr();
2876 addupc_task(p, pc, 1);
b0d623f7 2877 OSBitAndAtomic(~((uint32_t)P_OWEUPC), &p->p_flag);
1c79356b
A
2878 }
2879
2d21ac55
A
2880 if (timerisset(&p->p_vtimer_user.it_value)) {
2881 uint32_t microsecs;
2882
2883 task_vtimer_update(p->task, TASK_VTIMER_USER, &microsecs);
2884
2885 if (!itimerdecr(p, &p->p_vtimer_user, microsecs)) {
2886 if (timerisset(&p->p_vtimer_user.it_value))
2887 task_vtimer_set(p->task, TASK_VTIMER_USER);
2888 else
2889 task_vtimer_clear(p->task, TASK_VTIMER_USER);
2890
2891 psignal(p, SIGVTALRM);
b0d623f7 2892 }
9bccf70c 2893 }
1c79356b 2894
2d21ac55
A
2895 if (timerisset(&p->p_vtimer_prof.it_value)) {
2896 uint32_t microsecs;
1c79356b 2897
2d21ac55 2898 task_vtimer_update(p->task, TASK_VTIMER_PROF, &microsecs);
1c79356b 2899
2d21ac55
A
2900 if (!itimerdecr(p, &p->p_vtimer_prof, microsecs)) {
2901 if (timerisset(&p->p_vtimer_prof.it_value))
2902 task_vtimer_set(p->task, TASK_VTIMER_PROF);
2903 else
2904 task_vtimer_clear(p->task, TASK_VTIMER_PROF);
2905
2906 psignal(p, SIGPROF);
2907 }
b0d623f7 2908 }
1c79356b 2909
2d21ac55
A
2910 if (timerisset(&p->p_rlim_cpu)) {
2911 struct timeval tv;
1c79356b 2912
2d21ac55 2913 task_vtimer_update(p->task, TASK_VTIMER_RLIM, (uint32_t *) &tv.tv_usec);
1c79356b 2914
2d21ac55
A
2915 proc_spinlock(p);
2916 if (p->p_rlim_cpu.tv_sec > 0 || p->p_rlim_cpu.tv_usec > tv.tv_usec) {
2917 tv.tv_sec = 0;
2918 timersub(&p->p_rlim_cpu, &tv, &p->p_rlim_cpu);
2919 proc_spinunlock(p);
2920 } else {
2921
2922 timerclear(&p->p_rlim_cpu);
2923 proc_spinunlock(p);
2924
2925 task_vtimer_clear(p->task, TASK_VTIMER_RLIM);
2926
2927 psignal(p, SIGXCPU);
2928 }
2929 }
2930
b0d623f7
A
2931#if CONFIG_DTRACE
2932 if (ut->t_dtrace_sig) {
2933 uint8_t dt_action_sig = ut->t_dtrace_sig;
2934 ut->t_dtrace_sig = 0;
2935 psignal(p, dt_action_sig);
2936 }
6d2010ae 2937
b0d623f7 2938 if (ut->t_dtrace_stop) {
6d2010ae
A
2939 ut->t_dtrace_stop = 0;
2940 proc_lock(p);
2941 p->p_dtrace_stop = 1;
2942 proc_unlock(p);
2943 (void)task_suspend(p->task);
2944 }
2945
2946 if (ut->t_dtrace_resumepid) {
2947 proc_t resumeproc = proc_find(ut->t_dtrace_resumepid);
2948 ut->t_dtrace_resumepid = 0;
2949 if (resumeproc != PROC_NULL) {
2950 proc_lock(resumeproc);
2951 /* We only act on processes stopped by dtrace */
2952 if (resumeproc->p_dtrace_stop) {
2953 resumeproc->p_dtrace_stop = 0;
2954 proc_unlock(resumeproc);
2955 task_resume(resumeproc->task);
2956 }
2957 else {
2958 proc_unlock(resumeproc);
2959 }
2960 proc_rele(resumeproc);
2961 }
b0d623f7 2962 }
6d2010ae 2963
b0d623f7
A
2964#endif /* CONFIG_DTRACE */
2965
2d21ac55
A
2966 if (CHECK_SIGNALS(p, current_thread(), ut)) {
2967 while ( (signum = issignal(p)) )
2968 postsig(signum);
2969 }
2970
2971 if (!bsd_init_done) {
2972 bsd_init_done = 1;
2973 bsdinit_task();
2974 }
1c79356b 2975
1c79356b
A
2976}
2977
593a1d5f 2978/* ptrace set runnable */
1c79356b 2979void
2d21ac55 2980pt_setrunnable(proc_t p)
1c79356b 2981{
2d21ac55 2982 task_t task;
1c79356b
A
2983
2984 task = p->task;
2985
2d21ac55
A
2986 if (p->p_lflag & P_LTRACED) {
2987 proc_lock(p);
1c79356b 2988 p->p_stat = SRUN;
2d21ac55 2989 proc_unlock(p);
1c79356b
A
2990 if (p->sigwait) {
2991 wakeup((caddr_t)&(p->sigwait));
593a1d5f
A
2992 if ((p->p_lflag & P_LSIGEXC) == 0) { // 5878479
2993 task_release(task);
2994 }
1c79356b
A
2995 }
2996 }
2997}
9bccf70c
A
2998
2999kern_return_t
3000do_bsdexception(
3001 int exc,
3002 int code,
3003 int sub)
3004{
2d21ac55 3005 mach_exception_data_type_t codes[EXCEPTION_CODE_MAX];
9bccf70c
A
3006
3007 codes[0] = code;
3008 codes[1] = sub;
3009 return(bsd_exception(exc, codes, 2));
3010}
3011
91447636 3012int
2d21ac55 3013proc_pendingsignals(proc_t p, sigset_t mask)
91447636
A
3014{
3015 struct uthread * uth;
3016 thread_t th;
3017 sigset_t bits = 0;
91447636 3018
2d21ac55 3019 proc_lock(p);
91447636 3020 /* If the process is in proc exit return no signal info */
2d21ac55
A
3021 if (p->p_lflag & P_LPEXIT) {
3022 goto out;
3023 }
91447636 3024
2d21ac55 3025 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
91447636
A
3026 th = p->p_vforkact;
3027 uth = (struct uthread *)get_bsdthread_info(th);
3028 if (uth) {
3029 bits = (((uth->uu_siglist & ~uth->uu_sigmask) & ~p->p_sigignore) & mask);
3030 }
3031 goto out;
3032 }
3033
3034 bits = 0;
3035 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
3036 bits |= (((uth->uu_siglist & ~uth->uu_sigmask) & ~p->p_sigignore) & mask);
3037 }
3038out:
2d21ac55 3039 proc_unlock(p);
91447636
A
3040 return(bits);
3041}
3042
3043int
3044thread_issignal(proc_t p, thread_t th, sigset_t mask)
3045{
3046 struct uthread * uth;
3047 sigset_t bits=0;
3048
2d21ac55
A
3049 proc_lock(p);
3050 uth = (struct uthread *)get_bsdthread_info(th);
3051 if (uth) {
3052 bits = (((uth->uu_siglist & ~uth->uu_sigmask) & ~p->p_sigignore) & mask);
3053 }
3054 proc_unlock(p);
3055 return(bits);
3056}
91447636 3057
2d21ac55
A
3058/*
3059 * Allow external reads of the sigprop array.
3060 */
3061int
3062hassigprop(int sig, int prop)
3063{
3064 return (sigprop[sig] & prop);
3065}
3066
3067void
3068pgsigio(pid_t pgid, int sig)
3069{
3070 proc_t p = PROC_NULL;
3071
3072 if (pgid < 0)
3073 gsignal(-(pgid), sig);
3074
3075 else if (pgid > 0 && (p = proc_find(pgid)) != 0)
3076 psignal(p, sig);
3077 if (p != PROC_NULL)
3078 proc_rele(p);
3079}
3080
2d21ac55
A
3081void
3082proc_signalstart(proc_t p, int locked)
3083{
6d2010ae 3084 if (!locked)
2d21ac55 3085 proc_lock(p);
6d2010ae
A
3086 p->p_sigwaitcnt++;
3087 while ((p->p_lflag & P_LINSIGNAL) == P_LINSIGNAL)
2d21ac55 3088 msleep(&p->p_sigmask, &p->p_mlock, 0, "proc_signstart", NULL);
6d2010ae
A
3089 p->p_sigwaitcnt--;
3090
2d21ac55 3091 p->p_lflag |= P_LINSIGNAL;
2d21ac55 3092 p->p_signalholder = current_thread();
6d2010ae 3093 if (!locked)
2d21ac55 3094 proc_unlock(p);
2d21ac55
A
3095}
3096
3097void
3098proc_signalend(proc_t p, int locked)
3099{
6d2010ae 3100 if (!locked)
2d21ac55
A
3101 proc_lock(p);
3102 p->p_lflag &= ~P_LINSIGNAL;
3103
6d2010ae 3104 if (p->p_sigwaitcnt > 0)
2d21ac55 3105 wakeup(&p->p_sigmask);
6d2010ae 3106
2d21ac55 3107 p->p_signalholder = NULL;
6d2010ae 3108 if (!locked)
2d21ac55
A
3109 proc_unlock(p);
3110}
3111
2d21ac55
A
3112void
3113sig_lock_to_exit(proc_t p)
3114{
3115 thread_t self = current_thread();
3116
3117 p->exit_thread = self;
3118 proc_unlock(p);
3119 (void) task_suspend(p->task);
3120 proc_lock(p);
91447636
A
3121}
3122
2d21ac55
A
3123int
3124sig_try_locked(proc_t p)
3125{
3126 thread_t self = current_thread();
3127
3128 while (p->sigwait || p->exit_thread) {
3129 if (p->exit_thread) {
3130 return(0);
3131 }
3132 msleep((caddr_t)&p->sigwait_thread, &p->p_mlock, PCATCH | PDROP, 0, 0);
3133 if (thread_should_abort(self)) {
3134 /*
3135 * Terminate request - clean up.
3136 */
3137 proc_lock(p);
3138 return -1;
3139 }
3140 proc_lock(p);
3141 }
3142 return 1;
3143}