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 /* @(#)error.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 "io.h" 26 #include "brkincr.h" 27 #include "jobs.h" 28 #include "sym.h" 29 30 /* These routines are defined by this module */ 31 void exitsh(); 32 void done(); 33 void failed(); 34 void rmtemp(); 35 36 /* These routines are used by this module but defined elsewhere */ 37 extern void arg_clear(); 38 extern void chktrap(); 39 extern void free(); 40 extern void hist_flush(); 41 extern char *movstr(); 42 extern void name_unscope(); 43 extern void p_flush(); 44 extern void p_prp(); 45 extern void p_setout(); 46 extern void p_str(); 47 extern void restore(); 48 extern void rm_files(); 49 extern void setcooked(); 50 #ifdef VFORK 51 extern void vfork_restore(); 52 #endif /* VFORK */ 53 54 /* ======== error handling ======== */ 55 56 /* Find out if it is time to go away. 57 * `trapnote' is set to SIGSET when fault is seen and 58 * no trap has been set. 59 */ 60 61 /* 62 * This routine is called when fatal errors are encountered 63 * A message is printed out and the shell tries to exit 64 */ 65 66 void failed(s1,s2) 67 register char *s1,*s2; 68 { 69 p_setout(stderr); 70 p_prp(s1,s2?':':NL); 71 if(s2) 72 { 73 putc(SP,output); 74 p_str(s2,NL); 75 } 76 exitsh(ERROR); 77 } 78 79 /* Arrive here from `FATAL' errors 80 * a) exit command, 81 * b) default trap, 82 * c) fault with no trap set. 83 * 84 * Action is to return to command level or exit. 85 */ 86 87 void exitsh(xno) 88 int xno; 89 { 90 register unsigned state=(states&~(ERRFLG|MONITOR)); 91 exitval=xno; 92 if(state&BUILTIN) 93 longjmp(*freturn,1); 94 state |= is_option(ERRFLG|MONITOR); 95 if((state&(ERRFLG|FORKED|TTYFLG)) != TTYFLG) 96 { 97 states = state; 98 done(0); 99 } 100 else 101 { 102 if((state&FUNCTION)==0) 103 { 104 p_flush(); 105 /* flush out input buffer */ 106 setbuf(input,input->_base); 107 name_unscope(); 108 arg_clear(); 109 restore(0); 110 } 111 #ifdef VFORK 112 vfork_restore(); 113 #endif /* VFORK */ 114 execbrk = breakcnt = 0; 115 aliflg = 0; 116 exec_flag = 0; 117 hist_flush(); 118 #ifdef JOBS 119 state &= ~(FUNCTION|FIXFLG|NONSTOP|READC|RWAIT|PROMPT|READPR|MONITOR|BUILTIN|VFORKED); 120 state |= is_option(INTFLG|READPR|MONITOR); 121 jobstat.j_flag = 0; 122 #else 123 state &= ~(FUNCTION|FIXFLG|RWAIT|PROMPT|READPR|BUILTIN); 124 state |= is_option(INTFLG|READPR); 125 #endif /* JOBS */ 126 states = state; 127 longjmp(*freturn,1); 128 } 129 } 130 131 /* 132 * This is the exit routine for the shell 133 */ 134 135 void done(sig) 136 register int sig; 137 { 138 register char *t; 139 register int savxit = exitval; 140 if(t=trapcom[0]) 141 { 142 trapcom[0]=0; /*should free but not long */ 143 execexp(t,(FILE*)0); 144 } 145 else 146 { 147 /* avoid recursive call for set -e */ 148 states &= ~ERRFLG; 149 chktrap(); 150 } 151 rmtemp((IOPTR)0); 152 #ifdef ACCT 153 doacct(); 154 #endif /* ACCT */ 155 #if VSH || ESH 156 if(is_option(EMACS|EDITVI|GMACS) && standin->fstak==0) 157 setcooked(fileno(input)); 158 #endif 159 if(states&RM_TMP) 160 /* clean up all temp files */ 161 rm_files(tmpout); 162 p_flush(); 163 #ifdef JOBS 164 if(sig==SIGHUP || (is_option(INTFLG)&&(getppid()==1))) 165 kill_all(); 166 #endif /* JOBS */ 167 if(sig) 168 { 169 /* generate fault termination code */ 170 signal(sig,SIG_DFL); 171 #ifdef BSD_4_2 172 sigrelse(sig); 173 #endif /* BSD_4_2 */ 174 kill(getpid(),sig); 175 pause(); 176 } 177 exit(savxit); 178 } 179 180 /* 181 * remove temporary files 182 */ 183 184 void rmtemp(base) 185 IOPTR base; 186 { 187 register IOPTR iop = iotemp; 188 while(iop>base) 189 { 190 unlink(iop->ioname); 191 free(iop->iolink); 192 iop=iop->iolst; 193 } 194 iotemp = iop; 195 } 196