1 #ifndef lint 2 static char *sccsid = "@(#)err.c 4.2 (Berkeley) 12/13/84"; 3 #endif 4 5 #include "sh.h" 6 #include <sys/ioctl.h> 7 8 /* 9 * C Shell 10 */ 11 12 bool errspl; /* Argument to error was spliced by seterr2 */ 13 char one[2] = { '1', 0 }; 14 char *onev[2] = { one, NOSTR }; 15 /* 16 * Print error string s with optional argument arg. 17 * This routine always resets or exits. The flag haderr 18 * is set so the routine who catches the unwind can propogate 19 * it if they want. 20 * 21 * Note that any open files at the point of error will eventually 22 * be closed in the routine process in sh.c which is the only 23 * place error unwinds are ever caught. 24 */ 25 /*VARARGS1*/ 26 error(s, arg) 27 char *s; 28 { 29 register char **v; 30 register char *ep; 31 32 /* 33 * Must flush before we print as we wish output before the error 34 * to go on (some form of) standard output, while output after 35 * goes on (some form of) diagnostic output. 36 * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG. 37 * See flush in sh.print.c. 38 */ 39 flush(); 40 haderr = 1; /* Now to diagnostic output */ 41 timflg = 0; /* This isn't otherwise reset */ 42 if (v = pargv) 43 pargv = 0, blkfree(v); 44 if (v = gargv) 45 gargv = 0, blkfree(v); 46 47 /* 48 * A zero arguments causes no printing, else print 49 * an error diagnostic here. 50 */ 51 if (s) 52 printf(s, arg), printf(".\n"); 53 54 didfds = 0; /* Forget about 0,1,2 */ 55 if ((ep = err) && errspl) { 56 errspl = 0; 57 xfree(ep); 58 } 59 errspl = 0; 60 61 /* 62 * Reset the state of the input. 63 * This buffered seek to end of file will also 64 * clear the while/foreach stack. 65 */ 66 btoeof(); 67 68 /* 69 * Go away if -e or we are a child shell 70 */ 71 if (exiterr || child) 72 exit(1); 73 74 setq("status", onev, &shvhed); 75 if (tpgrp > 0) 76 (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp); 77 reset(); /* Unwind */ 78 } 79 80 /* 81 * Perror is the shells version of perror which should otherwise 82 * never be called. 83 */ 84 Perror(s) 85 char *s; 86 { 87 88 /* 89 * Perror uses unit 2, thus if we didn't set up the fd's 90 * we must set up unit 2 now else the diagnostic will disappear 91 */ 92 if (!didfds) { 93 register int oerrno = errno; 94 95 (void) dcopy(SHDIAG, 2); 96 errno = oerrno; 97 } 98 perror(s); 99 error(NOSTR); /* To exit or unwind */ 100 } 101 102 bferr(cp) 103 char *cp; 104 { 105 106 flush(); 107 haderr = 1; 108 printf("%s: ", bname); 109 error(cp); 110 } 111 112 /* 113 * The parser and scanner set up errors for later by calling seterr, 114 * which sets the variable err as a side effect; later to be tested, 115 * e.g. in process. 116 */ 117 seterr(s) 118 char *s; 119 { 120 121 if (err == 0) 122 err = s, errspl = 0; 123 } 124 125 /* Set err to a splice of cp and dp, to be freed later in error() */ 126 seterr2(cp, dp) 127 char *cp, *dp; 128 { 129 130 if (err) 131 return; 132 err = strspl(cp, dp); 133 errspl++; 134 } 135 136 /* Set err to a splice of cp with a string form of character d */ 137 seterrc(cp, d) 138 char *cp, d; 139 { 140 char chbuf[2]; 141 142 chbuf[0] = d; 143 chbuf[1] = 0; 144 seterr2(cp, chbuf); 145 } 146