xref: /titanic_50/usr/src/cmd/sh/fault.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1996, by Sun Microsystems, Inc.
28*7c478bd9Sstevel@tonic-gate  * All rights reserved.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.13.17.1	*/
32*7c478bd9Sstevel@tonic-gate /*
33*7c478bd9Sstevel@tonic-gate  * UNIX shell
34*7c478bd9Sstevel@tonic-gate  */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #include	"defs.h"
37*7c478bd9Sstevel@tonic-gate #include	<sys/procset.h>
38*7c478bd9Sstevel@tonic-gate #include	<siginfo.h>
39*7c478bd9Sstevel@tonic-gate #include	<ucontext.h>
40*7c478bd9Sstevel@tonic-gate #include	<errno.h>
41*7c478bd9Sstevel@tonic-gate #include	<string.h>
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate static	void (*psig0_func)() = SIG_ERR;	/* previous signal handler for signal 0 */
44*7c478bd9Sstevel@tonic-gate static	char sigsegv_stack[SIGSTKSZ];
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate static void sigsegv(int sig, siginfo_t *sip, ucontext_t *uap);
47*7c478bd9Sstevel@tonic-gate static void fault();
48*7c478bd9Sstevel@tonic-gate static BOOL sleeping = 0;
49*7c478bd9Sstevel@tonic-gate static unsigned char *trapcom[MAXTRAP]; /* array of actions, one per signal */
50*7c478bd9Sstevel@tonic-gate static BOOL trapflg[MAXTRAP] =
51*7c478bd9Sstevel@tonic-gate {
52*7c478bd9Sstevel@tonic-gate 	0,
53*7c478bd9Sstevel@tonic-gate 	0,	/* hangup */
54*7c478bd9Sstevel@tonic-gate 	0,	/* interrupt */
55*7c478bd9Sstevel@tonic-gate 	0,	/* quit */
56*7c478bd9Sstevel@tonic-gate 	0,	/* illegal instr */
57*7c478bd9Sstevel@tonic-gate 	0,	/* trace trap */
58*7c478bd9Sstevel@tonic-gate 	0,	/* IOT */
59*7c478bd9Sstevel@tonic-gate 	0,	/* EMT */
60*7c478bd9Sstevel@tonic-gate 	0,	/* float pt. exp */
61*7c478bd9Sstevel@tonic-gate 	0,	/* kill */
62*7c478bd9Sstevel@tonic-gate 	0, 	/* bus error */
63*7c478bd9Sstevel@tonic-gate 	0,	/* memory faults */
64*7c478bd9Sstevel@tonic-gate 	0,	/* bad sys call */
65*7c478bd9Sstevel@tonic-gate 	0,	/* bad pipe call */
66*7c478bd9Sstevel@tonic-gate 	0,	/* alarm */
67*7c478bd9Sstevel@tonic-gate 	0, 	/* software termination */
68*7c478bd9Sstevel@tonic-gate 	0,	/* unassigned */
69*7c478bd9Sstevel@tonic-gate 	0,	/* unassigned */
70*7c478bd9Sstevel@tonic-gate 	0,	/* death of child */
71*7c478bd9Sstevel@tonic-gate 	0,	/* power fail */
72*7c478bd9Sstevel@tonic-gate 	0,	/* window size change */
73*7c478bd9Sstevel@tonic-gate 	0,	/* urgent IO condition */
74*7c478bd9Sstevel@tonic-gate 	0,	/* pollable event occured */
75*7c478bd9Sstevel@tonic-gate 	0,	/* stopped by signal */
76*7c478bd9Sstevel@tonic-gate 	0,	/* stopped by user */
77*7c478bd9Sstevel@tonic-gate 	0,	/* continued */
78*7c478bd9Sstevel@tonic-gate 	0,	/* stopped by tty input */
79*7c478bd9Sstevel@tonic-gate 	0,	/* stopped by tty output */
80*7c478bd9Sstevel@tonic-gate 	0,	/* virtual timer expired */
81*7c478bd9Sstevel@tonic-gate 	0,	/* profiling timer expired */
82*7c478bd9Sstevel@tonic-gate 	0,	/* exceeded cpu limit */
83*7c478bd9Sstevel@tonic-gate 	0,	/* exceeded file size limit */
84*7c478bd9Sstevel@tonic-gate 	0, 	/* process's lwps are blocked */
85*7c478bd9Sstevel@tonic-gate 	0,	/* special signal used by thread library */
86*7c478bd9Sstevel@tonic-gate 	0, 	/* check point freeze */
87*7c478bd9Sstevel@tonic-gate 	0,	/* check point thaw */
88*7c478bd9Sstevel@tonic-gate };
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate static void (*(
91*7c478bd9Sstevel@tonic-gate sigval[MAXTRAP]))() =
92*7c478bd9Sstevel@tonic-gate {
93*7c478bd9Sstevel@tonic-gate 	0,
94*7c478bd9Sstevel@tonic-gate 	done, 	/* hangup */
95*7c478bd9Sstevel@tonic-gate 	fault,	/* interrupt */
96*7c478bd9Sstevel@tonic-gate 	fault,	/* quit */
97*7c478bd9Sstevel@tonic-gate 	done,	/* illegal instr */
98*7c478bd9Sstevel@tonic-gate 	done,	/* trace trap */
99*7c478bd9Sstevel@tonic-gate 	done,	/* IOT */
100*7c478bd9Sstevel@tonic-gate 	done,	/* EMT */
101*7c478bd9Sstevel@tonic-gate 	done,	/* floating pt. exp */
102*7c478bd9Sstevel@tonic-gate 	0,	/* kill */
103*7c478bd9Sstevel@tonic-gate 	done, 	/* bus error */
104*7c478bd9Sstevel@tonic-gate 	sigsegv,	/* memory faults */
105*7c478bd9Sstevel@tonic-gate 	done, 	/* bad sys call */
106*7c478bd9Sstevel@tonic-gate 	done,	/* bad pipe call */
107*7c478bd9Sstevel@tonic-gate 	done,	/* alarm */
108*7c478bd9Sstevel@tonic-gate 	fault,	/* software termination */
109*7c478bd9Sstevel@tonic-gate 	done,	/* unassigned */
110*7c478bd9Sstevel@tonic-gate 	done,	/* unassigned */
111*7c478bd9Sstevel@tonic-gate 	0,	/* death of child */
112*7c478bd9Sstevel@tonic-gate 	done,	/* power fail */
113*7c478bd9Sstevel@tonic-gate 	0,	/* window size change */
114*7c478bd9Sstevel@tonic-gate 	done,	/* urgent IO condition */
115*7c478bd9Sstevel@tonic-gate 	done,	/* pollable event occured */
116*7c478bd9Sstevel@tonic-gate 	0,	/* uncatchable stop */
117*7c478bd9Sstevel@tonic-gate 	0,	/* foreground stop */
118*7c478bd9Sstevel@tonic-gate 	0,	/* stopped process continued */
119*7c478bd9Sstevel@tonic-gate 	0,	/* background tty read */
120*7c478bd9Sstevel@tonic-gate 	0,	/* background tty write */
121*7c478bd9Sstevel@tonic-gate 	done,	/* virtual timer expired */
122*7c478bd9Sstevel@tonic-gate 	done,	/* profiling timer expired */
123*7c478bd9Sstevel@tonic-gate 	done,	/* exceeded cpu limit */
124*7c478bd9Sstevel@tonic-gate 	done,	/* exceeded file size limit */
125*7c478bd9Sstevel@tonic-gate 	0, 	/* process's lwps are blocked */
126*7c478bd9Sstevel@tonic-gate 	0,	/* special signal used by thread library */
127*7c478bd9Sstevel@tonic-gate 	0, 	/* check point freeze */
128*7c478bd9Sstevel@tonic-gate 	0,	/* check point thaw */
129*7c478bd9Sstevel@tonic-gate };
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate static int
132*7c478bd9Sstevel@tonic-gate ignoring(i)
133*7c478bd9Sstevel@tonic-gate register int i;
134*7c478bd9Sstevel@tonic-gate {
135*7c478bd9Sstevel@tonic-gate 	struct sigaction act;
136*7c478bd9Sstevel@tonic-gate 	if (trapflg[i] & SIGIGN)
137*7c478bd9Sstevel@tonic-gate 		return (1);
138*7c478bd9Sstevel@tonic-gate 	sigaction(i, 0, &act);
139*7c478bd9Sstevel@tonic-gate 	if (act.sa_handler == SIG_IGN) {
140*7c478bd9Sstevel@tonic-gate 		trapflg[i] |= SIGIGN;
141*7c478bd9Sstevel@tonic-gate 		return (1);
142*7c478bd9Sstevel@tonic-gate 	}
143*7c478bd9Sstevel@tonic-gate 	return (0);
144*7c478bd9Sstevel@tonic-gate }
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate static void
147*7c478bd9Sstevel@tonic-gate clrsig(i)
148*7c478bd9Sstevel@tonic-gate int	i;
149*7c478bd9Sstevel@tonic-gate {
150*7c478bd9Sstevel@tonic-gate 	if (trapcom[i] != 0) {
151*7c478bd9Sstevel@tonic-gate 		free(trapcom[i]);
152*7c478bd9Sstevel@tonic-gate 		trapcom[i] = 0;
153*7c478bd9Sstevel@tonic-gate 	}
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	if (trapflg[i] & SIGMOD) {
157*7c478bd9Sstevel@tonic-gate 		/*
158*7c478bd9Sstevel@tonic-gate 		 * If the signal has been set to SIGIGN and we are now
159*7c478bd9Sstevel@tonic-gate 		 * clearing the disposition of the signal (restoring it
160*7c478bd9Sstevel@tonic-gate 		 * back to its default value) then we need to clear this
161*7c478bd9Sstevel@tonic-gate 		 * bit as well
162*7c478bd9Sstevel@tonic-gate 		 *
163*7c478bd9Sstevel@tonic-gate 		 */
164*7c478bd9Sstevel@tonic-gate 		if (trapflg[i] & SIGIGN)
165*7c478bd9Sstevel@tonic-gate 			trapflg[i] &= ~SIGIGN;
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 		trapflg[i] &= ~SIGMOD;
168*7c478bd9Sstevel@tonic-gate 		handle(i, sigval[i]);
169*7c478bd9Sstevel@tonic-gate 	}
170*7c478bd9Sstevel@tonic-gate }
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate void
173*7c478bd9Sstevel@tonic-gate done(sig)
174*7c478bd9Sstevel@tonic-gate {
175*7c478bd9Sstevel@tonic-gate 	register unsigned char	*t;
176*7c478bd9Sstevel@tonic-gate 	int	savxit;
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	if (t = trapcom[0])
179*7c478bd9Sstevel@tonic-gate 	{
180*7c478bd9Sstevel@tonic-gate 		trapcom[0] = 0;
181*7c478bd9Sstevel@tonic-gate 		/* Save exit value so trap handler will not change its val */
182*7c478bd9Sstevel@tonic-gate 		savxit = exitval;
183*7c478bd9Sstevel@tonic-gate 		execexp(t, 0);
184*7c478bd9Sstevel@tonic-gate 		exitval = savxit;		/* Restore exit value */
185*7c478bd9Sstevel@tonic-gate 		free(t);
186*7c478bd9Sstevel@tonic-gate 	}
187*7c478bd9Sstevel@tonic-gate 	else
188*7c478bd9Sstevel@tonic-gate 		chktrap();
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 	rmtemp(0);
191*7c478bd9Sstevel@tonic-gate 	rmfunctmp();
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate #ifdef ACCT
194*7c478bd9Sstevel@tonic-gate 	doacct();
195*7c478bd9Sstevel@tonic-gate #endif
196*7c478bd9Sstevel@tonic-gate 	if (flags & subsh) {
197*7c478bd9Sstevel@tonic-gate 		/* in a subshell, need to wait on foreground job */
198*7c478bd9Sstevel@tonic-gate 		collect_fg_job();
199*7c478bd9Sstevel@tonic-gate 	}
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	(void) endjobs(0);
202*7c478bd9Sstevel@tonic-gate 	if (sig) {
203*7c478bd9Sstevel@tonic-gate 		sigset_t set;
204*7c478bd9Sstevel@tonic-gate 		sigemptyset(&set);
205*7c478bd9Sstevel@tonic-gate 		sigaddset(&set, sig);
206*7c478bd9Sstevel@tonic-gate 		sigprocmask(SIG_UNBLOCK, &set, 0);
207*7c478bd9Sstevel@tonic-gate 		handle(sig, SIG_DFL);
208*7c478bd9Sstevel@tonic-gate 		kill(mypid, sig);
209*7c478bd9Sstevel@tonic-gate 	}
210*7c478bd9Sstevel@tonic-gate 	exit(exitval);
211*7c478bd9Sstevel@tonic-gate }
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate static void
214*7c478bd9Sstevel@tonic-gate fault(sig)
215*7c478bd9Sstevel@tonic-gate register int	sig;
216*7c478bd9Sstevel@tonic-gate {
217*7c478bd9Sstevel@tonic-gate 	register int flag;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	switch (sig) {
220*7c478bd9Sstevel@tonic-gate 		case SIGALRM:
221*7c478bd9Sstevel@tonic-gate 			if (sleeping)
222*7c478bd9Sstevel@tonic-gate 				return;
223*7c478bd9Sstevel@tonic-gate 			break;
224*7c478bd9Sstevel@tonic-gate 	}
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 	if (trapcom[sig])
227*7c478bd9Sstevel@tonic-gate 		flag = TRAPSET;
228*7c478bd9Sstevel@tonic-gate 	else if (flags & subsh)
229*7c478bd9Sstevel@tonic-gate 		done(sig);
230*7c478bd9Sstevel@tonic-gate 	else
231*7c478bd9Sstevel@tonic-gate 		flag = SIGSET;
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 	trapnote |= flag;
234*7c478bd9Sstevel@tonic-gate 	trapflg[sig] |= flag;
235*7c478bd9Sstevel@tonic-gate }
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate int
238*7c478bd9Sstevel@tonic-gate handle(sig, func)
239*7c478bd9Sstevel@tonic-gate 	int sig;
240*7c478bd9Sstevel@tonic-gate 	void (*func)();
241*7c478bd9Sstevel@tonic-gate {
242*7c478bd9Sstevel@tonic-gate 	int	ret;
243*7c478bd9Sstevel@tonic-gate 	struct sigaction act, oact;
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 	if (func == SIG_IGN && (trapflg[sig] & SIGIGN))
246*7c478bd9Sstevel@tonic-gate 		return (0);
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	/*
249*7c478bd9Sstevel@tonic-gate 	 * Ensure that sigaction is only called with valid signal numbers,
250*7c478bd9Sstevel@tonic-gate 	 * we can get random values back for oact.sa_handler if the signal
251*7c478bd9Sstevel@tonic-gate 	 * number is invalid
252*7c478bd9Sstevel@tonic-gate 	 *
253*7c478bd9Sstevel@tonic-gate 	 */
254*7c478bd9Sstevel@tonic-gate 	if (sig > MINTRAP && sig < MAXTRAP) {
255*7c478bd9Sstevel@tonic-gate 		sigemptyset(&act.sa_mask);
256*7c478bd9Sstevel@tonic-gate 		act.sa_flags = (sig == SIGSEGV) ? (SA_ONSTACK | SA_SIGINFO) : 0;
257*7c478bd9Sstevel@tonic-gate 		act.sa_handler = func;
258*7c478bd9Sstevel@tonic-gate 		sigaction(sig, &act, &oact);
259*7c478bd9Sstevel@tonic-gate 	}
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate 	if (func == SIG_IGN)
262*7c478bd9Sstevel@tonic-gate 		trapflg[sig] |= SIGIGN;
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 	/*
265*7c478bd9Sstevel@tonic-gate 	 * Special case for signal zero, we can not obtain the previos
266*7c478bd9Sstevel@tonic-gate 	 * action by calling sigaction, instead we save it in the variable
267*7c478bd9Sstevel@tonic-gate 	 * psig0_func, so we can test it next time through this code
268*7c478bd9Sstevel@tonic-gate 	 *
269*7c478bd9Sstevel@tonic-gate 	 */
270*7c478bd9Sstevel@tonic-gate 	if (sig == 0) {
271*7c478bd9Sstevel@tonic-gate 		ret = (psig0_func != func);
272*7c478bd9Sstevel@tonic-gate 		psig0_func = func;
273*7c478bd9Sstevel@tonic-gate 	} else {
274*7c478bd9Sstevel@tonic-gate 		ret = (func != oact.sa_handler);
275*7c478bd9Sstevel@tonic-gate 	}
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate 	return (ret);
278*7c478bd9Sstevel@tonic-gate }
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate void
281*7c478bd9Sstevel@tonic-gate stdsigs()
282*7c478bd9Sstevel@tonic-gate {
283*7c478bd9Sstevel@tonic-gate 	register int	i;
284*7c478bd9Sstevel@tonic-gate 	stack_t	ss;
285*7c478bd9Sstevel@tonic-gate 	int	err = 0;
286*7c478bd9Sstevel@tonic-gate 	int rtmin = (int)SIGRTMIN;
287*7c478bd9Sstevel@tonic-gate 	int rtmax = (int)SIGRTMAX;
288*7c478bd9Sstevel@tonic-gate 
289*7c478bd9Sstevel@tonic-gate 	ss.ss_size = SIGSTKSZ;
290*7c478bd9Sstevel@tonic-gate 	ss.ss_sp = sigsegv_stack;
291*7c478bd9Sstevel@tonic-gate 	ss.ss_flags = 0;
292*7c478bd9Sstevel@tonic-gate 	errno = 0;
293*7c478bd9Sstevel@tonic-gate 	if (sigaltstack(&ss, (stack_t *)NULL) == -1) {
294*7c478bd9Sstevel@tonic-gate 		err = errno;
295*7c478bd9Sstevel@tonic-gate 		failure("sigaltstack(2) failed with", strerror(err));
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	for (i = 1; i < MAXTRAP; i++) {
299*7c478bd9Sstevel@tonic-gate 		if (i == rtmin) {
300*7c478bd9Sstevel@tonic-gate 			i = rtmax;
301*7c478bd9Sstevel@tonic-gate 			continue;
302*7c478bd9Sstevel@tonic-gate 		}
303*7c478bd9Sstevel@tonic-gate 		if (sigval[i] == 0)
304*7c478bd9Sstevel@tonic-gate 			continue;
305*7c478bd9Sstevel@tonic-gate 		if (i != SIGSEGV && ignoring(i))
306*7c478bd9Sstevel@tonic-gate 			continue;
307*7c478bd9Sstevel@tonic-gate 		handle(i, sigval[i]);
308*7c478bd9Sstevel@tonic-gate 	}
309*7c478bd9Sstevel@tonic-gate 
310*7c478bd9Sstevel@tonic-gate 	/*
311*7c478bd9Sstevel@tonic-gate 	 * handle all the realtime signals
312*7c478bd9Sstevel@tonic-gate 	 *
313*7c478bd9Sstevel@tonic-gate 	 */
314*7c478bd9Sstevel@tonic-gate 	for (i = rtmin; i <= rtmax; i++) {
315*7c478bd9Sstevel@tonic-gate 		handle(i, done);
316*7c478bd9Sstevel@tonic-gate 	}
317*7c478bd9Sstevel@tonic-gate }
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate void
320*7c478bd9Sstevel@tonic-gate oldsigs()
321*7c478bd9Sstevel@tonic-gate {
322*7c478bd9Sstevel@tonic-gate 	register int	i;
323*7c478bd9Sstevel@tonic-gate 	register unsigned char	*t;
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	i = MAXTRAP;
326*7c478bd9Sstevel@tonic-gate 	while (i--)
327*7c478bd9Sstevel@tonic-gate 	{
328*7c478bd9Sstevel@tonic-gate 		t = trapcom[i];
329*7c478bd9Sstevel@tonic-gate 		if (t == 0 || *t)
330*7c478bd9Sstevel@tonic-gate 			clrsig(i);
331*7c478bd9Sstevel@tonic-gate 		trapflg[i] = 0;
332*7c478bd9Sstevel@tonic-gate 	}
333*7c478bd9Sstevel@tonic-gate 	trapnote = 0;
334*7c478bd9Sstevel@tonic-gate }
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate /*
337*7c478bd9Sstevel@tonic-gate  * check for traps
338*7c478bd9Sstevel@tonic-gate  */
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate void
341*7c478bd9Sstevel@tonic-gate chktrap()
342*7c478bd9Sstevel@tonic-gate {
343*7c478bd9Sstevel@tonic-gate 	register int	i = MAXTRAP;
344*7c478bd9Sstevel@tonic-gate 	register unsigned char	*t;
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 	trapnote &= ~TRAPSET;
347*7c478bd9Sstevel@tonic-gate 	while (--i)
348*7c478bd9Sstevel@tonic-gate 	{
349*7c478bd9Sstevel@tonic-gate 		if (trapflg[i] & TRAPSET)
350*7c478bd9Sstevel@tonic-gate 		{
351*7c478bd9Sstevel@tonic-gate 			trapflg[i] &= ~TRAPSET;
352*7c478bd9Sstevel@tonic-gate 			if (t = trapcom[i])
353*7c478bd9Sstevel@tonic-gate 			{
354*7c478bd9Sstevel@tonic-gate 				int	savxit = exitval;
355*7c478bd9Sstevel@tonic-gate 				execexp(t, 0);
356*7c478bd9Sstevel@tonic-gate 				exitval = savxit;
357*7c478bd9Sstevel@tonic-gate 				exitset();
358*7c478bd9Sstevel@tonic-gate 			}
359*7c478bd9Sstevel@tonic-gate 		}
360*7c478bd9Sstevel@tonic-gate 	}
361*7c478bd9Sstevel@tonic-gate }
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate systrap(argc, argv)
364*7c478bd9Sstevel@tonic-gate int argc;
365*7c478bd9Sstevel@tonic-gate char **argv;
366*7c478bd9Sstevel@tonic-gate {
367*7c478bd9Sstevel@tonic-gate 	int sig;
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate 	if (argc == 1) {
370*7c478bd9Sstevel@tonic-gate 		/*
371*7c478bd9Sstevel@tonic-gate 		 * print out the current action associated with each signal
372*7c478bd9Sstevel@tonic-gate 		 * handled by the shell
373*7c478bd9Sstevel@tonic-gate 		 *
374*7c478bd9Sstevel@tonic-gate 		 */
375*7c478bd9Sstevel@tonic-gate 		for (sig = 0; sig < MAXTRAP; sig++) {
376*7c478bd9Sstevel@tonic-gate 			if (trapcom[sig]) {
377*7c478bd9Sstevel@tonic-gate 				prn_buff(sig);
378*7c478bd9Sstevel@tonic-gate 				prs_buff(colon);
379*7c478bd9Sstevel@tonic-gate 				prs_buff(trapcom[sig]);
380*7c478bd9Sstevel@tonic-gate 				prc_buff(NL);
381*7c478bd9Sstevel@tonic-gate 			}
382*7c478bd9Sstevel@tonic-gate 		}
383*7c478bd9Sstevel@tonic-gate 	} else {
384*7c478bd9Sstevel@tonic-gate 		/*
385*7c478bd9Sstevel@tonic-gate 		 * set the action for the list of signals
386*7c478bd9Sstevel@tonic-gate 		 *
387*7c478bd9Sstevel@tonic-gate 		 */
388*7c478bd9Sstevel@tonic-gate 		char *cmd = *argv, *a1 = *(argv+1);
389*7c478bd9Sstevel@tonic-gate 		BOOL noa1;
390*7c478bd9Sstevel@tonic-gate 		noa1 = (str2sig(a1, &sig) == 0);
391*7c478bd9Sstevel@tonic-gate 		if (noa1 == 0)
392*7c478bd9Sstevel@tonic-gate 			++argv;
393*7c478bd9Sstevel@tonic-gate 		while (*++argv) {
394*7c478bd9Sstevel@tonic-gate 			if (str2sig(*argv, &sig) < 0 ||
395*7c478bd9Sstevel@tonic-gate 			    sig >= MAXTRAP || sig < MINTRAP ||
396*7c478bd9Sstevel@tonic-gate 			    sig == SIGSEGV) {
397*7c478bd9Sstevel@tonic-gate 				failure(cmd, badtrap);
398*7c478bd9Sstevel@tonic-gate 			} else if (noa1) {
399*7c478bd9Sstevel@tonic-gate 				/*
400*7c478bd9Sstevel@tonic-gate 				 * no action specifed so reset the siganl
401*7c478bd9Sstevel@tonic-gate 				 * to its default disposition
402*7c478bd9Sstevel@tonic-gate 				 *
403*7c478bd9Sstevel@tonic-gate 				 */
404*7c478bd9Sstevel@tonic-gate 				clrsig(sig);
405*7c478bd9Sstevel@tonic-gate 			} else if (*a1) {
406*7c478bd9Sstevel@tonic-gate 				/*
407*7c478bd9Sstevel@tonic-gate 				 * set the action associated with the signal
408*7c478bd9Sstevel@tonic-gate 				 * to a1
409*7c478bd9Sstevel@tonic-gate 				 *
410*7c478bd9Sstevel@tonic-gate 				 */
411*7c478bd9Sstevel@tonic-gate 				if (trapflg[sig] & SIGMOD || sig == 0 ||
412*7c478bd9Sstevel@tonic-gate 				    !ignoring(sig)) {
413*7c478bd9Sstevel@tonic-gate 					handle(sig, fault);
414*7c478bd9Sstevel@tonic-gate 					trapflg[sig] |= SIGMOD;
415*7c478bd9Sstevel@tonic-gate 					replace(&trapcom[sig], a1);
416*7c478bd9Sstevel@tonic-gate 				}
417*7c478bd9Sstevel@tonic-gate 			} else if (handle(sig, SIG_IGN)) {
418*7c478bd9Sstevel@tonic-gate 				/*
419*7c478bd9Sstevel@tonic-gate 				 * set the action associated with the signal
420*7c478bd9Sstevel@tonic-gate 				 * to SIG_IGN
421*7c478bd9Sstevel@tonic-gate 				 *
422*7c478bd9Sstevel@tonic-gate 				 */
423*7c478bd9Sstevel@tonic-gate 				trapflg[sig] |= SIGMOD;
424*7c478bd9Sstevel@tonic-gate 				replace(&trapcom[sig], a1);
425*7c478bd9Sstevel@tonic-gate 			}
426*7c478bd9Sstevel@tonic-gate 		}
427*7c478bd9Sstevel@tonic-gate 	}
428*7c478bd9Sstevel@tonic-gate }
429*7c478bd9Sstevel@tonic-gate 
430*7c478bd9Sstevel@tonic-gate unsigned int
431*7c478bd9Sstevel@tonic-gate sleep(ticks)
432*7c478bd9Sstevel@tonic-gate unsigned int ticks;
433*7c478bd9Sstevel@tonic-gate {
434*7c478bd9Sstevel@tonic-gate 	sigset_t set, oset;
435*7c478bd9Sstevel@tonic-gate 	struct sigaction act, oact;
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 
438*7c478bd9Sstevel@tonic-gate 	/*
439*7c478bd9Sstevel@tonic-gate 	 * add SIGALRM to mask
440*7c478bd9Sstevel@tonic-gate 	 */
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate 	sigemptyset(&set);
443*7c478bd9Sstevel@tonic-gate 	sigaddset(&set, SIGALRM);
444*7c478bd9Sstevel@tonic-gate 	sigprocmask(SIG_BLOCK, &set, &oset);
445*7c478bd9Sstevel@tonic-gate 
446*7c478bd9Sstevel@tonic-gate 	/*
447*7c478bd9Sstevel@tonic-gate 	 * catch SIGALRM
448*7c478bd9Sstevel@tonic-gate 	 */
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate 	sigemptyset(&act.sa_mask);
451*7c478bd9Sstevel@tonic-gate 	act.sa_flags = 0;
452*7c478bd9Sstevel@tonic-gate 	act.sa_handler = fault;
453*7c478bd9Sstevel@tonic-gate 	sigaction(SIGALRM, &act, &oact);
454*7c478bd9Sstevel@tonic-gate 
455*7c478bd9Sstevel@tonic-gate 	/*
456*7c478bd9Sstevel@tonic-gate 	 * start alarm and wait for signal
457*7c478bd9Sstevel@tonic-gate 	 */
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate 	alarm(ticks);
460*7c478bd9Sstevel@tonic-gate 	sleeping = 1;
461*7c478bd9Sstevel@tonic-gate 	sigsuspend(&oset);
462*7c478bd9Sstevel@tonic-gate 	sleeping = 0;
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate 	/*
465*7c478bd9Sstevel@tonic-gate 	 * reset alarm, catcher and mask
466*7c478bd9Sstevel@tonic-gate 	 */
467*7c478bd9Sstevel@tonic-gate 
468*7c478bd9Sstevel@tonic-gate 	alarm(0);
469*7c478bd9Sstevel@tonic-gate 	sigaction(SIGALRM, &oact, NULL);
470*7c478bd9Sstevel@tonic-gate 	sigprocmask(SIG_SETMASK, &oset, 0);
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate }
473*7c478bd9Sstevel@tonic-gate 
474*7c478bd9Sstevel@tonic-gate void
475*7c478bd9Sstevel@tonic-gate sigsegv(int sig, siginfo_t *sip, ucontext_t *uap)
476*7c478bd9Sstevel@tonic-gate {
477*7c478bd9Sstevel@tonic-gate 	if (sip == (siginfo_t *)NULL) {
478*7c478bd9Sstevel@tonic-gate 		/*
479*7c478bd9Sstevel@tonic-gate 		 * This should never happen, but if it does this is all we
480*7c478bd9Sstevel@tonic-gate 		 * can do. It can only happen if sigaction(2) for SIGSEGV
481*7c478bd9Sstevel@tonic-gate 		 * has been called without SA_SIGINFO being set.
482*7c478bd9Sstevel@tonic-gate 		 *
483*7c478bd9Sstevel@tonic-gate 		 */
484*7c478bd9Sstevel@tonic-gate 
485*7c478bd9Sstevel@tonic-gate 		exit(ERROR);
486*7c478bd9Sstevel@tonic-gate 	} else {
487*7c478bd9Sstevel@tonic-gate 		if (sip->si_code <= 0) {
488*7c478bd9Sstevel@tonic-gate 			/*
489*7c478bd9Sstevel@tonic-gate 			 * If we are here then SIGSEGV must have been sent to
490*7c478bd9Sstevel@tonic-gate 			 * us from a user process NOT as a result of an
491*7c478bd9Sstevel@tonic-gate 			 * internal error within the shell eg
492*7c478bd9Sstevel@tonic-gate 			 * kill -SEGV $$
493*7c478bd9Sstevel@tonic-gate 			 * will bring us here. So do the normal thing.
494*7c478bd9Sstevel@tonic-gate 			 *
495*7c478bd9Sstevel@tonic-gate 			 */
496*7c478bd9Sstevel@tonic-gate 			fault(sig);
497*7c478bd9Sstevel@tonic-gate 		} else {
498*7c478bd9Sstevel@tonic-gate 			/*
499*7c478bd9Sstevel@tonic-gate 			 * If we are here then there must have been an internal
500*7c478bd9Sstevel@tonic-gate 			 * error within the shell to generate SIGSEGV eg
501*7c478bd9Sstevel@tonic-gate 			 * the stack is full and we cannot call any more
502*7c478bd9Sstevel@tonic-gate 			 * functions (Remeber this signal handler is running
503*7c478bd9Sstevel@tonic-gate 			 * on an alternate stack). So we just exit cleanly
504*7c478bd9Sstevel@tonic-gate 			 * with an error status (no core file).
505*7c478bd9Sstevel@tonic-gate 			 */
506*7c478bd9Sstevel@tonic-gate 			exit(ERROR);
507*7c478bd9Sstevel@tonic-gate 		}
508*7c478bd9Sstevel@tonic-gate 	}
509*7c478bd9Sstevel@tonic-gate }
510