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