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