1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1996 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include "signalmap.h"
30 #include <sys/signal.h>
31 #include <sys/errno.h>
32
33 extern int errno;
34 void (*handlers[32])(); /* XXX - 32??? NSIG, maybe? */
35
36 void
maphandler(int sig,int code,struct sigcontext * scp,char * addr)37 maphandler(int sig, int code, struct sigcontext *scp, char *addr)
38 {
39 switch (sig) {
40 case SIGBUS:
41 case SIGSEGV:
42 switch (FC_CODE(code)) {
43 case 3: /* 5.x value for FC_OBJERR */
44 code = FC_MAKE_ERR(FC_ERRNO(code));
45 break;
46 case 5: /* 5.x value for FC_NOMAP */
47 code = FC_NOMAP;
48 break;
49 }
50 break;
51 }
52 __sendsig(maptooldsig(sig), code, scp, addr, handlers[sig]);
53 }
54
55 void (*
signal(int sig,void (* a)(int))56 signal(int sig, void (*a)(int)))(int)
57 {
58 int newsig;
59
60 struct sigvec osv, sv;
61
62 sv.sv_handler = a;
63 sv.sv_mask = 0;
64 #ifdef S5EMUL
65 sv.sv_flags = SV_INTERRUPT|SV_RESETHAND;
66 #else
67 sv.sv_flags = 0;
68 #endif
69 if (sigvec(sig, &sv, &osv) < 0)
70 return (BADSIG);
71 return (osv.sv_handler);
72 }
73
74
75 int
sigvec(int sig,struct sigvec * nvec,struct sigvec * ovec)76 sigvec(int sig, struct sigvec *nvec, struct sigvec *ovec)
77 {
78 int newsig;
79 struct sigvec tvec, *tvecp;
80 void (*oldhand)(int);
81
82 if ((int)nvec == -1 || (int)ovec == -1) {
83 errno = EFAULT;
84 return (-1);
85 }
86
87 newsig = maptonewsig(sig);
88 oldhand = handlers[newsig];
89
90 if ((tvecp = nvec) != 0) {
91 tvec = *nvec;
92 tvecp = &tvec;
93 /*
94 * To be compatible with the behavior of SunOS 4.x:
95 * If the new signal handler is SIG_IGN or SIG_DFL,
96 * do not change the signal's entry in the handler array.
97 * This allows a child of vfork(2) to set signal handlers
98 * to SIG_IGN or SIG_DFL without affecting the parent.
99 */
100 if (tvecp->sv_handler != SIG_DFL &&
101 tvecp->sv_handler != SIG_IGN) {
102 handlers[newsig] = tvecp->sv_handler;
103 tvecp->sv_handler = maphandler;
104 }
105 }
106
107 if (ucbsigvec(newsig, tvecp, ovec) == -1) {
108 handlers[newsig] = oldhand;
109 return (-1);
110 }
111
112 if (ovec && ovec->sv_handler != SIG_DFL && ovec->sv_handler != SIG_IGN)
113 ovec->sv_handler = oldhand;
114
115 return (0);
116 }
117
118 int
sigsetmask(int mask)119 sigsetmask(int mask)
120 {
121 int ret;
122 ret = ucbsigsetmask(maptonewmask(mask));
123 return (maptooldmask(ret));
124 }
125
126 int
sigblock(int mask)127 sigblock(int mask)
128 {
129 int ret;
130 ret = ucbsigblock(maptonewmask(mask));
131 return (maptooldmask(ret));
132 }
133
134
135 int
sigpause(int mask)136 sigpause(int mask)
137 {
138 int ret;
139 return (ucbsigpause(maptonewmask(mask)));
140 }
141
142 int
siginterrupt(int sig,int flag)143 siginterrupt(int sig, int flag)
144 {
145 return (ucbsiginterrupt(maptonewsig(sig), flag));
146 }
147
148
149 int
maptonewsig(int sig)150 maptonewsig(int sig)
151 {
152 switch (sig) {
153 case SIGURG: /* urgent condition on IO channel */
154 return (XSIGURG);
155 case SIGSTOP: /* sendable stop signal not from tty */
156 return (XSIGSTOP);
157 case SIGTSTP: /* stop signal from tty */
158 return (XSIGTSTP);
159 case SIGCONT: /* continue a stopped process */
160 return (XSIGCONT);
161 case SIGCLD: /* System V name for SIGCHLD */
162 return (XSIGCLD);
163 case SIGTTIN: /* to readers pgrp upon background tty read */
164 return (XSIGTTIN);
165 case SIGTTOU: /* like TTIN for output */
166 return (XSIGTTOU);
167 case SIGIO: /* input/output possible signal */
168 return (XSIGIO);
169 case SIGXCPU: /* exceeded CPU time limit */
170 return (XSIGXCPU);
171 case SIGXFSZ: /* exceeded file size limit */
172 return (XSIGXFSZ);
173 case SIGVTALRM: /* virtual time alarm */
174 return (XSIGVTALRM);
175 case SIGPROF: /* profiling time alarm */
176 return (XSIGPROF);
177 case SIGWINCH: /* window changed */
178 return (XSIGWINCH);
179 case SIGLOST: /* resource lost, not supported */
180 return (-1);
181 case SIGUSR1:
182 return (XSIGUSR1);
183 case SIGUSR2: /* user defined signal 2 */
184 return (XSIGUSR2);
185 default:
186 return (sig);
187 }
188 }
189
190 int
maptooldsig(int sig)191 maptooldsig(int sig)
192 {
193 switch (sig) {
194 case XSIGURG: /* urgent condition on IO channel */
195 return (SIGURG);
196 case XSIGSTOP: /* sendable stop signal not from tty */
197 return (SIGSTOP);
198 case XSIGTSTP: /* stop signal from tty */
199 return (SIGTSTP);
200 case XSIGCONT: /* continue a stopped process */
201 return (SIGCONT);
202 case XSIGCLD: /* System V name for SIGCHLD */
203 return (SIGCLD);
204 case XSIGTTIN: /* to readers pgrp upon background tty read */
205 return (SIGTTIN);
206 case XSIGTTOU: /* like TTIN for output */
207 return (SIGTTOU);
208 case XSIGIO: /* input/output possible signal */
209 return (SIGIO);
210 case XSIGXCPU: /* exceeded CPU time limit */
211 return (SIGXCPU);
212 case XSIGXFSZ: /* exceeded file size limit */
213 return (SIGXFSZ);
214 case XSIGVTALRM: /* virtual time alarm */
215 return (SIGVTALRM);
216 case XSIGPROF: /* profiling time alarm */
217 return (SIGPROF);
218 case XSIGWINCH: /* window changed */
219 return (SIGWINCH);
220 case XSIGUSR1:
221 return (SIGUSR1);
222 case XSIGUSR2: /* user defined signal 2 */
223 return (SIGUSR2);
224 case XSIGPWR: /* user defined signal 2 */
225 return (-1);
226 default:
227 return (sig);
228 }
229 }
230
231 int
maptooldmask(int mask)232 maptooldmask(int mask)
233 {
234 int omask;
235
236 omask = mask & 0x7FFF; /* these signo are same */
237
238 if (mask & sigmask(XSIGURG))
239 omask |= sigmask(SIGURG);
240 if (mask & sigmask(XSIGSTOP))
241 omask |= sigmask(SIGSTOP);
242 if (mask & sigmask(XSIGTSTP))
243 omask |= sigmask(SIGTSTP);
244 if (mask & sigmask(XSIGCONT))
245 omask |= sigmask(SIGCONT);
246 if (mask & sigmask(XSIGCLD))
247 omask |= sigmask(SIGCLD);
248 if (mask & sigmask(XSIGTTIN))
249 omask |= sigmask(SIGTTIN);
250 if (mask & sigmask(XSIGTTOU))
251 omask |= sigmask(SIGTTOU);
252 if (mask & sigmask(XSIGIO))
253 omask |= sigmask(SIGIO);
254 if (mask & sigmask(XSIGXCPU))
255 omask |= sigmask(SIGXCPU);
256 if (mask & sigmask(XSIGXFSZ))
257 omask |= sigmask(SIGXFSZ);
258 if (mask & sigmask(XSIGVTALRM))
259 omask |= sigmask(SIGVTALRM);
260 if (mask & sigmask(XSIGPROF))
261 omask |= sigmask(SIGPROF);
262 if (mask & sigmask(XSIGWINCH))
263 omask |= sigmask(SIGWINCH);
264 if (mask & sigmask(XSIGUSR1))
265 omask |= sigmask(SIGUSR1);
266 if (mask & sigmask(XSIGUSR2))
267 omask |= sigmask(SIGUSR2);
268 return (omask);
269 }
270
271
272 int
maptonewmask(int omask)273 maptonewmask(int omask)
274 {
275 int mask;
276
277 if (omask == -1) {
278 return (-1);
279 }
280
281 mask = omask & 0x7FFF; /* these signo are the same */
282
283 if (omask & sigmask(SIGURG))
284 mask |= sigmask(XSIGURG);
285 if (omask & sigmask(SIGSTOP))
286 mask |= sigmask(XSIGSTOP);
287 if (omask & sigmask(SIGTSTP))
288 mask |= sigmask(XSIGTSTP);
289 if (omask & sigmask(SIGCONT))
290 mask |= sigmask(XSIGCONT);
291 if (omask & sigmask(SIGCLD))
292 mask |= sigmask(XSIGCLD);
293 if (omask & sigmask(SIGTTIN))
294 mask |= sigmask(XSIGTTIN);
295 if (omask & sigmask(SIGTTOU))
296 mask |= sigmask(XSIGTTOU);
297 if (omask & sigmask(SIGIO))
298 mask |= sigmask(XSIGIO);
299 if (omask & sigmask(SIGXCPU))
300 mask |= sigmask(XSIGXCPU);
301 if (omask & sigmask(SIGXFSZ))
302 mask |= sigmask(XSIGXFSZ);
303 if (omask & sigmask(SIGVTALRM))
304 mask |= sigmask(XSIGVTALRM);
305 if (omask & sigmask(SIGPROF))
306 mask |= sigmask(XSIGPROF);
307 if (omask & sigmask(SIGWINCH))
308 mask |= sigmask(XSIGWINCH);
309 if (omask & sigmask(SIGUSR1))
310 mask |= sigmask(XSIGUSR1);
311 if (omask & sigmask(SIGUSR2))
312 mask |= sigmask(XSIGUSR2);
313 return (mask);
314 }
315