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