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