xref: /titanic_44/usr/src/lib/libbc/libc/sys/common/signalmap.c (revision a38ddfee9c8c6b6c5a2947ff52fd2338362a4444)
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
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 (*
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
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
119 sigsetmask(int mask)
120 {
121 	int ret;
122 	ret = ucbsigsetmask(maptonewmask(mask));
123 	return (maptooldmask(ret));
124 }
125 
126 int
127 sigblock(int mask)
128 {
129 	int ret;
130 	ret = ucbsigblock(maptonewmask(mask));
131 	return (maptooldmask(ret));
132 }
133 
134 
135 int
136 sigpause(int mask)
137 {
138 	int ret;
139 	return (ucbsigpause(maptonewmask(mask)));
140 }
141 
142 int
143 siginterrupt(int sig, int flag)
144 {
145 	return (ucbsiginterrupt(maptonewsig(sig), flag));
146 }
147 
148 
149 int
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
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
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
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