xref: /onnv-gate/usr/src/ucblib/libucb/i386/sys/signal.c (revision 0:68f95e015346)
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 2004 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 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /*
31*0Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
32*0Sstevel@tonic-gate  * under license from the Regents of the University of California.
33*0Sstevel@tonic-gate  */
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate /*
36*0Sstevel@tonic-gate  * 4.3BSD signal compatibility functions
37*0Sstevel@tonic-gate  *
38*0Sstevel@tonic-gate  * the implementation interprets signal masks equal to -1 as "all of the
39*0Sstevel@tonic-gate  * signals in the signal set", thereby allowing signals with numbers
40*0Sstevel@tonic-gate  * above 32 to be blocked when referenced in code such as:
41*0Sstevel@tonic-gate  *
42*0Sstevel@tonic-gate  *	for (i = 0; i < NSIG; i++)
43*0Sstevel@tonic-gate  *		mask |= sigmask(i)
44*0Sstevel@tonic-gate  */
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate #include <sys/types.h>
49*0Sstevel@tonic-gate #include <ucontext.h>
50*0Sstevel@tonic-gate #include <signal.h>
51*0Sstevel@tonic-gate #include <errno.h>
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #undef	BUS_OBJERR	/* namespace conflict */
54*0Sstevel@tonic-gate #include <sys/siginfo.h>
55*0Sstevel@tonic-gate #include "libc.h"
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate #pragma weak sigvechandler = _sigvechandler
58*0Sstevel@tonic-gate #pragma weak sigsetmask = _sigsetmask
59*0Sstevel@tonic-gate #pragma weak sigblock = _sigblock
60*0Sstevel@tonic-gate #pragma weak sigpause = usigpause
61*0Sstevel@tonic-gate #pragma weak sigvec = _sigvec
62*0Sstevel@tonic-gate #pragma weak sigstack = _sigstack
63*0Sstevel@tonic-gate #pragma weak signal = usignal
64*0Sstevel@tonic-gate #pragma weak siginterrupt = _siginterrupt
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate #define	set2mask(setp) ((setp)->__sigbits[0])
67*0Sstevel@tonic-gate #define	mask2set(mask, setp) \
68*0Sstevel@tonic-gate 	((mask) == -1 ? sigfillset(setp) : \
69*0Sstevel@tonic-gate 	    (sigemptyset(setp), (((setp)->__sigbits[0]) = (int)(mask))))
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate void (*_siguhandler[NSIG])() = { 0 };
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate /* forward declarations */
74*0Sstevel@tonic-gate int ucbsigsetmask(int);
75*0Sstevel@tonic-gate int ucbsigblock(int);
76*0Sstevel@tonic-gate int ucbsigvec(int, struct sigvec *, struct sigvec *);
77*0Sstevel@tonic-gate int ucbsigpause(int);
78*0Sstevel@tonic-gate int ucbsiginterrupt(int, int);
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate /*
81*0Sstevel@tonic-gate  * sigvechandler is the real signal handler installed for all
82*0Sstevel@tonic-gate  * signals handled in the 4.3BSD compatibility interface - it translates
83*0Sstevel@tonic-gate  * SVR4 signal hander arguments into 4.3BSD signal handler arguments
84*0Sstevel@tonic-gate  * and then calls the real handler
85*0Sstevel@tonic-gate  */
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate void
88*0Sstevel@tonic-gate _sigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp)
89*0Sstevel@tonic-gate {
90*0Sstevel@tonic-gate 	static void ucbsigvechandler();
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate 	ucbsigvechandler(sig, sip, ucp);
93*0Sstevel@tonic-gate }
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate static void
96*0Sstevel@tonic-gate ucbsigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp)
97*0Sstevel@tonic-gate {
98*0Sstevel@tonic-gate 	struct sigcontext sc;
99*0Sstevel@tonic-gate 	int code;
100*0Sstevel@tonic-gate 	char *addr;
101*0Sstevel@tonic-gate 	int i, j;
102*0Sstevel@tonic-gate 	int gwinswitch = 0;
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	sc.sc_onstack = ((ucp->uc_stack.ss_flags & SS_ONSTACK) != 0);
105*0Sstevel@tonic-gate 	sc.sc_mask = set2mask(&ucp->uc_sigmask);
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate #if defined(__amd64)
108*0Sstevel@tonic-gate 	sc.sc_sp = (long)ucp->uc_mcontext.gregs[REG_RSP];
109*0Sstevel@tonic-gate 	sc.sc_pc = (long)ucp->uc_mcontext.gregs[REG_RIP];
110*0Sstevel@tonic-gate 	sc.sc_ps = (long)ucp->uc_mcontext.gregs[REG_RFL];
111*0Sstevel@tonic-gate 	sc.sc_r0 = (long)ucp->uc_mcontext.gregs[REG_RAX];
112*0Sstevel@tonic-gate 	sc.sc_r1 = (long)ucp->uc_mcontext.gregs[REG_RDX];
113*0Sstevel@tonic-gate #else
114*0Sstevel@tonic-gate 	sc.sc_sp = (int)ucp->uc_mcontext.gregs[UESP];
115*0Sstevel@tonic-gate 	sc.sc_pc = (int)ucp->uc_mcontext.gregs[EIP];
116*0Sstevel@tonic-gate 	sc.sc_ps = (int)ucp->uc_mcontext.gregs[EFL];
117*0Sstevel@tonic-gate 	sc.sc_r0 = (int)ucp->uc_mcontext.gregs[EAX];
118*0Sstevel@tonic-gate 	sc.sc_r1 = (int)ucp->uc_mcontext.gregs[EDX];
119*0Sstevel@tonic-gate #endif
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate 	/*
122*0Sstevel@tonic-gate 	 * Translate signal codes from new to old.
123*0Sstevel@tonic-gate 	 * /usr/include/sys/siginfo.h contains new codes.
124*0Sstevel@tonic-gate 	 * /usr/ucbinclude/sys/signal.h contains old codes.
125*0Sstevel@tonic-gate 	 */
126*0Sstevel@tonic-gate 	code = 0;
127*0Sstevel@tonic-gate 	addr = SIG_NOADDR;
128*0Sstevel@tonic-gate 	if (sip != NULL && SI_FROMKERNEL(sip)) {
129*0Sstevel@tonic-gate 		addr = sip->si_addr;
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 		switch (sig) {
132*0Sstevel@tonic-gate 		case SIGILL:
133*0Sstevel@tonic-gate 		case SIGFPE:
134*0Sstevel@tonic-gate 			code = ILL_ILLINSTR_FAULT;
135*0Sstevel@tonic-gate 			break;
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 		case SIGBUS:
138*0Sstevel@tonic-gate 			switch (sip->si_code) {
139*0Sstevel@tonic-gate 			case BUS_ADRALN:
140*0Sstevel@tonic-gate 				code = BUS_ALIGN;
141*0Sstevel@tonic-gate 				break;
142*0Sstevel@tonic-gate 			case BUS_ADRERR:
143*0Sstevel@tonic-gate 				code = BUS_HWERR;
144*0Sstevel@tonic-gate 				break;
145*0Sstevel@tonic-gate 			default:	/* BUS_OBJERR */
146*0Sstevel@tonic-gate 				code = FC_MAKE_ERR(sip->si_errno);
147*0Sstevel@tonic-gate 				break;
148*0Sstevel@tonic-gate 			}
149*0Sstevel@tonic-gate 			break;
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 		case SIGSEGV:
152*0Sstevel@tonic-gate 			switch (sip->si_code) {
153*0Sstevel@tonic-gate 			case SEGV_MAPERR:
154*0Sstevel@tonic-gate 				code = SEGV_NOMAP;
155*0Sstevel@tonic-gate 				break;
156*0Sstevel@tonic-gate 			case SEGV_ACCERR:
157*0Sstevel@tonic-gate 				code = SEGV_PROT;
158*0Sstevel@tonic-gate 				break;
159*0Sstevel@tonic-gate 			default:
160*0Sstevel@tonic-gate 				code = FC_MAKE_ERR(sip->si_errno);
161*0Sstevel@tonic-gate 				break;
162*0Sstevel@tonic-gate 			}
163*0Sstevel@tonic-gate 			break;
164*0Sstevel@tonic-gate 
165*0Sstevel@tonic-gate 		default:
166*0Sstevel@tonic-gate 			addr = SIG_NOADDR;
167*0Sstevel@tonic-gate 			break;
168*0Sstevel@tonic-gate 		}
169*0Sstevel@tonic-gate 	}
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate 	(*_siguhandler[sig])(sig, code, &sc, addr);
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate 	if (sc.sc_onstack)
174*0Sstevel@tonic-gate 		ucp->uc_stack.ss_flags |= SS_ONSTACK;
175*0Sstevel@tonic-gate 	else
176*0Sstevel@tonic-gate 		ucp->uc_stack.ss_flags &= ~SS_ONSTACK;
177*0Sstevel@tonic-gate 	mask2set(sc.sc_mask, &ucp->uc_sigmask);
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate #if defined(__amd64)
180*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[REG_RSP] = (long)sc.sc_sp;
181*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[REG_RIP] = (long)sc.sc_pc;
182*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[REG_RFL] = (long)sc.sc_ps;
183*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[REG_RAX] = (long)sc.sc_r0;
184*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[REG_RDX] = (long)sc.sc_r1;
185*0Sstevel@tonic-gate #else
186*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[UESP] = (int)sc.sc_sp;
187*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[EIP] = (int)sc.sc_pc;
188*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[EFL] = (int)sc.sc_ps;
189*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[EAX] = (int)sc.sc_r0;
190*0Sstevel@tonic-gate 	ucp->uc_mcontext.gregs[EDX] = (int)sc.sc_r1;
191*0Sstevel@tonic-gate #endif
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate 	setcontext(ucp);
194*0Sstevel@tonic-gate }
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate int
197*0Sstevel@tonic-gate _sigsetmask(int mask)
198*0Sstevel@tonic-gate {
199*0Sstevel@tonic-gate 	return (ucbsigsetmask(mask));
200*0Sstevel@tonic-gate }
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate int
203*0Sstevel@tonic-gate ucbsigsetmask(int mask)
204*0Sstevel@tonic-gate {
205*0Sstevel@tonic-gate 	sigset_t oset;
206*0Sstevel@tonic-gate 	sigset_t nset;
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	(void) sigprocmask(0, (sigset_t *)0, &nset);
209*0Sstevel@tonic-gate 	mask2set(mask, &nset);
210*0Sstevel@tonic-gate 	(void) sigprocmask(SIG_SETMASK, &nset, &oset);
211*0Sstevel@tonic-gate 	return (set2mask(&oset));
212*0Sstevel@tonic-gate }
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate int
215*0Sstevel@tonic-gate _sigblock(int mask)
216*0Sstevel@tonic-gate {
217*0Sstevel@tonic-gate 	return (ucbsigblock(mask));
218*0Sstevel@tonic-gate }
219*0Sstevel@tonic-gate 
220*0Sstevel@tonic-gate int
221*0Sstevel@tonic-gate ucbsigblock(int mask)
222*0Sstevel@tonic-gate {
223*0Sstevel@tonic-gate 	sigset_t oset;
224*0Sstevel@tonic-gate 	sigset_t nset;
225*0Sstevel@tonic-gate 
226*0Sstevel@tonic-gate 	(void) sigprocmask(0, (sigset_t *)0, &nset);
227*0Sstevel@tonic-gate 	mask2set(mask, &nset);
228*0Sstevel@tonic-gate 	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
229*0Sstevel@tonic-gate 	return (set2mask(&oset));
230*0Sstevel@tonic-gate }
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate int
233*0Sstevel@tonic-gate usigpause(int mask)
234*0Sstevel@tonic-gate {
235*0Sstevel@tonic-gate 	return (ucbsigpause(mask));
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate 
238*0Sstevel@tonic-gate int
239*0Sstevel@tonic-gate ucbsigpause(int mask)
240*0Sstevel@tonic-gate {
241*0Sstevel@tonic-gate 	sigset_t set, oset;
242*0Sstevel@tonic-gate 	int ret;
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate 	(void) sigprocmask(0, (sigset_t *)0, &set);
245*0Sstevel@tonic-gate 	oset = set;
246*0Sstevel@tonic-gate 	mask2set(mask, &set);
247*0Sstevel@tonic-gate 	ret = sigsuspend(&set);
248*0Sstevel@tonic-gate 	(void) sigprocmask(SIG_SETMASK, &oset, (sigset_t *)0);
249*0Sstevel@tonic-gate 	return (ret);
250*0Sstevel@tonic-gate }
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate int
253*0Sstevel@tonic-gate _sigvec(int sig, struct sigvec *nvec, struct sigvec *ovec)
254*0Sstevel@tonic-gate {
255*0Sstevel@tonic-gate 	return (ucbsigvec(sig, nvec, ovec));
256*0Sstevel@tonic-gate }
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate int
259*0Sstevel@tonic-gate ucbsigvec(int sig, struct sigvec *nvec, struct sigvec *ovec)
260*0Sstevel@tonic-gate {
261*0Sstevel@tonic-gate 	struct sigaction nact;
262*0Sstevel@tonic-gate 	struct sigaction oact;
263*0Sstevel@tonic-gate 	struct sigaction *nactp;
264*0Sstevel@tonic-gate 	void (*ohandler)(), (*nhandler)();
265*0Sstevel@tonic-gate 
266*0Sstevel@tonic-gate 	if (sig <= 0 || sig >= NSIG) {
267*0Sstevel@tonic-gate 		errno = EINVAL;
268*0Sstevel@tonic-gate 		return (-1);
269*0Sstevel@tonic-gate 	}
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate 	if ((intptr_t)ovec == -1 || (intptr_t)nvec == -1) {
272*0Sstevel@tonic-gate 		errno = EFAULT;
273*0Sstevel@tonic-gate 		return (-1);
274*0Sstevel@tonic-gate 	}
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate 	ohandler = _siguhandler[sig];
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate 	if (nvec) {
279*0Sstevel@tonic-gate 		_sigaction(sig, (struct sigaction *)0, &nact);
280*0Sstevel@tonic-gate 		nhandler = nvec->sv_handler;
281*0Sstevel@tonic-gate 		/*
282*0Sstevel@tonic-gate 		 * To be compatible with the behavior of SunOS 4.x:
283*0Sstevel@tonic-gate 		 * If the new signal handler is SIG_IGN or SIG_DFL,
284*0Sstevel@tonic-gate 		 * do not change the signal's entry in the handler array.
285*0Sstevel@tonic-gate 		 * This allows a child of vfork(2) to set signal handlers
286*0Sstevel@tonic-gate 		 * to SIG_IGN or SIG_DFL without affecting the parent.
287*0Sstevel@tonic-gate 		 */
288*0Sstevel@tonic-gate 		if (nhandler != SIG_DFL && nhandler != SIG_IGN) {
289*0Sstevel@tonic-gate 			_siguhandler[sig] = nhandler;
290*0Sstevel@tonic-gate 			nact.sa_handler = (void (*)())ucbsigvechandler;
291*0Sstevel@tonic-gate 		} else {
292*0Sstevel@tonic-gate 			nact.sa_handler = nhandler;
293*0Sstevel@tonic-gate 		}
294*0Sstevel@tonic-gate 		mask2set(nvec->sv_mask, &nact.sa_mask);
295*0Sstevel@tonic-gate 		if (sig == SIGKILL || sig == SIGSTOP)
296*0Sstevel@tonic-gate 			nact.sa_handler = SIG_DFL;
297*0Sstevel@tonic-gate 		nact.sa_flags = SA_SIGINFO;
298*0Sstevel@tonic-gate 		if (!(nvec->sv_flags & SV_INTERRUPT))
299*0Sstevel@tonic-gate 			nact.sa_flags |= SA_RESTART;
300*0Sstevel@tonic-gate 		if (nvec->sv_flags & SV_RESETHAND)
301*0Sstevel@tonic-gate 			nact.sa_flags |= SA_RESETHAND;
302*0Sstevel@tonic-gate 		if (nvec->sv_flags & SV_ONSTACK)
303*0Sstevel@tonic-gate 			nact.sa_flags |= SA_ONSTACK;
304*0Sstevel@tonic-gate 		nactp = &nact;
305*0Sstevel@tonic-gate 	} else
306*0Sstevel@tonic-gate 		nactp = (struct sigaction *)0;
307*0Sstevel@tonic-gate 
308*0Sstevel@tonic-gate 	if (_sigaction(sig, nactp, &oact) < 0) {
309*0Sstevel@tonic-gate 		_siguhandler[sig] = ohandler;
310*0Sstevel@tonic-gate 		return (-1);
311*0Sstevel@tonic-gate 	}
312*0Sstevel@tonic-gate 
313*0Sstevel@tonic-gate 	if (ovec) {
314*0Sstevel@tonic-gate 		if (oact.sa_handler == SIG_DFL || oact.sa_handler == SIG_IGN)
315*0Sstevel@tonic-gate 			ovec->sv_handler = oact.sa_handler;
316*0Sstevel@tonic-gate 		else
317*0Sstevel@tonic-gate 			ovec->sv_handler = ohandler;
318*0Sstevel@tonic-gate 		ovec->sv_mask = set2mask(&oact.sa_mask);
319*0Sstevel@tonic-gate 		ovec->sv_flags = 0;
320*0Sstevel@tonic-gate 		if (oact.sa_flags & SA_ONSTACK)
321*0Sstevel@tonic-gate 			ovec->sv_flags |= SV_ONSTACK;
322*0Sstevel@tonic-gate 		if (oact.sa_flags & SA_RESETHAND)
323*0Sstevel@tonic-gate 			ovec->sv_flags |= SV_RESETHAND;
324*0Sstevel@tonic-gate 		if (!(oact.sa_flags & SA_RESTART))
325*0Sstevel@tonic-gate 			ovec->sv_flags |= SV_INTERRUPT;
326*0Sstevel@tonic-gate 	}
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate 	return (0);
329*0Sstevel@tonic-gate }
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate int
332*0Sstevel@tonic-gate _sigstack(struct sigstack *nss, struct sigstack *oss)
333*0Sstevel@tonic-gate {
334*0Sstevel@tonic-gate 	struct sigaltstack nalt;
335*0Sstevel@tonic-gate 	struct sigaltstack oalt;
336*0Sstevel@tonic-gate 	struct sigaltstack *naltp;
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate 	if (nss) {
339*0Sstevel@tonic-gate 		/*
340*0Sstevel@tonic-gate 		 * assumes stack growth is down (like sparc and x86)
341*0Sstevel@tonic-gate 		 */
342*0Sstevel@tonic-gate 		nalt.ss_sp = nss->ss_sp - SIGSTKSZ;
343*0Sstevel@tonic-gate 		nalt.ss_size = SIGSTKSZ;
344*0Sstevel@tonic-gate 		nalt.ss_flags = 0;
345*0Sstevel@tonic-gate 		naltp = &nalt;
346*0Sstevel@tonic-gate 	} else
347*0Sstevel@tonic-gate 		naltp = (struct sigaltstack *)0;
348*0Sstevel@tonic-gate 
349*0Sstevel@tonic-gate 	if (sigaltstack(naltp, &oalt) < 0)
350*0Sstevel@tonic-gate 		return (-1);
351*0Sstevel@tonic-gate 
352*0Sstevel@tonic-gate 	if (oss) {
353*0Sstevel@tonic-gate 		/*
354*0Sstevel@tonic-gate 		 * assumes stack growth is down (like sparc and x86)
355*0Sstevel@tonic-gate 		 */
356*0Sstevel@tonic-gate 		oss->ss_sp = oalt.ss_sp + oalt.ss_size;
357*0Sstevel@tonic-gate 		oss->ss_onstack = ((oalt.ss_flags & SS_ONSTACK) != 0);
358*0Sstevel@tonic-gate 	}
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate 	return (0);
361*0Sstevel@tonic-gate }
362*0Sstevel@tonic-gate 
363*0Sstevel@tonic-gate void (*
364*0Sstevel@tonic-gate ucbsignal(int s, void (*a)()))()
365*0Sstevel@tonic-gate {
366*0Sstevel@tonic-gate 	struct sigvec osv;
367*0Sstevel@tonic-gate 	struct sigvec nsv;
368*0Sstevel@tonic-gate 	static int mask[NSIG];
369*0Sstevel@tonic-gate 	static int flags[NSIG];
370*0Sstevel@tonic-gate 
371*0Sstevel@tonic-gate 	nsv.sv_handler = a;
372*0Sstevel@tonic-gate 	nsv.sv_mask = mask[s];
373*0Sstevel@tonic-gate 	nsv.sv_flags = flags[s];
374*0Sstevel@tonic-gate 	if (ucbsigvec(s, &nsv, &osv) < 0)
375*0Sstevel@tonic-gate 		return (SIG_ERR);
376*0Sstevel@tonic-gate 	if (nsv.sv_mask != osv.sv_mask || nsv.sv_flags != osv.sv_flags) {
377*0Sstevel@tonic-gate 		mask[s] = nsv.sv_mask = osv.sv_mask;
378*0Sstevel@tonic-gate 		flags[s] = nsv.sv_flags =
379*0Sstevel@tonic-gate 			osv.sv_flags & ~(SV_RESETHAND|SV_INTERRUPT);
380*0Sstevel@tonic-gate 		if (ucbsigvec(s, &nsv, (struct sigvec *)0) < 0)
381*0Sstevel@tonic-gate 			return (SIG_ERR);
382*0Sstevel@tonic-gate 	}
383*0Sstevel@tonic-gate 	return (osv.sv_handler);
384*0Sstevel@tonic-gate }
385*0Sstevel@tonic-gate 
386*0Sstevel@tonic-gate void (*
387*0Sstevel@tonic-gate usignal(int s, void (*a)()))()
388*0Sstevel@tonic-gate {
389*0Sstevel@tonic-gate 	return (ucbsignal(s, a));
390*0Sstevel@tonic-gate }
391*0Sstevel@tonic-gate 
392*0Sstevel@tonic-gate /*
393*0Sstevel@tonic-gate  * Set signal state to prevent restart of system calls
394*0Sstevel@tonic-gate  * after an instance of the indicated signal.
395*0Sstevel@tonic-gate  */
396*0Sstevel@tonic-gate int
397*0Sstevel@tonic-gate _siginterrupt(int sig, int flag)
398*0Sstevel@tonic-gate {
399*0Sstevel@tonic-gate 	return (ucbsiginterrupt(sig, flag));
400*0Sstevel@tonic-gate }
401*0Sstevel@tonic-gate 
402*0Sstevel@tonic-gate int
403*0Sstevel@tonic-gate ucbsiginterrupt(int sig, int flag)
404*0Sstevel@tonic-gate {
405*0Sstevel@tonic-gate 	struct sigvec sv;
406*0Sstevel@tonic-gate 	int ret;
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate 	if ((ret = ucbsigvec(sig, 0, &sv)) < 0)
409*0Sstevel@tonic-gate 		return (ret);
410*0Sstevel@tonic-gate 	if (flag)
411*0Sstevel@tonic-gate 		sv.sv_flags |= SV_INTERRUPT;
412*0Sstevel@tonic-gate 	else
413*0Sstevel@tonic-gate 		sv.sv_flags &= ~SV_INTERRUPT;
414*0Sstevel@tonic-gate 	return (ucbsigvec(sig, &sv, 0));
415*0Sstevel@tonic-gate }
416