]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_sig.c
xnu-1504.15.3.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
337 if (uc->cr_ruid == my_cred->cr_ruid ||
338 uc->cr_ruid == my_cred->cr_svuid ||
339 kauth_cred_getuid(uc) == my_cred->cr_ruid ||
b0d623f7 340 kauth_cred_getuid(uc) == my_cred->cr_svuid) {
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
569 * onnon-PPC platforms.
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
A
625
626#ifdef __ppc__
627 if (signum == SIGFPE) {
628 if (sa->sa_handler == SIG_DFL || sa->sa_handler == SIG_IGN)
b0d623f7 629 thread_enable_fpe(thread, 0);
9bccf70c 630 else
b0d623f7 631 thread_enable_fpe(thread, 1);
9bccf70c
A
632 }
633#endif /* __ppc__ */
1c79356b
A
634 /*
635 * Set bit in p_sigignore for signals that are set to SIG_IGN,
636 * and for signals set to SIG_DFL where the default is to ignore.
637 * However, don't put SIGCONT in p_sigignore,
638 * as we have to restart the process.
639 */
640 if (sa->sa_handler == SIG_IGN ||
641 (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
1c79356b 642
b0d623f7 643 clear_procsiglist(p, bit, in_sigstart);
1c79356b
A
644 if (signum != SIGCONT)
645 p->p_sigignore |= bit; /* easier in psignal */
646 p->p_sigcatch &= ~bit;
647 } else {
648 p->p_sigignore &= ~bit;
649 if (sa->sa_handler == SIG_DFL)
650 p->p_sigcatch &= ~bit;
651 else
652 p->p_sigcatch |= bit;
653 }
9bccf70c 654 return(0);
1c79356b
A
655}
656
657/*
658 * Initialize signal state for process 0;
659 * set to ignore signals that are ignored by default.
660 */
661void
2d21ac55 662siginit(proc_t p)
1c79356b 663{
2d21ac55 664 int i;
1c79356b
A
665
666 for (i = 0; i < NSIG; i++)
667 if (sigprop[i] & SA_IGNORE && i != SIGCONT)
668 p->p_sigignore |= sigmask(i);
669}
670
671/*
672 * Reset signals for an exec of the specified process.
673 */
674void
2d21ac55 675execsigs(proc_t p, thread_t thread)
1c79356b 676{
2d21ac55
A
677 struct sigacts *ps = p->p_sigacts;
678 int nc, mask;
679 struct uthread *ut;
1c79356b 680
2d21ac55 681 ut = (struct uthread *)get_bsdthread_info(thread);
b0d623f7
A
682
683 /*
684 * transfer saved signal states from the process
685 * back to the current thread.
686 *
687 * NOTE: We do this without the process locked,
688 * because we are guaranteed to be single-threaded
689 * by this point in exec and the p_siglist is
690 * only accessed by threads inside the process.
691 */
692 ut->uu_siglist |= p->p_siglist;
693 p->p_siglist = 0;
694
1c79356b
A
695 /*
696 * Reset caught signals. Held signals remain held
697 * through p_sigmask (unless they were caught,
698 * and are now ignored by default).
699 */
700 while (p->p_sigcatch) {
701 nc = ffs((long)p->p_sigcatch);
702 mask = sigmask(nc);
703 p->p_sigcatch &= ~mask;
704 if (sigprop[nc] & SA_IGNORE) {
705 if (nc != SIGCONT)
706 p->p_sigignore |= mask;
b0d623f7 707 ut->uu_siglist &= ~mask;
1c79356b
A
708 }
709 ps->ps_sigact[nc] = SIG_DFL;
710 }
b0d623f7 711
1c79356b
A
712 /*
713 * Reset stack state to the user stack.
714 * Clear set of signals caught on the signal stack.
715 */
2d21ac55
A
716 /* thread */
717 ut->uu_sigstk.ss_flags = SA_DISABLE;
718 ut->uu_sigstk.ss_size = 0;
719 ut->uu_sigstk.ss_sp = USER_ADDR_NULL;
720 ut->uu_flag &= ~UT_ALTSTACK;
721 /* process */
0c530ab8 722 ps->ps_sigonstack = 0;
1c79356b
A
723}
724
725/*
726 * Manipulate signal mask.
727 * Note that we receive new mask, not pointer,
728 * and return old mask as return value;
729 * the library stub does the rest.
730 */
1c79356b 731int
b0d623f7 732sigprocmask(proc_t p, struct sigprocmask_args *uap, __unused int32_t *retval)
1c79356b
A
733{
734 int error = 0;
9bccf70c 735 sigset_t oldmask, nmask;
91447636 736 user_addr_t omask = uap->omask;
9bccf70c 737 struct uthread *ut;
1c79356b 738
91447636 739 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
740 oldmask = ut->uu_sigmask;
741
91447636 742 if (uap->mask == USER_ADDR_NULL) {
9bccf70c
A
743 /* just want old mask */
744 goto out;
745 }
91447636 746 error = copyin(uap->mask, &nmask, sizeof(sigset_t));
9bccf70c
A
747 if (error)
748 goto out;
1c79356b
A
749
750 switch (uap->how) {
751 case SIG_BLOCK:
9bccf70c 752 block_procsigmask(p, (nmask & ~sigcantmask));
91447636 753 signal_setast(current_thread());
1c79356b
A
754 break;
755
756 case SIG_UNBLOCK:
9bccf70c 757 unblock_procsigmask(p, (nmask & ~sigcantmask));
91447636 758 signal_setast(current_thread());
1c79356b
A
759 break;
760
761 case SIG_SETMASK:
9bccf70c 762 set_procsigmask(p, (nmask & ~sigcantmask));
91447636 763 signal_setast(current_thread());
1c79356b
A
764 break;
765
766 default:
767 error = EINVAL;
768 break;
769 }
9bccf70c 770out:
91447636 771 if (!error && omask != USER_ADDR_NULL)
9bccf70c 772 copyout(&oldmask, omask, sizeof(sigset_t));
1c79356b
A
773 return (error);
774}
775
1c79356b 776int
b0d623f7 777sigpending(__unused proc_t p, struct sigpending_args *uap, __unused int32_t *retval)
1c79356b 778{
9bccf70c
A
779 struct uthread *ut;
780 sigset_t pendlist;
1c79356b 781
91447636 782 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
783 pendlist = ut->uu_siglist;
784
785 if (uap->osv)
786 copyout(&pendlist, uap->osv, sizeof(sigset_t));
787 return(0);
1c79356b
A
788}
789
1c79356b
A
790/*
791 * Suspend process until signal, providing mask to be set
792 * in the meantime. Note nonstandard calling convention:
793 * libc stub passes mask, not pointer, to save a copyin.
794 */
795
91447636
A
796static int
797sigcontinue(__unused int error)
1c79356b 798{
91447636 799// struct uthread *ut = get_bsdthread_info(current_thread());
2d21ac55
A
800 unix_syscall_return(EINTR);
801}
802
803int
b0d623f7 804sigsuspend(proc_t p, struct sigsuspend_args *uap, int32_t *retval)
2d21ac55
A
805{
806 __pthread_testcancel(1);
807 return(sigsuspend_nocancel(p, (struct sigsuspend_nocancel_args *)uap, retval));
1c79356b
A
808}
809
1c79356b 810int
b0d623f7 811sigsuspend_nocancel(proc_t p, struct sigsuspend_nocancel_args *uap, __unused int32_t *retval)
1c79356b 812{
9bccf70c
A
813 struct uthread *ut;
814
91447636 815 ut = (struct uthread *)get_bsdthread_info(current_thread());
1c79356b
A
816
817 /*
818 * When returning from sigpause, we want
819 * the old mask to be restored after the
820 * signal handler has finished. Thus, we
821 * save it here and mark the sigacts structure
822 * to indicate this.
823 */
9bccf70c 824 ut->uu_oldmask = ut->uu_sigmask;
91447636 825 ut->uu_flag |= UT_SAS_OLDMASK;
9bccf70c 826 ut->uu_sigmask = (uap->mask & ~sigcantmask);
1c79356b
A
827 (void) tsleep0((caddr_t) p, PPAUSE|PCATCH, "pause", 0, sigcontinue);
828 /* always return EINTR rather than ERESTART... */
829 return (EINTR);
830}
831
9bccf70c
A
832
833int
2d21ac55
A
834__disable_threadsignal(__unused proc_t p,
835 __unused struct __disable_threadsignal_args *uap,
b0d623f7 836 __unused int32_t *retval)
9bccf70c
A
837{
838 struct uthread *uth;
839
91447636 840 uth = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
841
842 /* No longer valid to have any signal delivered */
2d21ac55 843 uth->uu_flag |= (UT_NO_SIGMASK | UT_CANCELDISABLE);
9bccf70c
A
844
845 return(0);
846
847}
848
2d21ac55
A
849void
850__pthread_testcancel(int presyscall)
851{
852
853 thread_t self = current_thread();
854 struct uthread * uthread;
855
856 uthread = (struct uthread *)get_bsdthread_info(self);
857
858
859 uthread->uu_flag &= ~UT_NOTCANCELPT;
860
861 if ((uthread->uu_flag & (UT_CANCELDISABLE | UT_CANCEL | UT_CANCELED)) == UT_CANCEL) {
862 if(presyscall != 0) {
863 unix_syscall_return(EINTR);
864 /* NOTREACHED */
865 } else
866 thread_abort_safely(self);
867 }
868}
869
870
9bccf70c 871
91447636 872int
2d21ac55 873__pthread_markcancel(__unused proc_t p,
b0d623f7 874 struct __pthread_markcancel_args *uap, __unused int32_t *retval)
9bccf70c
A
875{
876 thread_act_t target_act;
877 int error = 0;
9bccf70c
A
878 struct uthread *uth;
879
91447636 880 target_act = (thread_act_t)port_name_to_thread(uap->thread_port);
9bccf70c
A
881
882 if (target_act == THR_ACT_NULL)
883 return (ESRCH);
91447636
A
884
885 uth = (struct uthread *)get_bsdthread_info(target_act);
886
887 /* if the thread is in vfork do not cancel */
2d21ac55 888 if ((uth->uu_flag & (UT_VFORK | UT_CANCEL | UT_CANCELED )) == 0) {
91447636
A
889 uth->uu_flag |= (UT_CANCEL | UT_NO_SIGMASK);
890 if (((uth->uu_flag & UT_NOTCANCELPT) == 0)
891 && ((uth->uu_flag & UT_CANCELDISABLE) == 0))
892 thread_abort_safely(target_act);
893 }
894
895 thread_deallocate(target_act);
896 return (error);
897}
898
899/* if action =0 ; return the cancellation state ,
900 * if marked for cancellation, make the thread canceled
901 * if action = 1 ; Enable the cancel handling
902 * if action = 2; Disable the cancel handling
903 */
904int
2d21ac55 905__pthread_canceled(__unused proc_t p,
b0d623f7 906 struct __pthread_canceled_args *uap, __unused int32_t *retval)
91447636 907{
2d21ac55 908 thread_act_t thread;
91447636
A
909 struct uthread *uth;
910 int action = uap->action;
911
2d21ac55
A
912 thread = current_thread();
913 uth = (struct uthread *)get_bsdthread_info(thread);
91447636
A
914
915 switch (action) {
916 case 1:
917 uth->uu_flag &= ~UT_CANCELDISABLE;
918 return(0);
919 case 2:
920 uth->uu_flag |= UT_CANCELDISABLE;
921 return(0);
922 case 0:
923 default:
924 /* if the thread is in vfork do not cancel */
925 if((uth->uu_flag & ( UT_CANCELDISABLE | UT_CANCEL | UT_CANCELED)) == UT_CANCEL) {
926 uth->uu_flag &= ~UT_CANCEL;
927 uth->uu_flag |= (UT_CANCELED | UT_NO_SIGMASK);
928 return(0);
929 }
930 return(EINVAL);
931 }
932 return(EINVAL);
933}
934
935void
936__posix_sem_syscall_return(kern_return_t kern_result)
937{
938 int error = 0;
939
940 if (kern_result == KERN_SUCCESS)
941 error = 0;
942 else if (kern_result == KERN_ABORTED)
943 error = EINTR;
944 else if (kern_result == KERN_OPERATION_TIMED_OUT)
945 error = ETIMEDOUT;
946 else
947 error = EINVAL;
948 unix_syscall_return(error);
949 /* does not return */
950}
951
b0d623f7 952#if OLD_SEMWAIT_SIGNAL
2d21ac55
A
953/*
954 * Returns: 0 Success
955 * EINTR
956 * ETIMEDOUT
957 * EINVAL
b0d623f7 958 * EFAULT if timespec is NULL
2d21ac55
A
959 */
960int
b0d623f7
A
961__old_semwait_signal(proc_t p, struct __old_semwait_signal_args *uap,
962 int32_t *retval)
2d21ac55
A
963{
964 __pthread_testcancel(0);
b0d623f7 965 return(__old_semwait_signal_nocancel(p, (struct __old_semwait_signal_nocancel_args *)uap, retval));
2d21ac55 966}
91447636
A
967
968int
b0d623f7
A
969__old_semwait_signal_nocancel(proc_t p, struct __old_semwait_signal_nocancel_args *uap,
970 __unused int32_t *retval)
91447636 971{
b0d623f7 972
91447636 973 kern_return_t kern_result;
b0d623f7 974 int error;
91447636
A
975 mach_timespec_t then;
976 struct timespec now;
b0d623f7
A
977 struct user_timespec ts;
978 boolean_t truncated_timeout = FALSE;
979
91447636 980 if(uap->timeout) {
b0d623f7
A
981
982 if (IS_64BIT_PROCESS(p)) {
983 struct user64_timespec ts64;
984 error = copyin(uap->ts, &ts64, sizeof(ts64));
985 ts.tv_sec = ts64.tv_sec;
986 ts.tv_nsec = ts64.tv_nsec;
987 } else {
988 struct user32_timespec ts32;
989 error = copyin(uap->ts, &ts32, sizeof(ts32));
990 ts.tv_sec = ts32.tv_sec;
991 ts.tv_nsec = ts32.tv_nsec;
992 }
993
994 if (error) {
995 return error;
996 }
997
998 if ((ts.tv_sec & 0xFFFFFFFF00000000ULL) != 0) {
999 ts.tv_sec = 0xFFFFFFFF;
1000 ts.tv_nsec = 0;
1001 truncated_timeout = TRUE;
1002 }
1003
91447636 1004 if (uap->relative) {
b0d623f7
A
1005 then.tv_sec = ts.tv_sec;
1006 then.tv_nsec = ts.tv_nsec;
91447636
A
1007 } else {
1008 nanotime(&now);
b0d623f7 1009
2d21ac55 1010 /* if time has elapsed, set time to null timepsec to bailout rightaway */
b0d623f7
A
1011 if (now.tv_sec == ts.tv_sec ?
1012 now.tv_nsec > ts.tv_nsec :
1013 now.tv_sec > ts.tv_sec) {
2d21ac55
A
1014 then.tv_sec = 0;
1015 then.tv_nsec = 0;
b0d623f7
A
1016 } else {
1017 then.tv_sec = ts.tv_sec - now.tv_sec;
1018 then.tv_nsec = ts.tv_nsec - now.tv_nsec;
1019 if (then.tv_nsec < 0) {
1020 then.tv_nsec += NSEC_PER_SEC;
1021 then.tv_sec--;
1022 }
2d21ac55 1023 }
91447636 1024 }
b0d623f7 1025
2d21ac55
A
1026 if (uap->mutex_sem == 0)
1027 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
1028 else
1029 kern_result = semaphore_timedwait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
b0d623f7 1030
91447636 1031 } else {
b0d623f7 1032
2d21ac55 1033 if (uap->mutex_sem == 0)
91447636
A
1034 kern_result = semaphore_wait_trap_internal(uap->cond_sem, __posix_sem_syscall_return);
1035 else
b0d623f7 1036
91447636
A
1037 kern_result = semaphore_wait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, __posix_sem_syscall_return);
1038 }
b0d623f7
A
1039
1040 if (kern_result == KERN_SUCCESS && !truncated_timeout)
91447636 1041 return(0);
b0d623f7
A
1042 else if (kern_result == KERN_SUCCESS && truncated_timeout)
1043 return(EINTR); /* simulate an exceptional condition because Mach doesn't support a longer timeout */
1044 else if (kern_result == KERN_ABORTED)
1045 return(EINTR);
1046 else if (kern_result == KERN_OPERATION_TIMED_OUT)
1047 return(ETIMEDOUT);
1048 else
1049 return(EINVAL);
1050}
1051#endif /* OLD_SEMWAIT_SIGNAL*/
1052
1053/*
1054 * Returns: 0 Success
1055 * EINTR
1056 * ETIMEDOUT
1057 * EINVAL
1058 * EFAULT if timespec is NULL
1059 */
1060int
1061__semwait_signal(proc_t p, struct __semwait_signal_args *uap,
1062 int32_t *retval)
1063{
1064 __pthread_testcancel(0);
1065 return(__semwait_signal_nocancel(p, (struct __semwait_signal_nocancel_args *)uap, retval));
1066}
1067
1068int
1069__semwait_signal_nocancel(__unused proc_t p, struct __semwait_signal_nocancel_args *uap,
1070 __unused int32_t *retval)
1071{
1072
1073 kern_return_t kern_result;
1074 mach_timespec_t then;
1075 struct timespec now;
1076 struct user_timespec ts;
1077 boolean_t truncated_timeout = FALSE;
1078
1079 if(uap->timeout) {
1080
1081 ts.tv_sec = uap->tv_sec;
1082 ts.tv_nsec = uap->tv_nsec;
1083
1084 if ((ts.tv_sec & 0xFFFFFFFF00000000ULL) != 0) {
1085 ts.tv_sec = 0xFFFFFFFF;
1086 ts.tv_nsec = 0;
1087 truncated_timeout = TRUE;
1088 }
1089
1090 if (uap->relative) {
1091 then.tv_sec = ts.tv_sec;
1092 then.tv_nsec = ts.tv_nsec;
1093 } else {
1094 nanotime(&now);
1095
1096 /* if time has elapsed, set time to null timepsec to bailout rightaway */
1097 if (now.tv_sec == ts.tv_sec ?
1098 now.tv_nsec > ts.tv_nsec :
1099 now.tv_sec > ts.tv_sec) {
1100 then.tv_sec = 0;
1101 then.tv_nsec = 0;
1102 } else {
1103 then.tv_sec = ts.tv_sec - now.tv_sec;
1104 then.tv_nsec = ts.tv_nsec - now.tv_nsec;
1105 if (then.tv_nsec < 0) {
1106 then.tv_nsec += NSEC_PER_SEC;
1107 then.tv_sec--;
1108 }
1109 }
1110 }
1111
1112 if (uap->mutex_sem == 0)
1113 kern_result = semaphore_timedwait_trap_internal((mach_port_name_t)uap->cond_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
1114 else
1115 kern_result = semaphore_timedwait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
1116
1117 } else {
1118
1119 if (uap->mutex_sem == 0)
1120 kern_result = semaphore_wait_trap_internal(uap->cond_sem, __posix_sem_syscall_return);
1121 else
1122
1123 kern_result = semaphore_wait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, __posix_sem_syscall_return);
1124 }
1125
1126 if (kern_result == KERN_SUCCESS && !truncated_timeout)
1127 return(0);
1128 else if (kern_result == KERN_SUCCESS && truncated_timeout)
1129 return(EINTR); /* simulate an exceptional condition because Mach doesn't support a longer timeout */
91447636
A
1130 else if (kern_result == KERN_ABORTED)
1131 return(EINTR);
1132 else if (kern_result == KERN_OPERATION_TIMED_OUT)
1133 return(ETIMEDOUT);
1134 else
1135 return(EINVAL);
1136}
1137
b0d623f7 1138
91447636 1139int
2d21ac55 1140__pthread_kill(__unused proc_t p, struct __pthread_kill_args *uap,
b0d623f7 1141 __unused int32_t *retval)
91447636
A
1142{
1143 thread_t target_act;
1144 int error = 0;
1145 int signum = uap->sig;
1146 struct uthread *uth;
1147
1148 target_act = (thread_t)port_name_to_thread(uap->thread_port);
1149
1150 if (target_act == THREAD_NULL)
1151 return (ESRCH);
9bccf70c
A
1152 if ((u_int)signum >= NSIG) {
1153 error = EINVAL;
1154 goto out;
1155 }
1156
1157 uth = (struct uthread *)get_bsdthread_info(target_act);
55e303ae 1158
91447636 1159 if (uth->uu_flag & UT_NO_SIGMASK) {
9bccf70c
A
1160 error = ESRCH;
1161 goto out;
1162 }
1163
1164 if (signum)
1165 psignal_uthread(target_act, signum);
1166out:
91447636 1167 thread_deallocate(target_act);
9bccf70c
A
1168 return (error);
1169}
1170
1171
9bccf70c 1172int
2d21ac55 1173__pthread_sigmask(__unused proc_t p, struct __pthread_sigmask_args *uap,
b0d623f7 1174 __unused int32_t *retval)
9bccf70c 1175{
91447636
A
1176 user_addr_t set = uap->set;
1177 user_addr_t oset = uap->oset;
1178 sigset_t nset;
9bccf70c
A
1179 int error = 0;
1180 struct uthread *ut;
1181 sigset_t oldset;
1182
91447636 1183 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c
A
1184 oldset = ut->uu_sigmask;
1185
91447636 1186 if (set == USER_ADDR_NULL) {
9bccf70c
A
1187 /* need only old mask */
1188 goto out;
1189 }
1190
91447636 1191 error = copyin(set, &nset, sizeof(sigset_t));
9bccf70c
A
1192 if (error)
1193 goto out;
1194
1195 switch (uap->how) {
1196 case SIG_BLOCK:
1197 ut->uu_sigmask |= (nset & ~sigcantmask);
1198 break;
1199
1200 case SIG_UNBLOCK:
1201 ut->uu_sigmask &= ~(nset);
91447636 1202 signal_setast(current_thread());
9bccf70c
A
1203 break;
1204
1205 case SIG_SETMASK:
1206 ut->uu_sigmask = (nset & ~sigcantmask);
91447636 1207 signal_setast(current_thread());
9bccf70c
A
1208 break;
1209
1210 default:
1211 error = EINVAL;
1212
1213 }
1214out:
91447636
A
1215 if (!error && oset != USER_ADDR_NULL)
1216 copyout(&oldset, oset, sizeof(sigset_t));
9bccf70c
A
1217
1218 return(error);
1219}
1220
2d21ac55
A
1221/*
1222 * Returns: 0 Success
1223 * EINVAL
1224 * copyin:EFAULT
1225 * copyout:EFAULT
1226 */
1227int
b0d623f7 1228__sigwait(proc_t p, struct __sigwait_args *uap, int32_t *retval)
2d21ac55
A
1229{
1230 __pthread_testcancel(1);
1231 return(__sigwait_nocancel(p, (struct __sigwait_nocancel_args *)uap, retval));
1232}
9bccf70c 1233
9bccf70c 1234int
b0d623f7 1235__sigwait_nocancel(proc_t p, struct __sigwait_nocancel_args *uap, __unused int32_t *retval)
9bccf70c 1236{
9bccf70c
A
1237 struct uthread *ut;
1238 struct uthread *uth;
9bccf70c
A
1239 int error = 0;
1240 sigset_t mask;
1241 sigset_t siglist;
1242 sigset_t sigw=0;
1243 int signum;
1244
91447636 1245 ut = (struct uthread *)get_bsdthread_info(current_thread());
9bccf70c 1246
91447636 1247 if (uap->set == USER_ADDR_NULL)
9bccf70c
A
1248 return(EINVAL);
1249
91447636 1250 error = copyin(uap->set, &mask, sizeof(sigset_t));
9bccf70c
A
1251 if (error)
1252 return(error);
1253
1254 siglist = (mask & ~sigcantmask);
1255
1256 if (siglist == 0)
1257 return(EINVAL);
1258
2d21ac55
A
1259 proc_lock(p);
1260 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
1261 proc_unlock(p);
9bccf70c
A
1262 return(EINVAL);
1263 } else {
2d21ac55 1264 proc_signalstart(p, 1);
9bccf70c 1265 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
91447636 1266 if ( (sigw = uth->uu_siglist & siglist) ) {
9bccf70c
A
1267 break;
1268 }
1269 }
2d21ac55 1270 proc_signalend(p, 1);
9bccf70c 1271 }
2d21ac55 1272
9bccf70c
A
1273 if (sigw) {
1274 /* The signal was pending on a thread */
1275 goto sigwait1;
1276 }
1277 /*
1278 * When returning from sigwait, we want
1279 * the old mask to be restored after the
1280 * signal handler has finished. Thus, we
1281 * save it here and mark the sigacts structure
1282 * to indicate this.
1283 */
2d21ac55 1284 uth = ut; /* wait for it to be delivered to us */
9bccf70c 1285 ut->uu_oldmask = ut->uu_sigmask;
91447636 1286 ut->uu_flag |= UT_SAS_OLDMASK;
2d21ac55
A
1287 if (siglist == (sigset_t)0) {
1288 proc_unlock(p);
9bccf70c 1289 return(EINVAL);
2d21ac55 1290 }
9bccf70c
A
1291 /* SIGKILL and SIGSTOP are not maskable as well */
1292 ut->uu_sigmask = ~(siglist|sigcantmask);
1293 ut->uu_sigwait = siglist;
2d21ac55 1294
9bccf70c 1295 /* No Continuations for now */
2d21ac55 1296 error = msleep((caddr_t)&ut->uu_sigwait, &p->p_mlock, PPAUSE|PCATCH, "pause", 0);
9bccf70c 1297
b0d623f7 1298 if (error == ERESTART)
9bccf70c
A
1299 error = 0;
1300
1301 sigw = (ut->uu_sigwait & siglist);
1302 ut->uu_sigmask = ut->uu_oldmask;
1303 ut->uu_oldmask = 0;
91447636 1304 ut->uu_flag &= ~UT_SAS_OLDMASK;
9bccf70c
A
1305sigwait1:
1306 ut->uu_sigwait = 0;
1307 if (!error) {
1308 signum = ffs((unsigned int)sigw);
1309 if (!signum)
1310 panic("sigwait with no signal wakeup");
2d21ac55
A
1311 /* Clear the pending signal in the thread it was delivered */
1312 uth->uu_siglist &= ~(sigmask(signum));
b0d623f7
A
1313
1314#if CONFIG_DTRACE
1315 DTRACE_PROC2(signal__clear, int, signum, siginfo_t *, &(ut->t_dtrace_siginfo));
1316#endif
1317
2d21ac55 1318 proc_unlock(p);
91447636 1319 if (uap->sig != USER_ADDR_NULL)
9bccf70c 1320 error = copyout(&signum, uap->sig, sizeof(int));
2d21ac55
A
1321 } else
1322 proc_unlock(p);
9bccf70c
A
1323
1324 return(error);
1325
1326}
1327
1c79356b 1328int
b0d623f7 1329sigaltstack(__unused proc_t p, struct sigaltstack_args *uap, __unused int32_t *retval)
1c79356b 1330{
b0d623f7
A
1331 struct kern_sigaltstack ss;
1332 struct kern_sigaltstack *pstk;
1c79356b 1333 int error;
2d21ac55
A
1334 struct uthread *uth;
1335 int onstack;
1c79356b 1336
0c530ab8 1337 uth = (struct uthread *)get_bsdthread_info(current_thread());
0c530ab8 1338
2d21ac55
A
1339 pstk = &uth->uu_sigstk;
1340 if ((uth->uu_flag & UT_ALTSTACK) == 0)
1341 uth->uu_sigstk.ss_flags |= SA_DISABLE;
1342 onstack = pstk->ss_flags & SA_ONSTACK;
91447636
A
1343 if (uap->oss) {
1344 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
1345 struct user64_sigaltstack ss64;
1346 sigaltstack_kern_to_user64(pstk, &ss64);
1347 error = copyout(&ss64, uap->oss, sizeof(ss64));
91447636 1348 } else {
b0d623f7
A
1349 struct user32_sigaltstack ss32;
1350 sigaltstack_kern_to_user32(pstk, &ss32);
1351 error = copyout(&ss32, uap->oss, sizeof(ss32));
91447636
A
1352 }
1353 if (error)
1354 return (error);
1355 }
1356 if (uap->nss == USER_ADDR_NULL)
1c79356b 1357 return (0);
91447636 1358 if (IS_64BIT_PROCESS(p)) {
b0d623f7
A
1359 struct user64_sigaltstack ss64;
1360 error = copyin(uap->nss, &ss64, sizeof(ss64));
1361 sigaltstack_user64_to_kern(&ss64, &ss);
91447636 1362 } else {
b0d623f7
A
1363 struct user32_sigaltstack ss32;
1364 error = copyin(uap->nss, &ss32, sizeof(ss32));
1365 sigaltstack_user32_to_kern(&ss32, &ss);
91447636
A
1366 }
1367 if (error)
1c79356b 1368 return (error);
9bccf70c
A
1369 if ((ss.ss_flags & ~SA_DISABLE) != 0) {
1370 return(EINVAL);
1371 }
1372
1c79356b 1373 if (ss.ss_flags & SA_DISABLE) {
2d21ac55
A
1374 /* if we are here we are not in the signal handler ;so no need to check */
1375 if (uth->uu_sigstk.ss_flags & SA_ONSTACK)
1376 return (EINVAL);
1377 uth->uu_flag &= ~UT_ALTSTACK;
1378 uth->uu_sigstk.ss_flags = ss.ss_flags;
1c79356b
A
1379 return (0);
1380 }
2d21ac55
A
1381 if (onstack)
1382 return (EPERM);
55e303ae
A
1383/* The older stacksize was 8K, enforce that one so no compat problems */
1384#define OLDMINSIGSTKSZ 8*1024
1385 if (ss.ss_size < OLDMINSIGSTKSZ)
1c79356b 1386 return (ENOMEM);
2d21ac55
A
1387 uth->uu_flag |= UT_ALTSTACK;
1388 uth->uu_sigstk= ss;
1c79356b
A
1389 return (0);
1390}
1391
1c79356b 1392int
b0d623f7 1393kill(proc_t cp, struct kill_args *uap, __unused int32_t *retval)
1c79356b 1394{
2d21ac55 1395 proc_t p;
91447636 1396 kauth_cred_t uc = kauth_cred_get();
2d21ac55 1397 int posix = uap->posix; /* !0 if posix behaviour desired */
91447636
A
1398
1399 AUDIT_ARG(pid, uap->pid);
1400 AUDIT_ARG(signum, uap->signum);
1c79356b
A
1401
1402 if ((u_int)uap->signum >= NSIG)
1403 return (EINVAL);
1404 if (uap->pid > 0) {
1405 /* kill single process */
2d21ac55 1406 if ((p = proc_find(uap->pid)) == NULL) {
55e303ae
A
1407 if ((p = pzfind(uap->pid)) != NULL) {
1408 /*
1409 * IEEE Std 1003.1-2001: return success
1410 * when killing a zombie.
1411 */
1412 return (0);
1413 }
1c79356b 1414 return (ESRCH);
55e303ae 1415 }
e5568f75 1416 AUDIT_ARG(process, p);
2d21ac55
A
1417 if (!cansignal(cp, uc, p, uap->signum, 0)) {
1418 proc_rele(p);
ff6e181a
A
1419 return(EPERM);
1420 }
1c79356b
A
1421 if (uap->signum)
1422 psignal(p, uap->signum);
2d21ac55 1423 proc_rele(p);
1c79356b
A
1424 return (0);
1425 }
1426 switch (uap->pid) {
1427 case -1: /* broadcast signal */
2d21ac55 1428 return (killpg1(cp, uap->signum, 0, 1, posix));
1c79356b 1429 case 0: /* signal own process group */
2d21ac55 1430 return (killpg1(cp, uap->signum, 0, 0, posix));
1c79356b 1431 default: /* negative explicit process group */
2d21ac55 1432 return (killpg1(cp, uap->signum, -(uap->pid), 0, posix));
1c79356b
A
1433 }
1434 /* NOTREACHED */
1435}
1436
2d21ac55
A
1437static int
1438killpg1_filt(proc_t p, void * arg)
1439{
1440 struct killpg1_filtargs * kfargp = (struct killpg1_filtargs *)arg;
1441 proc_t cp = kfargp->cp;
1442 int posix = kfargp->posix;
1443
1444
1445 if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
1446 (!posix && p == cp))
1447 return(0);
1448 else
1449 return(1);
1450}
1451
1452
1453static int
1454killpg1_pgrpfilt(proc_t p, __unused void * arg)
1455{
1456 if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
1457 (p->p_stat == SZOMB))
1458 return(0);
1459 else
1460 return(1);
1461}
1462
1463
1464
1465static int
1466killpg1_callback(proc_t p, void * arg)
1467{
1468 struct killpg1_iterargs * kargp = (struct killpg1_iterargs *)arg;
1469 proc_t cp = kargp->cp;
1470 kauth_cred_t uc = kargp->uc; /* refcounted by the caller safe to use internal fields */
1471 int signum = kargp->signum;
1472 int * nfoundp = kargp->nfoundp;
1473 int n;
b0d623f7
A
1474 int zombie = 0;
1475 int error = 0;
2d21ac55 1476
b0d623f7
A
1477 if ((kargp->zombie != 0) && ((p->p_listflag & P_LIST_EXITED) == P_LIST_EXITED))
1478 zombie = 1;
2d21ac55 1479
b0d623f7
A
1480 if (zombie != 0) {
1481 proc_list_lock();
1482 error = cansignal(cp, uc, p, signum, zombie);
1483 proc_list_unlock();
1484
1485 if (error != 0 && nfoundp != NULL) {
1486 n = *nfoundp;
1487 *nfoundp = n+1;
1488 }
1489 } else {
1490 if (cansignal(cp, uc, p, signum, 0) == 0)
1491 return(PROC_RETURNED);
2d21ac55 1492
b0d623f7
A
1493 if (nfoundp != NULL) {
1494 n = *nfoundp;
1495 *nfoundp = n+1;
1496 }
1497 if (signum != 0)
1498 psignal(p, signum);
2d21ac55 1499 }
2d21ac55
A
1500
1501 return(PROC_RETURNED);
2d21ac55 1502}
1c79356b
A
1503
1504/*
1505 * Common code for kill process group/broadcast kill.
1506 * cp is calling process.
1507 */
1508int
2d21ac55 1509killpg1(proc_t cp, int signum, int pgid, int all, int posix)
1c79356b 1510{
2d21ac55 1511 kauth_cred_t uc;
1c79356b
A
1512 struct pgrp *pgrp;
1513 int nfound = 0;
2d21ac55
A
1514 struct killpg1_iterargs karg;
1515 struct killpg1_filtargs kfarg;
1516 int error = 0;
1c79356b 1517
2d21ac55 1518 uc = kauth_cred_proc_ref(cp);
1c79356b
A
1519 if (all) {
1520 /*
1521 * broadcast
1522 */
2d21ac55
A
1523 kfarg.posix = posix;
1524 kfarg.cp = cp;
1525
1526 karg.cp = cp;
1527 karg.uc = uc;
1528 karg.nfoundp = &nfound;
1529 karg.signum = signum;
b0d623f7 1530 karg.zombie = 1;
2d21ac55 1531
b0d623f7 1532 proc_iterate((PROC_ALLPROCLIST | PROC_ZOMBPROCLIST), killpg1_callback, &karg, killpg1_filt, (void *)&kfarg);
2d21ac55 1533
1c79356b 1534 } else {
2d21ac55 1535 if (pgid == 0) {
1c79356b
A
1536 /*
1537 * zero pgid means send to my process group.
1538 */
2d21ac55
A
1539 pgrp = proc_pgrp(cp);
1540 } else {
1c79356b 1541 pgrp = pgfind(pgid);
2d21ac55
A
1542 if (pgrp == NULL) {
1543 error = ESRCH;
1544 goto out;
1545 }
1c79356b 1546 }
2d21ac55
A
1547
1548 karg.nfoundp = &nfound;
1549 karg.uc = uc;
1550 karg.signum = signum;
1551 karg.cp = cp;
b0d623f7 1552 karg.zombie = 0;
2d21ac55
A
1553
1554
1555 /* PGRP_DROPREF drops the pgrp refernce */
1556 pgrp_iterate(pgrp, PGRP_BLOCKITERATE | PGRP_DROPREF, killpg1_callback, &karg,
1557 killpg1_pgrpfilt, NULL);
1c79356b 1558 }
2d21ac55
A
1559 error = (nfound ? 0 : (posix ? EPERM : ESRCH));
1560out:
1561 kauth_cred_unref(&uc);
1562 return (error);
1c79356b
A
1563}
1564
2d21ac55 1565
1c79356b
A
1566/*
1567 * Send a signal to a process group.
1568 */
1569void
2d21ac55 1570gsignal(int pgid, int signum)
1c79356b
A
1571{
1572 struct pgrp *pgrp;
1573
2d21ac55 1574 if (pgid && (pgrp = pgfind(pgid))) {
1c79356b 1575 pgsignal(pgrp, signum, 0);
2d21ac55
A
1576 pg_rele(pgrp);
1577 }
1c79356b
A
1578}
1579
1580/*
2d21ac55 1581 * Send a signal to a process group. If checkctty is 1,
1c79356b
A
1582 * limit to members which have a controlling terminal.
1583 */
2d21ac55
A
1584
1585static int
1586pgsignal_filt(proc_t p, void * arg)
1c79356b 1587{
b0d623f7 1588 int checkctty = *(int*)arg;
1c79356b 1589
2d21ac55
A
1590 if ((checkctty == 0) || p->p_flag & P_CONTROLT)
1591 return(1);
1592 else
1593 return(0);
1c79356b
A
1594}
1595
2d21ac55
A
1596
1597static int
1598pgsignal_callback(proc_t p, void * arg)
9bccf70c 1599{
b0d623f7 1600 int signum = *(int*)arg;
9bccf70c 1601
2d21ac55
A
1602 psignal(p, signum);
1603 return(PROC_RETURNED);
1604}
1605
1606
1607void
1608pgsignal(struct pgrp *pgrp, int signum, int checkctty)
1609{
1610 if (pgrp != PGRP_NULL) {
b0d623f7 1611 pgrp_iterate(pgrp, PGRP_BLOCKITERATE, pgsignal_callback, &signum, pgsignal_filt, &checkctty);
2d21ac55 1612 }
9bccf70c
A
1613}
1614
2d21ac55
A
1615
1616void
1617tty_pgsignal(struct tty *tp, int signum, int checkctty)
1618{
1619 struct pgrp * pg;
1620
1621 pg = tty_pgrp(tp);
1622 if (pg != PGRP_NULL) {
b0d623f7 1623 pgrp_iterate(pg, PGRP_BLOCKITERATE, pgsignal_callback, &signum, pgsignal_filt, &checkctty);
2d21ac55
A
1624 pg_rele(pg);
1625 }
1626}
1c79356b
A
1627/*
1628 * Send a signal caused by a trap to a specific thread.
1629 */
1630void
2d21ac55 1631threadsignal(thread_t sig_actthread, int signum, mach_exception_code_t code)
1c79356b 1632{
2d21ac55
A
1633 struct uthread *uth;
1634 struct task * sig_task;
1635 proc_t p;
1c79356b
A
1636 int mask;
1637
1638 if ((u_int)signum >= NSIG || signum == 0)
1639 return;
1640
1641 mask = sigmask(signum);
1642 if ((mask & threadmask) == 0)
1643 return;
1644 sig_task = get_threadtask(sig_actthread);
2d21ac55 1645 p = (proc_t)(get_bsdtask_info(sig_task));
1c79356b 1646
0b4e3aa0 1647 uth = get_bsdthread_info(sig_actthread);
91447636 1648 if (uth && (uth->uu_flag & UT_VFORK))
0b4e3aa0
A
1649 p = uth->uu_proc;
1650
2d21ac55
A
1651 proc_lock(p);
1652 if (!(p->p_lflag & P_LTRACED) && (p->p_sigignore & mask)) {
1653 proc_unlock(p);
1c79356b 1654 return;
2d21ac55 1655 }
1c79356b 1656
9bccf70c 1657 uth->uu_siglist |= mask;
1c79356b 1658 uth->uu_code = code;
2d21ac55
A
1659 proc_unlock(p);
1660
1c79356b 1661 /* mark on process as well */
1c79356b
A
1662 signal_setast(sig_actthread);
1663}
1664
2d21ac55
A
1665static kern_return_t
1666get_signalthread(proc_t p, int signum, thread_t * thr)
1c79356b 1667{
2d21ac55
A
1668 struct uthread *uth;
1669 sigset_t mask = sigmask(signum);
1670 thread_t sig_thread;
1671 struct task * sig_task = p->task;
1672 kern_return_t kret;
1673
1674 *thr = THREAD_NULL;
1675
1676 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
1677 sig_thread = p->p_vforkact;
1678 kret = check_actforsig(sig_task, sig_thread, 1);
1679 if (kret == KERN_SUCCESS) {
1680 *thr = sig_thread;
1681 return(KERN_SUCCESS);
1682 }else
1683 return(KERN_FAILURE);
1684 }
1685
1686 proc_lock(p);
1687 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
1688 if(((uth->uu_flag & UT_NO_SIGMASK)== 0) &&
1689 (((uth->uu_sigmask & mask) == 0) || (uth->uu_sigwait & mask))) {
1690 if (check_actforsig(p->task, uth->uu_context.vc_thread, 1) == KERN_SUCCESS) {
1691 *thr = uth->uu_context.vc_thread;
1692 proc_unlock(p);
1693 return(KERN_SUCCESS);
1694 }
1695 }
1696 }
1697 proc_unlock(p);
1698 if (get_signalact(p->task, thr, 1) == KERN_SUCCESS) {
1699 return(KERN_SUCCESS);
1700 }
1701
1702 return(KERN_FAILURE);
1c79356b
A
1703}
1704
2d21ac55
A
1705/*
1706 * Send the signal to the process. If the signal has an action, the action
1707 * is usually performed by the target process rather than the caller; we add
1708 * the signal to the set of pending signals for the process.
1709 *
1710 * Exceptions:
1711 * o When a stop signal is sent to a sleeping process that takes the
1712 * default action, the process is stopped without awakening it.
1713 * o SIGCONT restarts stopped processes (or puts them back to sleep)
1714 * regardless of the signal action (eg, blocked or ignored).
1715 *
1716 * Other ignored signals are discarded immediately.
1717 */
1718static void
1719psignal_internal(proc_t p, task_t task, thread_t thread, int flavor, int signum)
0b4e3aa0 1720{
2d21ac55
A
1721 int prop;
1722 sig_t action = NULL;
1723 proc_t sig_proc;
1724 thread_t sig_thread;
1725 register task_t sig_task;
0b4e3aa0 1726 int mask;
9bccf70c 1727 struct uthread *uth;
2d21ac55
A
1728 kern_return_t kret;
1729 uid_t r_uid;
1730 proc_t pp;
1731 kauth_cred_t my_cred;
0b4e3aa0
A
1732
1733 if ((u_int)signum >= NSIG || signum == 0)
1734 panic("psignal signal number");
1735 mask = sigmask(signum);
1736 prop = sigprop[signum];
1737
1738#if SIGNAL_DEBUG
2d21ac55 1739 if(rdebug_proc && (p != PROC_NULL) && (p == rdebug_proc)) {
0b4e3aa0
A
1740 ram_printf(3);
1741 }
1742#endif /* SIGNAL_DEBUG */
1743
1c79356b
A
1744 /*
1745 * We will need the task pointer later. Grab it now to
1746 * check for a zombie process. Also don't send signals
1747 * to kernel internal tasks.
1748 */
2d21ac55
A
1749 if (flavor & PSIG_VFORK) {
1750 sig_task = task;
1751 sig_thread = thread;
1752 sig_proc= p;
1753 } else if (flavor & PSIG_THREAD) {
1754 sig_task = get_threadtask(thread);
1755 sig_thread = thread;
1756 sig_proc = (proc_t)get_bsdtask_info(sig_task);
1757 } else {
1758 sig_task = p->task;
1759 sig_proc = p;
1760 sig_thread = (struct thread *)0;
1761 }
1762 if (((sig_task == TASK_NULL) || is_kerneltask(sig_task))) {
1c79356b 1763 return;
7b1edb79 1764 }
1c79356b
A
1765
1766 /*
1767 * do not send signals to the process that has the thread
1768 * doing a reboot(). Not doing so will mark that thread aborted
1769 * and can cause IO failures wich will cause data loss.
1770 */
2d21ac55 1771 if (ISSET(sig_proc->p_flag, P_REBOOT)) {
1c79356b 1772 return;
7b1edb79 1773 }
1c79356b 1774
2d21ac55
A
1775 if( (flavor & (PSIG_VFORK | PSIG_THREAD)) == 0) {
1776 proc_knote(sig_proc, NOTE_SIGNAL | signum);
1777 }
1778
1779
1780 if ((flavor & PSIG_LOCKED)== 0)
1781 proc_signalstart(sig_proc, 0);
9bccf70c
A
1782
1783 /*
1784 * Deliver the signal to the first thread in the task. This
1785 * allows single threaded applications which use signals to
1786 * be able to be linked with multithreaded libraries. We have
55e303ae 1787 * an implicit reference to the current thread, but need
9bccf70c
A
1788 * an explicit one otherwise. The thread reference keeps
1789 * the corresponding task data structures around too. This
1790 * reference is released by thread_deallocate.
1c79356b 1791 */
9bccf70c 1792
9bccf70c 1793
2d21ac55
A
1794 if (((flavor & PSIG_VFORK) == 0) && ((sig_proc->p_lflag & P_LTRACED) == 0) && (sig_proc->p_sigignore & mask)) {
1795 DTRACE_PROC3(signal__discard, thread_t, sig_thread, proc_t, sig_proc, int, signum);
1796 goto psigout;
1797 }
9bccf70c 1798
2d21ac55
A
1799 if (flavor & PSIG_VFORK) {
1800 action = SIG_DFL;
1801 act_set_astbsd(sig_thread);
1802 kret = KERN_SUCCESS;
1803 } else if (flavor & PSIG_THREAD) {
1804 /* If successful return with ast set */
1805 kret = check_actforsig(sig_task, sig_thread, 1);
1806 } else {
1807 /* If successful return with ast set */
1808 kret = get_signalthread(sig_proc, signum, &sig_thread);
1809 }
1810 if (kret != KERN_SUCCESS) {
9bccf70c
A
1811#if SIGNAL_DEBUG
1812 ram_printf(1);
1813#endif /* SIGNAL_DEBUG */
1814 goto psigout;
1c79356b
A
1815 }
1816
2d21ac55
A
1817
1818 uth = get_bsdthread_info(sig_thread);
1c79356b
A
1819
1820 /*
1821 * If proc is traced, always give parent a chance.
1822 */
2d21ac55
A
1823
1824 if ((flavor & PSIG_VFORK) == 0) {
1825 if (sig_proc->p_lflag & P_LTRACED)
1c79356b 1826 action = SIG_DFL;
2d21ac55
A
1827 else {
1828 /*
1829 * If the signal is being ignored,
1830 * then we forget about it immediately.
1831 * (Note: we don't set SIGCONT in p_sigignore,
1832 * and if it is set to SIG_IGN,
1833 * action will be SIG_DFL here.)
1834 */
1835 if (sig_proc->p_sigignore & mask)
1836 goto psigout;
1837 if (uth->uu_sigwait & mask)
1838 action = KERN_SIG_WAIT;
1839 else if (uth->uu_sigmask & mask)
1840 action = KERN_SIG_HOLD;
1841 else if (sig_proc->p_sigcatch & mask)
1842 action = KERN_SIG_CATCH;
1843 else
1844 action = SIG_DFL;
1845 }
1c79356b
A
1846 }
1847
1c79356b 1848
2d21ac55
A
1849 proc_lock(sig_proc);
1850
1851 if (sig_proc->p_nice > NZERO && action == SIG_DFL && (prop & SA_KILL) &&
1852 (sig_proc->p_lflag & P_LTRACED) == 0)
1853 sig_proc->p_nice = NZERO;
1854
1855 if (prop & SA_CONT)
9bccf70c 1856 uth->uu_siglist &= ~stopsigmask;
1c79356b
A
1857
1858 if (prop & SA_STOP) {
2d21ac55 1859 struct pgrp *pg;
1c79356b
A
1860 /*
1861 * If sending a tty stop signal to a member of an orphaned
1862 * process group, discard the signal here if the action
1863 * is default; don't stop the process below if sleeping,
1864 * and don't clear any pending SIGCONT.
1865 */
2d21ac55
A
1866 proc_unlock(sig_proc);
1867 pg = proc_pgrp(sig_proc);
1868 if (prop & SA_TTYSTOP && pg->pg_jobc == 0 &&
1869 action == SIG_DFL) {
1870 pg_rele(pg);
1c79356b 1871 goto psigout;
2d21ac55
A
1872 }
1873 pg_rele(pg);
1874 proc_lock(sig_proc);
9bccf70c 1875 uth->uu_siglist &= ~contsigmask;
1c79356b 1876 }
2d21ac55 1877
9bccf70c 1878 uth->uu_siglist |= mask;
2d21ac55
A
1879 /*
1880 * Repost AST incase sigthread has processed
1881 * ast and missed signal post.
1882 */
1883 if (action == KERN_SIG_CATCH)
1884 act_set_astbsd(sig_thread);
1c79356b 1885
9bccf70c 1886
1c79356b
A
1887 /*
1888 * Defer further processing for signals which are held,
1889 * except that stopped processes must be continued by SIGCONT.
1890 */
2d21ac55
A
1891 /* vfork will not go thru as action is SIG_DFL */
1892 if ((action == KERN_SIG_HOLD) && ((prop & SA_CONT) == 0 || sig_proc->p_stat != SSTOP)) {
1893 proc_unlock(sig_proc);
1c79356b 1894 goto psigout;
9bccf70c
A
1895 }
1896 /*
1897 * SIGKILL priority twiddling moved here from above because
1898 * it needs sig_thread. Could merge it into large switch
1899 * below if we didn't care about priority for tracing
1900 * as SIGKILL's action is always SIG_DFL.
1901 */
2d21ac55
A
1902 if ((signum == SIGKILL) && (sig_proc->p_nice > NZERO)) {
1903 sig_proc->p_nice = NZERO;
9bccf70c
A
1904 }
1905
1906 /*
1907 * Process is traced - wake it up (if not already
1908 * stopped) so that it can discover the signal in
1909 * issig() and stop for the parent.
1910 */
2d21ac55
A
1911 if (sig_proc->p_lflag & P_LTRACED) {
1912 if (sig_proc->p_stat != SSTOP)
1913 goto runlocked;
1914 else {
1915 proc_unlock(sig_proc);
9bccf70c 1916 goto psigout;
2d21ac55 1917 }
9bccf70c 1918 }
2d21ac55
A
1919 if ((flavor & PSIG_VFORK) != 0)
1920 goto runlocked;
9bccf70c 1921
91447636 1922 if (action == KERN_SIG_WAIT) {
b0d623f7
A
1923#if CONFIG_DTRACE
1924 /*
1925 * DTrace proc signal-clear returns a siginfo_t. Collect the needed info.
1926 */
1927 r_uid = kauth_getruid(); /* per thread credential; protected by our thread context */
1928
1929 bzero((caddr_t)&(uth->t_dtrace_siginfo), sizeof(uth->t_dtrace_siginfo));
1930
1931 uth->t_dtrace_siginfo.si_signo = signum;
1932 uth->t_dtrace_siginfo.si_pid = current_proc()->p_pid;
1933 uth->t_dtrace_siginfo.si_status = W_EXITCODE(signum, 0);
1934 uth->t_dtrace_siginfo.si_uid = r_uid;
1935 uth->t_dtrace_siginfo.si_code = 0;
1936#endif
9bccf70c
A
1937 uth->uu_sigwait = mask;
1938 uth->uu_siglist &= ~mask;
9bccf70c
A
1939 wakeup(&uth->uu_sigwait);
1940 /* if it is SIGCONT resume whole process */
91447636 1941 if (prop & SA_CONT) {
b0d623f7 1942 OSBitOrAtomic(P_CONTINUED, &sig_proc->p_flag);
2d21ac55
A
1943 sig_proc->p_contproc = current_proc()->p_pid;
1944
1945 proc_unlock(sig_proc);
9bccf70c 1946 (void) task_resume(sig_task);
2d21ac55 1947 goto psigout;
91447636 1948 }
2d21ac55 1949 proc_unlock(sig_proc);
9bccf70c
A
1950 goto psigout;
1951 }
1952
1953 if (action != SIG_DFL) {
1954 /*
1955 * User wants to catch the signal.
1956 * Wake up the thread, but don't un-suspend it
1957 * (except for SIGCONT).
1958 */
55e303ae 1959 if (prop & SA_CONT) {
b0d623f7 1960 OSBitOrAtomic(P_CONTINUED, &sig_proc->p_flag);
2d21ac55
A
1961 proc_unlock(sig_proc);
1962 (void) task_resume(sig_task);
1963 proc_lock(sig_proc);
1964 sig_proc->p_stat = SRUN;
1965 } else if (sig_proc->p_stat == SSTOP) {
1966 proc_unlock(sig_proc);
9bccf70c 1967 goto psigout;
9bccf70c 1968 }
9bccf70c 1969 /*
2d21ac55
A
1970 * Fill out siginfo structure information to pass to the
1971 * signalled process/thread sigaction handler, when it
1972 * wakes up. si_code is 0 because this is an ordinary
1973 * signal, not a SIGCHLD, and so si_status is the signal
1974 * number itself, instead of the child process exit status.
1975 * We shift this left because it will be shifted right before
1976 * it is passed to user space. kind of ugly to use W_EXITCODE
1977 * this way, but it beats defining a new macro.
1978 *
1979 * Note: Avoid the SIGCHLD recursion case!
9bccf70c 1980 */
2d21ac55
A
1981 if (signum != SIGCHLD) {
1982 proc_unlock(sig_proc);
1983 r_uid = kauth_getruid();
1984 proc_lock(sig_proc);
1985
1986 sig_proc->si_pid = current_proc()->p_pid;
1987 sig_proc->si_status = W_EXITCODE(signum, 0);
1988 sig_proc->si_uid = r_uid;
1989 sig_proc->si_code = 0;
91447636 1990 }
1c79356b 1991
2d21ac55 1992 goto runlocked;
1c79356b
A
1993 } else {
1994 /* Default action - varies */
1995 if (mask & stopsigmask) {
1996 /*
1997 * These are the signals which by default
1998 * stop a process.
1999 *
2000 * Don't clog system with children of init
2001 * stopped from the keyboard.
2002 */
2d21ac55
A
2003 if (!(prop & SA_STOP) && sig_proc->p_pptr == initproc) {
2004 proc_unlock(sig_proc);
2005 psignal_locked(sig_proc, SIGKILL);
2006 proc_lock(sig_proc);
9bccf70c 2007 uth->uu_siglist &= ~mask;
2d21ac55
A
2008 proc_unlock(sig_proc);
2009 goto psigout;
1c79356b
A
2010 }
2011
2012 /*
9bccf70c
A
2013 * Stop the task
2014 * if task hasn't already been stopped by
2015 * a signal.
1c79356b 2016 */
2d21ac55
A
2017 uth->uu_siglist &= ~mask;
2018 if (sig_proc->p_stat != SSTOP) {
2019 sig_proc->p_xstat = signum;
2020 sig_proc->p_stat = SSTOP;
b0d623f7 2021 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &sig_proc->p_flag);
2d21ac55
A
2022 sig_proc->p_lflag &= ~P_LWAITED;
2023 proc_unlock(sig_proc);
2024
2025 pp = proc_parentholdref(sig_proc);
2026 stop(sig_proc, pp);
2027 if (( pp != PROC_NULL) && ((pp->p_flag & P_NOCLDSTOP) == 0)) {
2028
2029 my_cred = kauth_cred_proc_ref(sig_proc);
2030 r_uid = my_cred->cr_ruid;
2031 kauth_cred_unref(&my_cred);
2032
2033 proc_lock(sig_proc);
2034 pp->si_pid = sig_proc->p_pid;
2035 /*
2036 * POSIX: sigaction for a stopped child
2037 * when sent to the parent must set the
2038 * child's signal number into si_status.
2039 */
2040 if (signum != SIGSTOP)
2041 pp->si_status = WEXITSTATUS(sig_proc->p_xstat);
2042 else
2043 pp->si_status = W_EXITCODE(signum, signum);
9bccf70c 2044 pp->si_code = CLD_STOPPED;
2d21ac55
A
2045 pp->si_uid = r_uid;
2046 proc_unlock(sig_proc);
2047
9bccf70c 2048 psignal(pp, SIGCHLD);
1c79356b 2049 }
2d21ac55
A
2050 if (pp != PROC_NULL)
2051 proc_parentdropref(pp, 0);
2052 } else
2053 proc_unlock(sig_proc);
2054 goto psigout;
1c79356b
A
2055 }
2056
2d21ac55
A
2057 DTRACE_PROC3(signal__send, thread_t, sig_thread, proc_t, p, int, signum);
2058
2059 /*
2060 * enters switch with sig_proc lock held but dropped when
2061 * gets out of switch
2062 */
1c79356b
A
2063 switch (signum) {
2064 /*
2065 * Signals ignored by default have been dealt
2066 * with already, since their bits are on in
2067 * p_sigignore.
2068 */
2069
2070 case SIGKILL:
2071 /*
2072 * Kill signal always sets process running and
2073 * unsuspends it.
2074 */
2075 /*
2076 * Process will be running after 'run'
2077 */
2d21ac55
A
2078 sig_proc->p_stat = SRUN;
2079 proc_unlock(sig_proc);
2080 thread_abort(sig_thread);
1c79356b 2081
2d21ac55 2082 goto psigout;
1c79356b
A
2083
2084 case SIGCONT:
2085 /*
2086 * Let the process run. If it's sleeping on an
2087 * event, it remains so.
2088 */
b0d623f7 2089 OSBitOrAtomic(P_CONTINUED, &sig_proc->p_flag);
2d21ac55
A
2090 sig_proc->p_contproc = sig_proc->p_pid;
2091
2092 proc_unlock(sig_proc);
2093 (void) task_resume(sig_task);
2094 proc_lock(sig_proc);
2095 /*
2096 * When processing a SIGCONT, we need to check
2097 * to see if there are signals pending that
2098 * were not delivered because we had been
2099 * previously stopped. If that's the case,
2100 * we need to thread_abort_safely() to trigger
2101 * interruption of the current system call to
2102 * cause their handlers to fire. If it's only
2103 * the SIGCONT, then don't wake up.
2104 */
2105 if (((flavor & (PSIG_VFORK|PSIG_THREAD)) == 0) && (((uth->uu_siglist & ~uth->uu_sigmask) & ~sig_proc->p_sigignore) & ~mask)) {
2106 uth->uu_siglist &= ~mask;
2107 sig_proc->p_stat = SRUN;
2108 goto runlocked;
1c79356b 2109 }
2d21ac55 2110
9bccf70c 2111 uth->uu_siglist &= ~mask;
2d21ac55
A
2112 sig_proc->p_stat = SRUN;
2113 proc_unlock(sig_proc);
2114 goto psigout;
1c79356b
A
2115
2116 default:
2d21ac55
A
2117 /*
2118 * A signal which has a default action of killing
2119 * the process, and for which there is no handler,
2120 * needs to act like SIGKILL
2121 */
2122 if (((flavor & (PSIG_VFORK|PSIG_THREAD)) == 0) && (action == SIG_DFL) && (prop & SA_KILL)) {
2123 sig_proc->p_stat = SRUN;
2124 proc_unlock(sig_proc);
2125 thread_abort(sig_thread);
2126 goto psigout;
2127 }
2128
1c79356b
A
2129 /*
2130 * All other signals wake up the process, but don't
2131 * resume it.
2132 */
2d21ac55
A
2133 if (sig_proc->p_stat == SSTOP) {
2134 proc_unlock(sig_proc);
2135 goto psigout;
2136 }
2137 goto runlocked;
1c79356b
A
2138 }
2139 }
2140 /*NOTREACHED*/
2d21ac55
A
2141
2142runlocked:
1c79356b
A
2143 /*
2144 * If we're being traced (possibly because someone attached us
2145 * while we were stopped), check for a signal from the debugger.
2146 */
2d21ac55
A
2147 if (sig_proc->p_stat == SSTOP) {
2148 if ((sig_proc->p_lflag & P_LTRACED) != 0 && sig_proc->p_xstat != 0)
2149 uth->uu_siglist |= sigmask(sig_proc->p_xstat);
2150 if ((flavor & PSIG_VFORK) != 0) {
2151 sig_proc->p_stat = SRUN;
9bccf70c 2152 }
2d21ac55 2153 proc_unlock(sig_proc);
9bccf70c
A
2154 } else {
2155 /*
2156 * setrunnable(p) in BSD and
2157 * Wake up the thread if it is interruptible.
2158 */
2d21ac55
A
2159 sig_proc->p_stat = SRUN;
2160 proc_unlock(sig_proc);
2161 if ((flavor & PSIG_VFORK) == 0)
2162 thread_abort_safely(sig_thread);
2163 }
2164psigout:
2165 if ((flavor & PSIG_LOCKED)== 0) {
2166 proc_signalend(sig_proc, 0);
1c79356b 2167 }
1c79356b
A
2168}
2169
2d21ac55
A
2170void
2171psignal(proc_t p, int signum)
1c79356b 2172{
2d21ac55
A
2173 psignal_internal(p, NULL, NULL, 0, signum);
2174}
1c79356b 2175
2d21ac55
A
2176void
2177psignal_locked(proc_t p, int signum)
2178{
2179 psignal_internal(p, NULL, NULL, PSIG_LOCKED, signum);
1c79356b
A
2180}
2181
2d21ac55
A
2182void
2183psignal_vfork(proc_t p, task_t new_task, thread_t thread, int signum)
1c79356b 2184{
2d21ac55
A
2185 psignal_internal(p, new_task, thread, PSIG_VFORK, signum);
2186}
1c79356b 2187
2d21ac55
A
2188static void
2189psignal_uthread(thread_t thread, int signum)
2190{
2191 psignal_internal(PROC_NULL, TASK_NULL, thread, PSIG_THREAD, signum);
1c79356b
A
2192}
2193
2d21ac55 2194
1c79356b
A
2195/*
2196 * If the current process has received a signal (should be caught or cause
2197 * termination, should interrupt current syscall), return the signal number.
2198 * Stop signals with default action are processed immediately, then cleared;
2199 * they aren't returned. This is checked after each entry to the system for
2200 * a syscall or trap (though this can usually be done without calling issignal
2201 * by checking the pending signal masks in the CURSIG macro.) The normal call
2202 * sequence is
2203 *
2204 * while (signum = CURSIG(curproc))
2205 * postsig(signum);
2206 */
2207int
2d21ac55 2208issignal(proc_t p)
1c79356b 2209{
2d21ac55 2210 int signum, mask, prop, sigbits;
91447636 2211 thread_t cur_act;
1c79356b 2212 struct uthread * ut;
2d21ac55
A
2213 proc_t pp;
2214 kauth_cred_t my_cred;
2215 int retval = 0;
2216 uid_t r_uid;
1c79356b 2217
91447636 2218 cur_act = current_thread();
1c79356b 2219
9bccf70c
A
2220#if SIGNAL_DEBUG
2221 if(rdebug_proc && (p == rdebug_proc)) {
2222 ram_printf(3);
2223 }
2224#endif /* SIGNAL_DEBUG */
2d21ac55 2225 proc_lock(p);
1c79356b 2226
1c79356b
A
2227 /*
2228 * Try to grab the signal lock.
2229 */
2230 if (sig_try_locked(p) <= 0) {
2d21ac55
A
2231 proc_unlock(p);
2232 return(0);
1c79356b
A
2233 }
2234
2d21ac55
A
2235 proc_signalstart(p, 1);
2236
1c79356b
A
2237 ut = get_bsdthread_info(cur_act);
2238 for(;;) {
9bccf70c 2239 sigbits = ut->uu_siglist & ~ut->uu_sigmask;
1c79356b 2240
2d21ac55 2241 if (p->p_lflag & P_LPPWAIT)
1c79356b
A
2242 sigbits &= ~stopsigmask;
2243 if (sigbits == 0) { /* no signal to send */
2d21ac55
A
2244 retval = 0;
2245 goto out;
1c79356b 2246 }
2d21ac55 2247
1c79356b
A
2248 signum = ffs((long)sigbits);
2249 mask = sigmask(signum);
2250 prop = sigprop[signum];
2251
1c79356b
A
2252 /*
2253 * We should see pending but ignored signals
2d21ac55 2254 * only if P_LTRACED was on when they were posted.
1c79356b 2255 */
2d21ac55 2256 if (mask & p->p_sigignore && (p->p_lflag & P_LTRACED) == 0) {
9bccf70c 2257 ut->uu_siglist &= ~mask; /* take the signal! */
1c79356b
A
2258 continue;
2259 }
2d21ac55
A
2260 if (p->p_lflag & P_LTRACED && (p->p_lflag & P_LPPWAIT) == 0) {
2261 task_t task;
1c79356b
A
2262 /*
2263 * If traced, always stop, and stay
2264 * stopped until released by the debugger.
2265 */
2266 /* ptrace debugging */
2267 p->p_xstat = signum;
2d21ac55
A
2268
2269 if (p->p_lflag & P_LSIGEXC) {
9bccf70c
A
2270 p->sigwait = TRUE;
2271 p->sigwait_thread = cur_act;
2272 p->p_stat = SSTOP;
b0d623f7 2273 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
2d21ac55 2274 p->p_lflag &= ~P_LWAITED;
9bccf70c 2275 ut->uu_siglist &= ~mask; /* clear the old signal */
2d21ac55
A
2276 proc_signalend(p, 1);
2277 proc_unlock(p);
9bccf70c 2278 do_bsdexception(EXC_SOFTWARE, EXC_SOFT_SIGNAL, signum);
2d21ac55
A
2279 proc_lock(p);
2280 proc_signalstart(p, 1);
9bccf70c 2281 } else {
2d21ac55
A
2282 proc_unlock(p);
2283 my_cred = kauth_cred_proc_ref(p);
2284 r_uid = my_cred->cr_ruid;
2285 kauth_cred_unref(&my_cred);
2286
2287 pp = proc_parentholdref(p);
2288 if (pp != PROC_NULL) {
2289 proc_lock(pp);
2290
2291 pp->si_pid = p->p_pid;
2292 pp->si_status = p->p_xstat;
2293 pp->si_code = CLD_TRAPPED;
2294 pp->si_uid = r_uid;
2295
2296 proc_unlock(pp);
2297 }
2298
9bccf70c
A
2299 /*
2300 * XXX Have to really stop for debuggers;
2301 * XXX stop() doesn't do the right thing.
2302 * XXX Inline the task_suspend because we
2303 * XXX have to diddle Unix state in the
2304 * XXX middle of it.
2305 */
2306 task = p->task;
2d21ac55
A
2307 task_suspend(task);
2308
2309 proc_lock(p);
9bccf70c
A
2310 p->sigwait = TRUE;
2311 p->sigwait_thread = cur_act;
2312 p->p_stat = SSTOP;
b0d623f7 2313 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
2d21ac55 2314 p->p_lflag &= ~P_LWAITED;
9bccf70c 2315 ut->uu_siglist &= ~mask; /* clear the old signal */
9bccf70c 2316
2d21ac55
A
2317 proc_signalend(p, 1);
2318 proc_unlock(p);
2319
2320 if (pp != PROC_NULL) {
2321 psignal(pp, SIGCHLD);
2322 proc_list_lock();
2323 wakeup((caddr_t)pp);
2324 proc_parentdropref(pp, 1);
2325 proc_list_unlock();
2326 }
2327
9bccf70c
A
2328 assert_wait((caddr_t)&p->sigwait, (THREAD_INTERRUPTIBLE));
2329 thread_block(THREAD_CONTINUE_NULL);
2d21ac55
A
2330 proc_lock(p);
2331 proc_signalstart(p, 1);
9bccf70c
A
2332 }
2333
1c79356b
A
2334 p->sigwait = FALSE;
2335 p->sigwait_thread = NULL;
2336 wakeup((caddr_t)&p->sigwait_thread);
2337
2338 /*
2339 * This code is to detect when gdb is killed
2340 * even as the traced program is attached.
2341 * pgsignal would get the SIGKILL to traced program
2342 * That's what we are trying to see (I hope)
2343 */
9bccf70c 2344 if (ut->uu_siglist & sigmask(SIGKILL)) {
1c79356b
A
2345 /*
2346 * Wait event may still be outstanding;
2347 * clear it, since sig_lock_to_exit will
2348 * wait.
2349 */
91447636 2350 clear_wait(current_thread(), THREAD_INTERRUPTED);
1c79356b
A
2351 sig_lock_to_exit(p);
2352 /*
2353 * Since this thread will be resumed
2354 * to allow the current syscall to
2355 * be completed, must save u_qsave
2356 * before calling exit(). (Since exit()
2357 * calls closef() which can trash u_qsave.)
2358 */
2d21ac55
A
2359 proc_signalend(p, 1);
2360 proc_unlock(p);
b0d623f7
A
2361 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_FRCEXIT) | DBG_FUNC_NONE,
2362 p->p_pid, W_EXITCODE(0, SIGKILL), 2, 0, 0);
2d21ac55 2363 exit1(p, W_EXITCODE(0, SIGKILL), (int *)NULL);
1c79356b
A
2364 return(0);
2365 }
2366
2367 /*
2368 * We may have to quit
2369 */
91447636 2370 if (thread_should_abort(current_thread())) {
2d21ac55
A
2371 retval = 0;
2372 goto out;
1c79356b
A
2373 }
2374 /*
2375 * If parent wants us to take the signal,
2376 * then it will leave it in p->p_xstat;
2377 * otherwise we just look for signals again.
2378 */
2379 signum = p->p_xstat;
2380 if (signum == 0)
2381 continue;
2382 /*
2383 * Put the new signal into p_siglist. If the
2384 * signal is being masked, look for other signals.
2385 */
2386 mask = sigmask(signum);
9bccf70c 2387 ut->uu_siglist |= mask;
9bccf70c 2388 if (ut->uu_sigmask & mask)
1c79356b
A
2389 continue;
2390 }
2391
2392 /*
2393 * Decide whether the signal should be returned.
2394 * Return the signal's number, or fall through
2395 * to clear it from the pending mask.
2396 */
2397
2398 switch ((long)p->p_sigacts->ps_sigact[signum]) {
2399
2400 case (long)SIG_DFL:
2401 /*
2402 * Don't take default actions on system processes.
2403 */
2d21ac55 2404 if (p->p_ppid == 0) {
1c79356b
A
2405#if DIAGNOSTIC
2406 /*
2407 * Are you sure you want to ignore SIGSEGV
2408 * in init? XXX
2409 */
2410 printf("Process (pid %d) got signal %d\n",
2411 p->p_pid, signum);
2412#endif
2413 break; /* == ignore */
2414 }
2415
2416 /*
2417 * If there is a pending stop signal to process
2418 * with default action, stop here,
2419 * then clear the signal. However,
2420 * if process is member of an orphaned
2421 * process group, ignore tty stop signals.
2422 */
2423 if (prop & SA_STOP) {
2d21ac55
A
2424 struct pgrp * pg;
2425
2426 proc_unlock(p);
2427 pg = proc_pgrp(p);
2428 if (p->p_lflag & P_LTRACED ||
2429 (pg->pg_jobc == 0 &&
2430 prop & SA_TTYSTOP)) {
2431 proc_lock(p);
2432 pg_rele(pg);
1c79356b 2433 break; /* == ignore */
2d21ac55
A
2434 }
2435 pg_rele(pg);
9bccf70c 2436 if (p->p_stat != SSTOP) {
2d21ac55 2437 proc_lock(p);
9bccf70c 2438 p->p_xstat = signum;
2d21ac55
A
2439
2440 p->p_stat = SSTOP;
2441 p->p_lflag &= ~P_LWAITED;
2442 proc_unlock(p);
2443
2444 pp = proc_parentholdref(p);
2445 stop(p, pp);
2446 if ((pp != PROC_NULL) && ((pp->p_flag & P_NOCLDSTOP) == 0)) {
2447 my_cred = kauth_cred_proc_ref(p);
2448 r_uid = my_cred->cr_ruid;
2449 kauth_cred_unref(&my_cred);
2450
2451 proc_lock(pp);
9bccf70c 2452 pp->si_pid = p->p_pid;
2d21ac55 2453 pp->si_status = WEXITSTATUS(p->p_xstat);
9bccf70c 2454 pp->si_code = CLD_STOPPED;
2d21ac55
A
2455 pp->si_uid = r_uid;
2456 proc_unlock(pp);
2457
9bccf70c
A
2458 psignal(pp, SIGCHLD);
2459 }
2d21ac55
A
2460 if (pp != PROC_NULL)
2461 proc_parentdropref(pp, 0);
1c79356b 2462 }
2d21ac55 2463 proc_lock(p);
1c79356b
A
2464 break;
2465 } else if (prop & SA_IGNORE) {
2466 /*
2467 * Except for SIGCONT, shouldn't get here.
2468 * Default action is to ignore; drop it.
2469 */
2470 break; /* == ignore */
2471 } else {
9bccf70c 2472 ut->uu_siglist &= ~mask; /* take the signal! */
2d21ac55
A
2473 retval = signum;
2474 goto out;
1c79356b 2475 }
2d21ac55 2476
1c79356b 2477 /*NOTREACHED*/
2d21ac55 2478 break;
1c79356b
A
2479
2480 case (long)SIG_IGN:
2481 /*
2482 * Masking above should prevent us ever trying
2483 * to take action on an ignored signal other
2484 * than SIGCONT, unless process is traced.
2485 */
2486 if ((prop & SA_CONT) == 0 &&
2d21ac55 2487 (p->p_lflag & P_LTRACED) == 0)
1c79356b
A
2488 printf("issignal\n");
2489 break; /* == ignore */
2490
2491 default:
2492 /*
2493 * This signal has an action, let
2494 * postsig() process it.
2495 */
9bccf70c 2496 ut->uu_siglist &= ~mask; /* take the signal! */
2d21ac55
A
2497 retval = signum;
2498 goto out;
1c79356b 2499 }
9bccf70c 2500 ut->uu_siglist &= ~mask; /* take the signal! */
1c79356b
A
2501 }
2502 /* NOTREACHED */
2d21ac55
A
2503out:
2504 proc_signalend(p,1);
2505 proc_unlock(p);
2506 return(retval);
1c79356b
A
2507}
2508
2509/* called from _sleep */
2510int
2d21ac55 2511CURSIG(proc_t p)
1c79356b 2512{
2d21ac55 2513 int signum, mask, prop, sigbits;
91447636 2514 thread_t cur_act;
1c79356b
A
2515 struct uthread * ut;
2516 int retnum = 0;
2517
1c79356b 2518
91447636 2519 cur_act = current_thread();
1c79356b
A
2520
2521 ut = get_bsdthread_info(cur_act);
2522
9bccf70c
A
2523 if (ut->uu_siglist == 0)
2524 return (0);
2525
2d21ac55 2526 if (((ut->uu_siglist & ~ut->uu_sigmask) == 0) && ((p->p_lflag & P_LTRACED) == 0))
9bccf70c
A
2527 return (0);
2528
2529 sigbits = ut->uu_siglist & ~ut->uu_sigmask;
1c79356b
A
2530
2531 for(;;) {
2d21ac55 2532 if (p->p_lflag & P_LPPWAIT)
1c79356b
A
2533 sigbits &= ~stopsigmask;
2534 if (sigbits == 0) { /* no signal to send */
2535 return (retnum);
2536 }
2537
2538 signum = ffs((long)sigbits);
2539 mask = sigmask(signum);
2540 prop = sigprop[signum];
2541
2542 /*
2543 * We should see pending but ignored signals
2d21ac55 2544 * only if P_LTRACED was on when they were posted.
1c79356b 2545 */
2d21ac55 2546 if (mask & p->p_sigignore && (p->p_lflag & P_LTRACED) == 0) {
1c79356b
A
2547 continue;
2548 }
2d21ac55 2549 if (p->p_lflag & P_LTRACED && (p->p_lflag & P_LPPWAIT) == 0) {
1c79356b
A
2550 /*
2551 * Put the new signal into p_siglist. If the
2552 * signal is being masked, look for other signals.
2553 */
2554 mask = sigmask(signum);
9bccf70c 2555 if (ut->uu_sigmask & mask)
1c79356b
A
2556 continue;
2557 return(signum);
2558 }
2559
2560 /*
2561 * Decide whether the signal should be returned.
2562 * Return the signal's number, or fall through
2563 * to clear it from the pending mask.
2564 */
2565
2566 switch ((long)p->p_sigacts->ps_sigact[signum]) {
2567
2568 case (long)SIG_DFL:
2569 /*
2570 * Don't take default actions on system processes.
2571 */
2d21ac55 2572 if (p->p_ppid == 0) {
1c79356b
A
2573#if DIAGNOSTIC
2574 /*
2575 * Are you sure you want to ignore SIGSEGV
2576 * in init? XXX
2577 */
2578 printf("Process (pid %d) got signal %d\n",
2579 p->p_pid, signum);
2580#endif
2581 break; /* == ignore */
2582 }
2583
2584 /*
2585 * If there is a pending stop signal to process
2586 * with default action, stop here,
2587 * then clear the signal. However,
2588 * if process is member of an orphaned
2589 * process group, ignore tty stop signals.
2590 */
2591 if (prop & SA_STOP) {
2d21ac55
A
2592 struct pgrp *pg;
2593
2594 pg = proc_pgrp(p);
2595
2596 if (p->p_lflag & P_LTRACED ||
2597 (pg->pg_jobc == 0 &&
2598 prop & SA_TTYSTOP)) {
2599 pg_rele(pg);
1c79356b 2600 break; /* == ignore */
2d21ac55
A
2601 }
2602 pg_rele(pg);
1c79356b
A
2603 retnum = signum;
2604 break;
2605 } else if (prop & SA_IGNORE) {
2606 /*
2607 * Except for SIGCONT, shouldn't get here.
2608 * Default action is to ignore; drop it.
2609 */
2610 break; /* == ignore */
2611 } else {
2612 return (signum);
2613 }
2614 /*NOTREACHED*/
2615
2616 case (long)SIG_IGN:
2617 /*
2618 * Masking above should prevent us ever trying
2619 * to take action on an ignored signal other
2620 * than SIGCONT, unless process is traced.
2621 */
2622 if ((prop & SA_CONT) == 0 &&
2d21ac55 2623 (p->p_lflag & P_LTRACED) == 0)
1c79356b
A
2624 printf("issignal\n");
2625 break; /* == ignore */
2626
2627 default:
2628 /*
2629 * This signal has an action, let
2630 * postsig() process it.
2631 */
2632 return (signum);
2633 }
2634 sigbits &= ~mask; /* take the signal! */
2635 }
2636 /* NOTREACHED */
2637}
2638
2639/*
2640 * Put the argument process into the stopped state and notify the parent
2641 * via wakeup. Signals are handled elsewhere. The process must not be
2642 * on the run queue.
2643 */
2d21ac55
A
2644static void
2645stop(proc_t p, proc_t parent)
1c79356b 2646{
b0d623f7 2647 OSBitAndAtomic(~((uint32_t)P_CONTINUED), &p->p_flag);
2d21ac55
A
2648 if ((parent != PROC_NULL) && (parent->p_stat != SSTOP)) {
2649 proc_list_lock();
2650 wakeup((caddr_t)parent);
2651 proc_list_unlock();
2652 }
1c79356b
A
2653 (void) task_suspend(p->task); /*XXX*/
2654}
2655
2656/*
2657 * Take the action for the specified signal
2658 * from the current set of pending signals.
2659 */
2660void
91447636 2661postsig(int signum)
1c79356b 2662{
2d21ac55 2663 proc_t p = current_proc();
91447636
A
2664 struct sigacts *ps = p->p_sigacts;
2665 user_addr_t catcher;
b0d623f7 2666 uint32_t code;
1c79356b 2667 int mask, returnmask;
9bccf70c 2668 struct uthread * ut;
1c79356b
A
2669
2670#if DIAGNOSTIC
2671 if (signum == 0)
2672 panic("postsig");
2673 /*
2674 * This must be called on master cpu
2675 */
2676 if (cpu_number() != master_cpu)
2677 panic("psig not on master");
2678#endif
2679
2d21ac55 2680 proc_lock(p);
1c79356b
A
2681 /*
2682 * Try to grab the signal lock.
2683 */
2684 if (sig_try_locked(p) <= 0) {
2d21ac55 2685 proc_unlock(p);
1c79356b
A
2686 return;
2687 }
2688
2d21ac55
A
2689 proc_signalstart(p, 1);
2690
91447636 2691 ut = (struct uthread *)get_bsdthread_info(current_thread());
1c79356b 2692 mask = sigmask(signum);
9bccf70c 2693 ut->uu_siglist &= ~mask;
91447636 2694 catcher = ps->ps_sigact[signum];
91447636 2695 if (catcher == SIG_DFL) {
1c79356b 2696 /*
91447636 2697 * Default catcher, where the default is to kill
1c79356b
A
2698 * the process. (Other cases were ignored above.)
2699 */
2d21ac55
A
2700 sig_lock_to_exit(p);
2701 p->p_acflag |= AXSIG;
2702 if (sigprop[signum] & SA_CORE) {
2703 p->p_sigacts->ps_sig = signum;
2704 proc_signalend(p, 1);
2705 proc_unlock(p);
2706 if (coredump(p) == 0)
2707 signum |= WCOREFLAG;
2708 } else {
2709 proc_signalend(p, 1);
2710 proc_unlock(p);
2711 }
2712
b0d623f7
A
2713#if CONFIG_DTRACE
2714 bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo));
2715
2716 ut->t_dtrace_siginfo.si_signo = signum;
2717 ut->t_dtrace_siginfo.si_pid = p->si_pid;
2718 ut->t_dtrace_siginfo.si_uid = p->si_uid;
2719 ut->t_dtrace_siginfo.si_status = WEXITSTATUS(p->si_status);
2d21ac55 2720
b0d623f7 2721 DTRACE_PROC3(signal__handle, int, signum, siginfo_t *, &(ut->t_dtrace_siginfo),
2d21ac55 2722 void (*)(void), SIG_DFL);
b0d623f7 2723#endif
2d21ac55 2724
b0d623f7
A
2725 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_FRCEXIT) | DBG_FUNC_NONE,
2726 p->p_pid, W_EXITCODE(0, signum), 3, 0, 0);
2d21ac55 2727 exit1(p, W_EXITCODE(0, signum), (int *)NULL);
1c79356b 2728 return;
1c79356b
A
2729 } else {
2730 /*
2731 * If we get here, the signal must be caught.
2732 */
2733#if DIAGNOSTIC
91447636 2734 if (catcher == SIG_IGN || (ut->uu_sigmask & mask))
1c79356b
A
2735 log(LOG_WARNING,
2736 "postsig: processing masked or ignored signal\n");
2737#endif
2d21ac55 2738
1c79356b
A
2739 /*
2740 * Set the new mask value and also defer further
2741 * occurences of this signal.
2742 *
2743 * Special case: user has done a sigpause. Here the
2744 * current mask is not of interest, but rather the
2745 * mask from before the sigpause is what we want
2746 * restored after the signal processing is completed.
2747 */
91447636 2748 if (ut->uu_flag & UT_SAS_OLDMASK) {
9bccf70c 2749 returnmask = ut->uu_oldmask;
91447636 2750 ut->uu_flag &= ~UT_SAS_OLDMASK;
9bccf70c 2751 ut->uu_oldmask = 0;
1c79356b 2752 } else
9bccf70c
A
2753 returnmask = ut->uu_sigmask;
2754 ut->uu_sigmask |= ps->ps_catchmask[signum];
2755 if ((ps->ps_signodefer & mask) == 0)
2756 ut->uu_sigmask |= mask;
2757 if ((signum != SIGILL) && (signum != SIGTRAP) && (ps->ps_sigreset & mask)) {
2758 if ((signum != SIGCONT) && (sigprop[signum] & SA_IGNORE))
2759 p->p_sigignore |= mask;
2760 ps->ps_sigact[signum] = SIG_DFL;
2761 ps->ps_siginfo &= ~mask;
2762 ps->ps_signodefer &= ~mask;
2763 }
2764#ifdef __ppc__
2765 /* Needs to disable to run in user mode */
2766 if (signum == SIGFPE) {
91447636 2767 thread_enable_fpe(current_thread(), 0);
9bccf70c
A
2768 }
2769#endif /* __ppc__ */
2770
1c79356b
A
2771 if (ps->ps_sig != signum) {
2772 code = 0;
2773 } else {
2774 code = ps->ps_code;
2775 ps->ps_code = 0;
2776 }
b0d623f7 2777 OSIncrementAtomicLong(&p->p_stats->p_ru.ru_nsignals);
91447636 2778 sendsig(p, catcher, signum, returnmask, code);
1c79356b 2779 }
2d21ac55
A
2780 proc_signalend(p, 1);
2781 proc_unlock(p);
1c79356b
A
2782}
2783
2784/*
2d21ac55
A
2785 * Attach a signal knote to the list of knotes for this process.
2786 *
2787 * Signal knotes share the knote list with proc knotes. This
2788 * could be avoided by using a signal-specific knote list, but
2789 * probably isn't worth the trouble.
1c79356b 2790 */
55e303ae
A
2791
2792static int
2793filt_sigattach(struct knote *kn)
2794{
2d21ac55
A
2795 proc_t p = current_proc(); /* can attach only to oneself */
2796
2797 proc_klist_lock();
55e303ae
A
2798
2799 kn->kn_ptr.p_proc = p;
2800 kn->kn_flags |= EV_CLEAR; /* automatically set */
2801
55e303ae 2802 KNOTE_ATTACH(&p->p_klist, kn);
2d21ac55
A
2803
2804 proc_klist_unlock();
55e303ae
A
2805
2806 return (0);
2807}
2808
2d21ac55
A
2809/*
2810 * remove the knote from the process list, if it hasn't already
2811 * been removed by exit processing.
2812 */
2813
55e303ae
A
2814static void
2815filt_sigdetach(struct knote *kn)
2816{
2d21ac55 2817 proc_t p = kn->kn_ptr.p_proc;
55e303ae 2818
2d21ac55
A
2819 proc_klist_lock();
2820 kn->kn_ptr.p_proc = NULL;
55e303ae 2821 KNOTE_DETACH(&p->p_klist, kn);
2d21ac55 2822 proc_klist_unlock();
55e303ae
A
2823}
2824
2825/*
2d21ac55
A
2826 * Post an event to the signal filter. Because we share the same list
2827 * as process knotes, we have to filter out and handle only signal events.
2828 *
2829 * We assume that we process fdfree() before we post the NOTE_EXIT for
2830 * a process during exit. Therefore, since signal filters can only be
2831 * set up "in-process", we should have already torn down the kqueue
2832 * hosting the EVFILT_SIGNAL knote and should never see NOTE_EXIT.
55e303ae
A
2833 */
2834static int
2835filt_signal(struct knote *kn, long hint)
2836{
2837
2838 if (hint & NOTE_SIGNAL) {
2839 hint &= ~NOTE_SIGNAL;
2840
91447636 2841 if (kn->kn_id == (unsigned int)hint)
55e303ae 2842 kn->kn_data++;
2d21ac55
A
2843 } else if (hint & NOTE_EXIT) {
2844 panic("filt_signal: detected NOTE_EXIT event");
55e303ae 2845 }
2d21ac55 2846
55e303ae
A
2847 return (kn->kn_data != 0);
2848}
2849
b0d623f7
A
2850static void
2851filt_signaltouch(struct knote *kn, struct kevent64_s *kev, long type)
2852{
2853 proc_klist_lock();
2854 switch (type) {
2855 case EVENT_REGISTER:
2856 kn->kn_sfflags = kev->fflags;
2857 kn->kn_sdata = kev->data;
2858 break;
2859 case EVENT_PROCESS:
2860 *kev = kn->kn_kevent;
2861 if (kn->kn_flags & EV_CLEAR) {
2862 kn->kn_data = 0;
2863 kn->kn_fflags = 0;
2864 }
2865 break;
2866 default:
2867 panic("filt_machporttouch() - invalid type (%ld)", type);
2868 break;
2869 }
2870 proc_klist_unlock();
2871}
2872
1c79356b 2873void
2d21ac55 2874bsd_ast(thread_t thread)
1c79356b 2875{
2d21ac55
A
2876 proc_t p = current_proc();
2877 struct uthread *ut = get_bsdthread_info(thread);
1c79356b 2878 int signum;
91447636 2879 user_addr_t pc;
91447636 2880 static int bsd_init_done = 0;
1c79356b
A
2881
2882 if (p == NULL)
2883 return;
2884
1c79356b
A
2885 if ((p->p_flag & P_OWEUPC) && (p->p_flag & P_PROFIL)) {
2886 pc = get_useraddr();
2887 addupc_task(p, pc, 1);
b0d623f7 2888 OSBitAndAtomic(~((uint32_t)P_OWEUPC), &p->p_flag);
1c79356b
A
2889 }
2890
2d21ac55
A
2891 if (timerisset(&p->p_vtimer_user.it_value)) {
2892 uint32_t microsecs;
2893
2894 task_vtimer_update(p->task, TASK_VTIMER_USER, &microsecs);
2895
2896 if (!itimerdecr(p, &p->p_vtimer_user, microsecs)) {
2897 if (timerisset(&p->p_vtimer_user.it_value))
2898 task_vtimer_set(p->task, TASK_VTIMER_USER);
2899 else
2900 task_vtimer_clear(p->task, TASK_VTIMER_USER);
2901
2902 psignal(p, SIGVTALRM);
b0d623f7 2903 }
9bccf70c 2904 }
1c79356b 2905
2d21ac55
A
2906 if (timerisset(&p->p_vtimer_prof.it_value)) {
2907 uint32_t microsecs;
1c79356b 2908
2d21ac55 2909 task_vtimer_update(p->task, TASK_VTIMER_PROF, &microsecs);
1c79356b 2910
2d21ac55
A
2911 if (!itimerdecr(p, &p->p_vtimer_prof, microsecs)) {
2912 if (timerisset(&p->p_vtimer_prof.it_value))
2913 task_vtimer_set(p->task, TASK_VTIMER_PROF);
2914 else
2915 task_vtimer_clear(p->task, TASK_VTIMER_PROF);
2916
2917 psignal(p, SIGPROF);
2918 }
b0d623f7 2919 }
1c79356b 2920
2d21ac55
A
2921 if (timerisset(&p->p_rlim_cpu)) {
2922 struct timeval tv;
1c79356b 2923
2d21ac55 2924 task_vtimer_update(p->task, TASK_VTIMER_RLIM, (uint32_t *) &tv.tv_usec);
1c79356b 2925
2d21ac55
A
2926 proc_spinlock(p);
2927 if (p->p_rlim_cpu.tv_sec > 0 || p->p_rlim_cpu.tv_usec > tv.tv_usec) {
2928 tv.tv_sec = 0;
2929 timersub(&p->p_rlim_cpu, &tv, &p->p_rlim_cpu);
2930 proc_spinunlock(p);
2931 } else {
2932
2933 timerclear(&p->p_rlim_cpu);
2934 proc_spinunlock(p);
2935
2936 task_vtimer_clear(p->task, TASK_VTIMER_RLIM);
2937
2938 psignal(p, SIGXCPU);
2939 }
2940 }
2941
b0d623f7
A
2942#if CONFIG_DTRACE
2943 if (ut->t_dtrace_sig) {
2944 uint8_t dt_action_sig = ut->t_dtrace_sig;
2945 ut->t_dtrace_sig = 0;
2946 psignal(p, dt_action_sig);
2947 }
2948 if (ut->t_dtrace_stop) {
2949 ut->t_dtrace_stop = 0;
2950 psignal(p, SIGSTOP);
2951 }
2952#endif /* CONFIG_DTRACE */
2953
2d21ac55
A
2954 if (CHECK_SIGNALS(p, current_thread(), ut)) {
2955 while ( (signum = issignal(p)) )
2956 postsig(signum);
2957 }
2958
2959 if (!bsd_init_done) {
2960 bsd_init_done = 1;
2961 bsdinit_task();
2962 }
1c79356b 2963
1c79356b
A
2964}
2965
593a1d5f 2966/* ptrace set runnable */
1c79356b 2967void
2d21ac55 2968pt_setrunnable(proc_t p)
1c79356b 2969{
2d21ac55 2970 task_t task;
1c79356b
A
2971
2972 task = p->task;
2973
2d21ac55
A
2974 if (p->p_lflag & P_LTRACED) {
2975 proc_lock(p);
1c79356b 2976 p->p_stat = SRUN;
2d21ac55 2977 proc_unlock(p);
1c79356b
A
2978 if (p->sigwait) {
2979 wakeup((caddr_t)&(p->sigwait));
593a1d5f
A
2980 if ((p->p_lflag & P_LSIGEXC) == 0) { // 5878479
2981 task_release(task);
2982 }
1c79356b
A
2983 }
2984 }
2985}
9bccf70c
A
2986
2987kern_return_t
2988do_bsdexception(
2989 int exc,
2990 int code,
2991 int sub)
2992{
2d21ac55 2993 mach_exception_data_type_t codes[EXCEPTION_CODE_MAX];
9bccf70c
A
2994
2995 codes[0] = code;
2996 codes[1] = sub;
2997 return(bsd_exception(exc, codes, 2));
2998}
2999
91447636 3000int
2d21ac55 3001proc_pendingsignals(proc_t p, sigset_t mask)
91447636
A
3002{
3003 struct uthread * uth;
3004 thread_t th;
3005 sigset_t bits = 0;
91447636 3006
2d21ac55 3007 proc_lock(p);
91447636 3008 /* If the process is in proc exit return no signal info */
2d21ac55
A
3009 if (p->p_lflag & P_LPEXIT) {
3010 goto out;
3011 }
91447636 3012
2d21ac55 3013 if ((p->p_lflag & P_LINVFORK) && p->p_vforkact) {
91447636
A
3014 th = p->p_vforkact;
3015 uth = (struct uthread *)get_bsdthread_info(th);
3016 if (uth) {
3017 bits = (((uth->uu_siglist & ~uth->uu_sigmask) & ~p->p_sigignore) & mask);
3018 }
3019 goto out;
3020 }
3021
3022 bits = 0;
3023 TAILQ_FOREACH(uth, &p->p_uthlist, uu_list) {
3024 bits |= (((uth->uu_siglist & ~uth->uu_sigmask) & ~p->p_sigignore) & mask);
3025 }
3026out:
2d21ac55 3027 proc_unlock(p);
91447636
A
3028 return(bits);
3029}
3030
3031int
3032thread_issignal(proc_t p, thread_t th, sigset_t mask)
3033{
3034 struct uthread * uth;
3035 sigset_t bits=0;
3036
2d21ac55
A
3037 proc_lock(p);
3038 uth = (struct uthread *)get_bsdthread_info(th);
3039 if (uth) {
3040 bits = (((uth->uu_siglist & ~uth->uu_sigmask) & ~p->p_sigignore) & mask);
3041 }
3042 proc_unlock(p);
3043 return(bits);
3044}
91447636 3045
2d21ac55
A
3046/*
3047 * Allow external reads of the sigprop array.
3048 */
3049int
3050hassigprop(int sig, int prop)
3051{
3052 return (sigprop[sig] & prop);
3053}
3054
3055void
3056pgsigio(pid_t pgid, int sig)
3057{
3058 proc_t p = PROC_NULL;
3059
3060 if (pgid < 0)
3061 gsignal(-(pgid), sig);
3062
3063 else if (pgid > 0 && (p = proc_find(pgid)) != 0)
3064 psignal(p, sig);
3065 if (p != PROC_NULL)
3066 proc_rele(p);
3067}
3068
3069
3070void
3071proc_signalstart(proc_t p, int locked)
3072{
3073 if (locked == 0)
3074 proc_lock(p);
3075 while ((p->p_lflag & P_LINSIGNAL) == P_LINSIGNAL) {
3076 p->p_lflag |= P_LSIGNALWAIT;
3077 msleep(&p->p_sigmask, &p->p_mlock, 0, "proc_signstart", NULL);
3078 }
3079 p->p_lflag |= P_LINSIGNAL;
3080#if DIAGNOSTIC
3081#if SIGNAL_DEBUG
3082#ifdef __ppc__
3083 {
3084 int sp, *fp, numsaved;
3085
3086 __asm__ volatile("mr %0,r1" : "=r" (sp));
3087
3088 fp = (int *)*((int *)sp);
3089 for (numsaved = 0; numsaved < 3; numsaved++) {
3090 p->lockpc[numsaved] = fp[2];
3091 if ((int)fp <= 0)
3092 break;
3093 fp = (int *)*fp;
3094 }
3095 }
3096#endif /* __ppc__ */
3097#endif /* SIGNAL_DEBUG */
3098#endif /* DIAGNOSTIC */
3099 p->p_signalholder = current_thread();
3100 if (locked == 0)
3101 proc_unlock(p);
3102
3103}
3104
3105void
3106proc_signalend(proc_t p, int locked)
3107{
3108 if (locked == 0)
3109 proc_lock(p);
3110 p->p_lflag &= ~P_LINSIGNAL;
3111
3112#if DIAGNOSTIC
3113#if SIGNAL_DEBUG
3114#ifdef __ppc__
3115 {
3116 int sp, *fp, numsaved;
3117
3118 __asm__ volatile("mr %0,r1" : "=r" (sp));
3119
3120 fp = (int *)*((int *)sp);
3121 for (numsaved = 0; numsaved < 3; numsaved++) {
3122 p->unlockpc[numsaved] = fp[2];
3123 if ((int)fp <= 0)
3124 break;
3125 fp = (int *)*fp;
3126 }
3127 }
3128#endif /* __ppc__ */
3129#endif /* SIGNAL_DEBUG */
3130#endif /* DIAGNOSTIC */
3131
3132 if ((p->p_lflag & P_LSIGNALWAIT) == P_LSIGNALWAIT) {
3133 p->p_lflag &= ~P_LSIGNALWAIT;
3134 wakeup(&p->p_sigmask);
3135 }
3136 p->p_signalholder = NULL;
3137 if (locked == 0)
3138 proc_unlock(p);
3139}
3140
3141
3142void
3143sig_lock_to_exit(proc_t p)
3144{
3145 thread_t self = current_thread();
3146
3147 p->exit_thread = self;
3148 proc_unlock(p);
3149 (void) task_suspend(p->task);
3150 proc_lock(p);
91447636
A
3151}
3152
2d21ac55
A
3153int
3154sig_try_locked(proc_t p)
3155{
3156 thread_t self = current_thread();
3157
3158 while (p->sigwait || p->exit_thread) {
3159 if (p->exit_thread) {
3160 return(0);
3161 }
3162 msleep((caddr_t)&p->sigwait_thread, &p->p_mlock, PCATCH | PDROP, 0, 0);
3163 if (thread_should_abort(self)) {
3164 /*
3165 * Terminate request - clean up.
3166 */
3167 proc_lock(p);
3168 return -1;
3169 }
3170 proc_lock(p);
3171 }
3172 return 1;
3173}