xref: /titanic_51/usr/src/lib/libbc/libc/sys/common/signalmap.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
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"	/* SVr4.0 1.2	*/
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(sig, code, scp, addr)
37 int sig, code;
38 struct sigcontext *scp;
39 char *addr;
40 {
41 	switch (sig) {
42 		case SIGBUS:
43 		case SIGSEGV:
44 			switch (FC_CODE(code)) {
45 			case 3:		/* 5.x value for FC_OBJERR */
46 				code = FC_MAKE_ERR(FC_ERRNO(code));
47 				break;
48 			case 5:		/* 5.x value for FC_NOMAP */
49 				code = FC_NOMAP;
50 				break;
51 			}
52 			break;
53 	}
54 	__sendsig(maptooldsig(sig), code, scp, addr, handlers[sig]);
55 }
56 
57 void (*signal(sig, a))()
58 int sig;
59 void (*a)();
60 {
61 	int newsig;
62 
63 	struct sigvec osv, sv;
64 
65 	sv.sv_handler = a;
66 	sv.sv_mask = 0;
67 #ifdef S5EMUL
68 	sv.sv_flags = SV_INTERRUPT|SV_RESETHAND;
69 #else
70 	sv.sv_flags = 0;
71 #endif
72 	if (sigvec(sig, &sv, &osv) < 0)
73 		return (BADSIG);
74 	return (osv.sv_handler);
75 }
76 
77 
78 sigvec(sig, nvec, ovec)
79 int sig;
80 struct sigvec *nvec, *ovec;
81 {
82 	int newsig;
83 	struct sigvec tvec, *tvecp;
84 	void (*oldhand)();
85 
86 	if ((int)nvec == -1 || (int)ovec == -1) {
87 		errno = EFAULT;
88 		return (-1);
89 	}
90 
91 	newsig = maptonewsig(sig);
92 	oldhand = handlers[newsig];
93 
94 	if ((tvecp = nvec) != 0) {
95 		tvec = *nvec;
96 		tvecp = &tvec;
97 		/*
98 		 * To be compatible with the behavior of SunOS 4.x:
99 		 * If the new signal handler is SIG_IGN or SIG_DFL,
100 		 * do not change the signal's entry in the handler array.
101 		 * This allows a child of vfork(2) to set signal handlers
102 		 * to SIG_IGN or SIG_DFL without affecting the parent.
103 		 */
104 		if (tvecp->sv_handler != SIG_DFL &&
105 		    tvecp->sv_handler != SIG_IGN) {
106 			handlers[newsig] = tvecp->sv_handler;
107 			tvecp->sv_handler = maphandler;
108 		}
109 	}
110 
111 	if (ucbsigvec(newsig, tvecp, ovec) == -1) {
112 		handlers[newsig] = oldhand;
113 		return (-1);
114 	}
115 
116 	if (ovec && ovec->sv_handler != SIG_DFL && ovec->sv_handler != SIG_IGN)
117 		ovec->sv_handler = oldhand;
118 
119 	return (0);
120 }
121 
122 sigsetmask(mask)
123 int mask;
124 {
125 	int ret;
126 	ret = ucbsigsetmask(maptonewmask(mask));
127 	return(maptooldmask(ret));
128 }
129 
130 sigblock(mask)
131 int mask;
132 {
133 	int ret;
134 	ret = ucbsigblock(maptonewmask(mask));
135 	return(maptooldmask(ret));
136 }
137 
138 
139 int sigpause(mask)
140 int mask;
141 {
142 	int ret;
143 	return(ucbsigpause(maptonewmask(mask)));
144 }
145 
146 siginterrupt(sig, flag)
147 int sig, flag;
148 {
149 	return(ucbsiginterrupt(maptonewsig(sig), flag));
150 }
151 
152 
153 maptonewsig(sig)
154 int	sig;
155 {
156 	switch (sig) {
157 	case SIGURG:               /* urgent condition on IO channel */
158 		return(XSIGURG);
159 	case SIGSTOP:              /* sendable stop signal not from tty */
160 		return(XSIGSTOP);
161 	case SIGTSTP:            /* stop signal from tty */
162 		return(XSIGTSTP);
163 	case SIGCONT:            /* continue a stopped process */
164 		return(XSIGCONT);
165 	case SIGCLD:          /* System V name for SIGCHLD */
166 		return(XSIGCLD);
167 	case SIGTTIN:          /* to readers pgrp upon background tty read */
168 		return(XSIGTTIN);
169 	case SIGTTOU:         /* like TTIN for output */
170 		return(XSIGTTOU);
171 	case SIGIO:        /* input/output possible signal */
172 		return(XSIGIO);
173 	case SIGXCPU:       /* exceeded CPU time limit */
174 		return(XSIGXCPU);
175 	case SIGXFSZ:       /* exceeded file size limit */
176 		return(XSIGXFSZ);
177 	case SIGVTALRM:      /* virtual time alarm */
178 		return(XSIGVTALRM);
179 	case SIGPROF:        /* profiling time alarm */
180 		return(XSIGPROF);
181 	case SIGWINCH:       /* window changed */
182 		return(XSIGWINCH);
183 	case SIGLOST:	     /* resource lost, not supported */
184 		return(-1);
185 	case SIGUSR1:
186 		return(XSIGUSR1);
187 	case SIGUSR2:      /* user defined signal 2 */
188 		return(XSIGUSR2);
189 	default:
190 		return(sig);
191 	}
192 }
193 
194 
195 maptooldsig(sig)
196 int	sig;
197 {
198 	switch (sig) {
199 	case XSIGURG:               /* urgent condition on IO channel */
200 		return(SIGURG);
201 	case XSIGSTOP:              /* sendable stop signal not from tty */
202 		return(SIGSTOP);
203 	case XSIGTSTP:            /* stop signal from tty */
204 		return(SIGTSTP);
205 	case XSIGCONT:            /* continue a stopped process */
206 		return(SIGCONT);
207 	case XSIGCLD:          /* System V name for SIGCHLD */
208 		return(SIGCLD);
209 	case XSIGTTIN:          /* to readers pgrp upon background tty read */
210 		return(SIGTTIN);
211 	case XSIGTTOU:         /* like TTIN for output */
212 		return(SIGTTOU);
213 	case XSIGIO:        /* input/output possible signal */
214 		return(SIGIO);
215 	case XSIGXCPU:       /* exceeded CPU time limit */
216 		return(SIGXCPU);
217 	case XSIGXFSZ:       /* exceeded file size limit */
218 		return(SIGXFSZ);
219 	case XSIGVTALRM:      /* virtual time alarm */
220 		return(SIGVTALRM);
221 	case XSIGPROF:        /* profiling time alarm */
222 		return(SIGPROF);
223 	case XSIGWINCH:       /* window changed */
224 		return(SIGWINCH);
225 	case XSIGUSR1:
226 		return(SIGUSR1);
227 	case XSIGUSR2:      /* user defined signal 2 */
228 		return(SIGUSR2);
229 	case XSIGPWR:      /* user defined signal 2 */
230 		return(-1);
231 	default:
232 		return(sig);
233 	}
234 }
235 
236 int maptooldmask(mask)
237 	int mask;
238 {
239 	int omask;
240 
241 	omask = mask & 0x7FFF;		/* these signo are same */
242 
243 	if (mask & sigmask(XSIGURG))
244 		omask |= sigmask(SIGURG);
245 	if (mask & sigmask(XSIGSTOP))
246 		omask |= sigmask(SIGSTOP);
247 	if (mask & sigmask(XSIGTSTP))
248 		omask |= sigmask(SIGTSTP);
249 	if (mask & sigmask(XSIGCONT))
250 		omask |= sigmask(SIGCONT);
251 	if (mask & sigmask(XSIGCLD))
252 		omask |= sigmask(SIGCLD);
253 	if (mask & sigmask(XSIGTTIN))
254 		omask |= sigmask(SIGTTIN);
255 	if (mask & sigmask(XSIGTTOU))
256 		omask |= sigmask(SIGTTOU);
257 	if (mask & sigmask(XSIGIO))
258 		omask |= sigmask(SIGIO);
259 	if (mask & sigmask(XSIGXCPU))
260 		omask |= sigmask(SIGXCPU);
261 	if (mask & sigmask(XSIGXFSZ))
262 		omask |= sigmask(SIGXFSZ);
263 	if (mask & sigmask(XSIGVTALRM))
264 		omask |= sigmask(SIGVTALRM);
265 	if (mask & sigmask(XSIGPROF))
266 		omask |= sigmask(SIGPROF);
267 	if (mask & sigmask(XSIGWINCH))
268 		omask |= sigmask(SIGWINCH);
269 	if (mask & sigmask(XSIGUSR1))
270 		omask |= sigmask(SIGUSR1);
271 	if (mask & sigmask(XSIGUSR2))
272 		omask |= sigmask(SIGUSR2);
273 	return(omask);
274 }
275 
276 
277 int maptonewmask(omask)
278 	int omask;
279 {
280 	int mask;
281 
282 	if (omask == -1) {
283 		return(-1);
284 	}
285 
286 	mask = omask & 0x7FFF;		/* these signo are the same */
287 
288 	if (omask & sigmask(SIGURG))
289 		mask |= sigmask(XSIGURG);
290 	if (omask & sigmask(SIGSTOP))
291 		mask |= sigmask(XSIGSTOP);
292 	if (omask & sigmask(SIGTSTP))
293 		mask |= sigmask(XSIGTSTP);
294 	if (omask & sigmask(SIGCONT))
295 		mask |= sigmask(XSIGCONT);
296 	if (omask & sigmask(SIGCLD))
297 		mask |= sigmask(XSIGCLD);
298 	if (omask & sigmask(SIGTTIN))
299 		mask |= sigmask(XSIGTTIN);
300 	if (omask & sigmask(SIGTTOU))
301 		mask |= sigmask(XSIGTTOU);
302 	if (omask & sigmask(SIGIO))
303 		mask |= sigmask(XSIGIO);
304 	if (omask & sigmask(SIGXCPU))
305 		mask |= sigmask(XSIGXCPU);
306 	if (omask & sigmask(SIGXFSZ))
307 		mask |= sigmask(XSIGXFSZ);
308 	if (omask & sigmask(SIGVTALRM))
309 		mask |= sigmask(XSIGVTALRM);
310 	if (omask & sigmask(SIGPROF))
311 		mask |= sigmask(XSIGPROF);
312 	if (omask & sigmask(SIGWINCH))
313 		mask |= sigmask(XSIGWINCH);
314 	if (omask & sigmask(SIGUSR1))
315 		mask |= sigmask(XSIGUSR1);
316 	if (omask & sigmask(SIGUSR2))
317 		mask |= sigmask(XSIGUSR2);
318 	return(mask);
319 }
320