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