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