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