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