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
fault(sig)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
stdsigs()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 */
ignsig(n)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
getsig(n)157 void getsig(n)
158 register int n;
159 {
160 if(trapflg[n]&SIGMOD || ignsig(n)==0)
161 signal(n,fault);
162 }
163
oldsigs()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
clrsig(n)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
chktrap()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