xref: /csrg-svn/local/toolchest/ksh/sh/fault.c (revision 35142)
1*35142Smarc /*
2*35142Smarc 
3*35142Smarc  *      Copyright (c) 1984, 1985, 1986 AT&T
4*35142Smarc  *      All Rights Reserved
5*35142Smarc 
6*35142Smarc  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35142Smarc  *      CODE OF AT&T.
8*35142Smarc  *      The copyright notice above does not
9*35142Smarc  *      evidence any actual or intended
10*35142Smarc  *      publication of such source code.
11*35142Smarc 
12*35142Smarc  */
13*35142Smarc /* @(#)fault.c	1.1 */
14*35142Smarc /*
15*35142Smarc  * UNIX shell
16*35142Smarc  *
17*35142Smarc  * S. R. Bourne
18*35142Smarc  * Rewritten by David Korn
19*35142Smarc  * AT&T Bell Laboratories
20*35142Smarc  *
21*35142Smarc  */
22*35142Smarc 
23*35142Smarc #include	"flags.h"
24*35142Smarc #include	"defs.h"
25*35142Smarc #include	"brkincr.h"
26*35142Smarc #include	"stak.h"
27*35142Smarc #include	"sym.h"
28*35142Smarc #include	"jobs.h"
29*35142Smarc #include	"timeout.h"
30*35142Smarc 
31*35142Smarc 
32*35142Smarc /* until the bug is fixed */
33*35142Smarc #define VOID	int
34*35142Smarc 
35*35142Smarc VOID	fault();
36*35142Smarc void	chktrap();
37*35142Smarc void	stdsig();
38*35142Smarc int	ignsig();
39*35142Smarc void	getsig();
40*35142Smarc void	oldsig();
41*35142Smarc void	clrsig();
42*35142Smarc 
43*35142Smarc extern VOID	done();
44*35142Smarc extern void	exitsh();
45*35142Smarc extern void	failed();
46*35142Smarc extern void	free();
47*35142Smarc extern void	p_str();
48*35142Smarc extern void	p_flush();
49*35142Smarc extern void	setbrk();
50*35142Smarc 
51*35142Smarc #ifdef VFORK
52*35142Smarc char trapflg[MAXTRAP+1];
53*35142Smarc #else
54*35142Smarc static char trapflg[MAXTRAP+1];
55*35142Smarc #endif	/* VFORK */
56*35142Smarc 
57*35142Smarc /* ========	fault handling routines	   ======== */
58*35142Smarc 
59*35142Smarc 
fault(sig)60*35142Smarc VOID	fault(sig)
61*35142Smarc register int 	sig;
62*35142Smarc {
63*35142Smarc 	register int 	flag;
64*35142Smarc #ifdef JOBS
65*35142Smarc #ifndef BSD
66*35142Smarc 	if(sig==SIGCLD)
67*35142Smarc 	{
68*35142Smarc 		trapnote |= SIGJOBS;
69*35142Smarc 		return;
70*35142Smarc 	}
71*35142Smarc #endif	/* BSD */
72*35142Smarc #endif	/* JOBS */
73*35142Smarc 	signal(sig, fault);
74*35142Smarc 	if(sig==SIGSEGV)
75*35142Smarc 		setbrk(BRKINCR);
76*35142Smarc 	if(sig==SIGALRM)
77*35142Smarc 	{
78*35142Smarc 		if((states&WAITING) && timeout>0)
79*35142Smarc 		{
80*35142Smarc 			if(states&RWAIT)
81*35142Smarc 			{
82*35142Smarc 				/* force exit */
83*35142Smarc 					states |= FORKED;
84*35142Smarc 					error(timed_out);
85*35142Smarc 			}
86*35142Smarc 			else
87*35142Smarc 			{
88*35142Smarc 				states |= RWAIT;
89*35142Smarc 				alarm(TGRACE);
90*35142Smarc 				p_str(time_warn,NL);
91*35142Smarc 				p_flush();
92*35142Smarc 			}
93*35142Smarc 		}
94*35142Smarc 	}
95*35142Smarc #ifdef JOBS
96*35142Smarc #ifdef BSD
97*35142Smarc 	else if(sig==SIGCHLD || sig==SIGTSTP || sig==SIGTTIN || sig==SIGTTOU)
98*35142Smarc 		trapnote |= SIGJOBS;
99*35142Smarc #endif	/* BSD */
100*35142Smarc #endif	/* JOBS */
101*35142Smarc 	else
102*35142Smarc 	{
103*35142Smarc 		flag = (trapcom[sig] ? TRAPSET : SIGSET);
104*35142Smarc 		trapnote |= flag;
105*35142Smarc 		trapflg[sig] |= flag;
106*35142Smarc 		if(sig <= SIGQUIT)
107*35142Smarc 			trapnote |= SIGSLOW;
108*35142Smarc 	}
109*35142Smarc #ifdef JOBS
110*35142Smarc #ifdef BSD
111*35142Smarc 	/* This is needed because broken reads automatically restart */
112*35142Smarc 	if(states&READC)
113*35142Smarc 		interrupt();
114*35142Smarc #endif	/* BSD */
115*35142Smarc #endif	/* JOBS */
116*35142Smarc }
117*35142Smarc 
stdsigs()118*35142Smarc void stdsigs()
119*35142Smarc {
120*35142Smarc 	register int i;
121*35142Smarc 	register int n;
122*35142Smarc 	register SYSPTR	syscan = signal_names;
123*35142Smarc 	while(*syscan->sysnam)
124*35142Smarc 	{
125*35142Smarc 		n = syscan->sysval;
126*35142Smarc 		i = n&((1<<SIGBITS)-1);
127*35142Smarc 		n >>= SIGBITS;
128*35142Smarc 		trapflg[--i] = n;
129*35142Smarc 		if((n&(SIGIGNORE|SIGNOSET))==0 && ignsig(i)==0)
130*35142Smarc 			signal(i,(n&SIGCAUGHT?fault:done));
131*35142Smarc 		else if(i==SIGQUIT)
132*35142Smarc 			ignsig(SIGQUIT);
133*35142Smarc 		syscan++;
134*35142Smarc 	}
135*35142Smarc 	syscan = sig_messages;
136*35142Smarc 	while(n=syscan->sysval)
137*35142Smarc 	{
138*35142Smarc 		if(*syscan->sysnam)
139*35142Smarc 			sysmsg[n-1] = syscan->sysnam;
140*35142Smarc 		syscan++;
141*35142Smarc 	}
142*35142Smarc }
143*35142Smarc 
144*35142Smarc /*
145*35142Smarc  * set signal n to ignore
146*35142Smarc  * returns 1 if signal was already ignored, 0 otherwise
147*35142Smarc  */
ignsig(n)148*35142Smarc int	ignsig(n)
149*35142Smarc register int n;
150*35142Smarc {
151*35142Smarc 	register int 	s;
152*35142Smarc 	if((s=(signal(n,SIG_IGN)==SIG_IGN)) == 0)
153*35142Smarc 		trapflg[n] |= SIGMOD;
154*35142Smarc 	return(s);
155*35142Smarc }
156*35142Smarc 
getsig(n)157*35142Smarc void	getsig(n)
158*35142Smarc register int n;
159*35142Smarc {
160*35142Smarc 	if(trapflg[n]&SIGMOD || ignsig(n)==0)
161*35142Smarc 		signal(n,fault);
162*35142Smarc }
163*35142Smarc 
oldsigs()164*35142Smarc void	oldsigs()
165*35142Smarc {
166*35142Smarc 	register int 	i;
167*35142Smarc 	register char *t;
168*35142Smarc 	i=MAXTRAP+1;
169*35142Smarc 	while(i--)
170*35142Smarc 	{
171*35142Smarc 		t=trapcom[i];
172*35142Smarc 		if(t==0 || *t)
173*35142Smarc 		{
174*35142Smarc #ifdef VFORK
175*35142Smarc 			/* don't free the trap string */
176*35142Smarc 			if(states&VFORKED);
177*35142Smarc 				trapcom[i] = 0;
178*35142Smarc #endif /* VFORK */
179*35142Smarc 			 clrsig(i);
180*35142Smarc 		}
181*35142Smarc 		trapflg[i]=0;
182*35142Smarc 	}
183*35142Smarc 	trapnote=0;
184*35142Smarc }
185*35142Smarc 
clrsig(n)186*35142Smarc void	clrsig(n)
187*35142Smarc register int 	n;
188*35142Smarc {
189*35142Smarc 	if(trapcom[n])
190*35142Smarc 	{
191*35142Smarc 		free(trapcom[n]);
192*35142Smarc 		trapcom[n]=0;
193*35142Smarc 	}
194*35142Smarc 	if(trapflg[n]&SIGMOD)
195*35142Smarc 	{
196*35142Smarc 		if(trapflg[n]&SIGCAUGHT)
197*35142Smarc 			signal(n, fault);
198*35142Smarc 		else if(trapflg[n]&SIGIGNORE)
199*35142Smarc 			 signal(n, SIG_DFL);
200*35142Smarc 		else
201*35142Smarc 			signal(n, done);
202*35142Smarc 		trapflg[n] &= ~SIGMOD;
203*35142Smarc 	}
204*35142Smarc }
205*35142Smarc 
206*35142Smarc 
207*35142Smarc /*
208*35142Smarc  * check for traps
209*35142Smarc  */
210*35142Smarc 
chktrap()211*35142Smarc void	chktrap()
212*35142Smarc {
213*35142Smarc 	register int 	i=MAXTRAP+1;
214*35142Smarc 	register char *t;
215*35142Smarc 	trapnote &= ~(TRAPSET|SIGSLOW);
216*35142Smarc 	if(states&ERRFLG)
217*35142Smarc 	{
218*35142Smarc 		if(is_option(ONEFLG))
219*35142Smarc 			exitsh(exitval);
220*35142Smarc 		else if(exitval)
221*35142Smarc 		{
222*35142Smarc 			if(trapcom[MAXTRAP])
223*35142Smarc 				trapflg[MAXTRAP] = TRAPSET;
224*35142Smarc 			if(is_option(ERRFLG))
225*35142Smarc 				exitsh(exitval);
226*35142Smarc 		}
227*35142Smarc 	}
228*35142Smarc 	while(--i)
229*35142Smarc 	{
230*35142Smarc 		if(trapflg[i]&TRAPSET)
231*35142Smarc 		{
232*35142Smarc 			trapflg[i] &= ~TRAPSET;
233*35142Smarc 			if(t=trapcom[i])
234*35142Smarc 			{
235*35142Smarc 				int savxit=exitval;
236*35142Smarc 				execexp(t,(FILE*)0);
237*35142Smarc 				exitval=savxit;
238*35142Smarc 				exitset();
239*35142Smarc 			}
240*35142Smarc 		}
241*35142Smarc 	}
242*35142Smarc }
243