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