3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include "lint.h"
28 #include <sys/feature_tests.h>
29 /*
30 * setcontext() really can return, if UC_CPU is not specified.
31 * Make the compiler shut up about it.
32 */
33 #if defined(__NORETURN)
34 #undef __NORETURN
35 #endif
36 #define __NORETURN
37 #include "thr_uberdata.h"
38 #include "asyncio.h"
39 #include <signal.h>
40 #include <siginfo.h>
41 #include <sys/systm.h>
42
53 * We only test valid signal bits, not rubbish following MAXSIG
54 * (for speed). Algorithm:
55 * if (s1 & fillset) == (s2 & fillset) then (s1 ^ s2) & fillset == 0
56 */
57 /* see lib/libc/inc/thr_uberdata.h for why this must be true */
58 #if (MAXSIG > (2 * 32) && MAXSIG <= (3 * 32))
59 return (!((s1->__sigbits[0] ^ s2->__sigbits[0]) |
60 (s1->__sigbits[1] ^ s2->__sigbits[1]) |
61 ((s1->__sigbits[2] ^ s2->__sigbits[2]) & FILLSET2)));
62 #else
63 #error "fix me: MAXSIG out of bounds"
64 #endif
65 }
66
67 /*
68 * Common code for calling the user-specified signal handler.
69 */
70 void
71 call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
72 {
73 ulwp_t *self = curthread;
74 uberdata_t *udp = self->ul_uberdata;
75 struct sigaction uact;
76 volatile struct sigaction *sap;
77
78 /*
79 * If we are taking a signal while parked or about to be parked
80 * on __lwp_park() then remove ourself from the sleep queue so
81 * that we can grab locks. The code in mutex_lock_queue() and
82 * cond_wait_common() will detect this and deal with it when
83 * __lwp_park() returns.
84 */
85 unsleep_self();
86 set_parking_flag(self, 0);
87
88 if (__td_event_report(self, TD_CATCHSIG, udp)) {
89 self->ul_td_evbuf.eventnum = TD_CATCHSIG;
90 self->ul_td_evbuf.eventdata = (void *)(intptr_t)sig;
91 tdb_event(TD_CATCHSIG, udp);
92 }
138 * signal mask for sigsuspend() or pollsys() (self->ul_tmpmask) but
139 * /proc can override this via PCSSIG, so we don't bother.
140 *
141 * We would also like to ASSERT() that the signal mask at the previous
142 * level equals self->ul_sigmask (maskset for sigsuspend() / pollsys()),
143 * but /proc can change the thread's signal mask via PCSHOLD, so we
144 * don't bother with that either.
145 */
146 ASSERT(ucp->uc_flags & UC_SIGMASK);
147 if (self->ul_sigsuspend) {
148 ucp->uc_sigmask = self->ul_sigmask;
149 self->ul_sigsuspend = 0;
150 /* the sigsuspend() or pollsys() signal mask */
151 sigorset(&uact.sa_mask, &self->ul_tmpmask);
152 } else {
153 /* the signal mask at the previous level */
154 sigorset(&uact.sa_mask, &ucp->uc_sigmask);
155 }
156 if (!(uact.sa_flags & SA_NODEFER)) /* add current signal */
157 (void) sigaddset(&uact.sa_mask, sig);
158 self->ul_sigmask = uact.sa_mask;
159 self->ul_siglink = ucp;
160 (void) __lwp_sigmask(SIG_SETMASK, &uact.sa_mask);
161
162 /*
163 * If this thread has been sent SIGCANCEL from the kernel
164 * or from pthread_cancel(), it is being asked to exit.
165 * The kernel may send SIGCANCEL without a siginfo struct.
166 * If the SIGCANCEL is process-directed (from kill() or
167 * sigqueue()), treat it as an ordinary signal.
168 */
169 if (sig == SIGCANCEL) {
170 if (sip == NULL || SI_FROMKERNEL(sip) ||
171 sip->si_code == SI_LWP) {
172 do_sigcancel();
173 goto out;
174 }
175 /* SIGCANCEL is ignored by default */
176 if (uact.sa_sigaction == SIG_DFL ||
177 uact.sa_sigaction == SIG_IGN)
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2014 Ryan Zezeski. All rights reserved.
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 #include "lint.h"
29 #include <sys/feature_tests.h>
30 /*
31 * setcontext() really can return, if UC_CPU is not specified.
32 * Make the compiler shut up about it.
33 */
34 #if defined(__NORETURN)
35 #undef __NORETURN
36 #endif
37 #define __NORETURN
38 #include "thr_uberdata.h"
39 #include "asyncio.h"
40 #include <signal.h>
41 #include <siginfo.h>
42 #include <sys/systm.h>
43
54 * We only test valid signal bits, not rubbish following MAXSIG
55 * (for speed). Algorithm:
56 * if (s1 & fillset) == (s2 & fillset) then (s1 ^ s2) & fillset == 0
57 */
58 /* see lib/libc/inc/thr_uberdata.h for why this must be true */
59 #if (MAXSIG > (2 * 32) && MAXSIG <= (3 * 32))
60 return (!((s1->__sigbits[0] ^ s2->__sigbits[0]) |
61 (s1->__sigbits[1] ^ s2->__sigbits[1]) |
62 ((s1->__sigbits[2] ^ s2->__sigbits[2]) & FILLSET2)));
63 #else
64 #error "fix me: MAXSIG out of bounds"
65 #endif
66 }
67
68 /*
69 * Common code for calling the user-specified signal handler.
70 */
71 void
72 call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
73 {
74 int i;
75 ulwp_t *self = curthread;
76 uberdata_t *udp = self->ul_uberdata;
77 struct sigaction uact;
78 volatile struct sigaction *sap;
79
80 /*
81 * If we are taking a signal while parked or about to be parked
82 * on __lwp_park() then remove ourself from the sleep queue so
83 * that we can grab locks. The code in mutex_lock_queue() and
84 * cond_wait_common() will detect this and deal with it when
85 * __lwp_park() returns.
86 */
87 unsleep_self();
88 set_parking_flag(self, 0);
89
90 if (__td_event_report(self, TD_CATCHSIG, udp)) {
91 self->ul_td_evbuf.eventnum = TD_CATCHSIG;
92 self->ul_td_evbuf.eventdata = (void *)(intptr_t)sig;
93 tdb_event(TD_CATCHSIG, udp);
94 }
140 * signal mask for sigsuspend() or pollsys() (self->ul_tmpmask) but
141 * /proc can override this via PCSSIG, so we don't bother.
142 *
143 * We would also like to ASSERT() that the signal mask at the previous
144 * level equals self->ul_sigmask (maskset for sigsuspend() / pollsys()),
145 * but /proc can change the thread's signal mask via PCSHOLD, so we
146 * don't bother with that either.
147 */
148 ASSERT(ucp->uc_flags & UC_SIGMASK);
149 if (self->ul_sigsuspend) {
150 ucp->uc_sigmask = self->ul_sigmask;
151 self->ul_sigsuspend = 0;
152 /* the sigsuspend() or pollsys() signal mask */
153 sigorset(&uact.sa_mask, &self->ul_tmpmask);
154 } else {
155 /* the signal mask at the previous level */
156 sigorset(&uact.sa_mask, &ucp->uc_sigmask);
157 }
158 if (!(uact.sa_flags & SA_NODEFER)) /* add current signal */
159 (void) sigaddset(&uact.sa_mask, sig);
160
161 /*
162 * Enforce the proper order for realtime signals. Lower signals
163 * have higher priority and multiple instances of the same signal
164 * must arrive in FIFO order (NODEFER does not apply).
165 *
166 * See section 2.4.2 of POSIX.
167 */
168 if ((sig >= SIGRTMIN) && (sig <= SIGRTMAX)) {
169 for (i = sig; i <= SIGRTMAX; i++) {
170 (void) sigaddset(&uact.sa_mask, i);
171 }
172 }
173
174 self->ul_sigmask = uact.sa_mask;
175 self->ul_siglink = ucp;
176 (void) __lwp_sigmask(SIG_SETMASK, &uact.sa_mask);
177
178 /*
179 * If this thread has been sent SIGCANCEL from the kernel
180 * or from pthread_cancel(), it is being asked to exit.
181 * The kernel may send SIGCANCEL without a siginfo struct.
182 * If the SIGCANCEL is process-directed (from kill() or
183 * sigqueue()), treat it as an ordinary signal.
184 */
185 if (sig == SIGCANCEL) {
186 if (sip == NULL || SI_FROMKERNEL(sip) ||
187 sip->si_code == SI_LWP) {
188 do_sigcancel();
189 goto out;
190 }
191 /* SIGCANCEL is ignored by default */
192 if (uact.sa_sigaction == SIG_DFL ||
193 uact.sa_sigaction == SIG_IGN)
|