1*17510Sedward #ifndef lint 2*17510Sedward static char *sccsid = "@(#)err.c 4.2 (Berkeley) 12/13/84"; 3*17510Sedward #endif 41291Sbill 51291Sbill #include "sh.h" 61291Sbill #include <sys/ioctl.h> 71291Sbill 81291Sbill /* 91291Sbill * C Shell 101291Sbill */ 111291Sbill 121291Sbill bool errspl; /* Argument to error was spliced by seterr2 */ 131291Sbill char one[2] = { '1', 0 }; 141291Sbill char *onev[2] = { one, NOSTR }; 151291Sbill /* 161291Sbill * Print error string s with optional argument arg. 171291Sbill * This routine always resets or exits. The flag haderr 181291Sbill * is set so the routine who catches the unwind can propogate 191291Sbill * it if they want. 201291Sbill * 211291Sbill * Note that any open files at the point of error will eventually 221291Sbill * be closed in the routine process in sh.c which is the only 231291Sbill * place error unwinds are ever caught. 241291Sbill */ 25*17510Sedward /*VARARGS1*/ 261291Sbill error(s, arg) 271291Sbill char *s; 281291Sbill { 291291Sbill register char **v; 301291Sbill register char *ep; 311291Sbill 321291Sbill /* 331291Sbill * Must flush before we print as we wish output before the error 341291Sbill * to go on (some form of) standard output, while output after 351291Sbill * goes on (some form of) diagnostic output. 361291Sbill * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG. 371291Sbill * See flush in sh.print.c. 381291Sbill */ 391291Sbill flush(); 401291Sbill haderr = 1; /* Now to diagnostic output */ 411291Sbill timflg = 0; /* This isn't otherwise reset */ 421291Sbill if (v = pargv) 431291Sbill pargv = 0, blkfree(v); 441291Sbill if (v = gargv) 451291Sbill gargv = 0, blkfree(v); 461291Sbill 471291Sbill /* 481291Sbill * A zero arguments causes no printing, else print 491291Sbill * an error diagnostic here. 501291Sbill */ 511291Sbill if (s) 521291Sbill printf(s, arg), printf(".\n"); 531291Sbill 541291Sbill didfds = 0; /* Forget about 0,1,2 */ 551291Sbill if ((ep = err) && errspl) { 561291Sbill errspl = 0; 571291Sbill xfree(ep); 581291Sbill } 591291Sbill errspl = 0; 601291Sbill 611291Sbill /* 621291Sbill * Reset the state of the input. 631291Sbill * This buffered seek to end of file will also 641291Sbill * clear the while/foreach stack. 651291Sbill */ 661291Sbill btoeof(); 671291Sbill 681291Sbill /* 691291Sbill * Go away if -e or we are a child shell 701291Sbill */ 711291Sbill if (exiterr || child) 721291Sbill exit(1); 731291Sbill 741291Sbill setq("status", onev, &shvhed); 751291Sbill if (tpgrp > 0) 76*17510Sedward (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp); 771291Sbill reset(); /* Unwind */ 781291Sbill } 791291Sbill 801291Sbill /* 811291Sbill * Perror is the shells version of perror which should otherwise 821291Sbill * never be called. 831291Sbill */ 841291Sbill Perror(s) 851291Sbill char *s; 861291Sbill { 871291Sbill 881291Sbill /* 891291Sbill * Perror uses unit 2, thus if we didn't set up the fd's 901291Sbill * we must set up unit 2 now else the diagnostic will disappear 911291Sbill */ 921291Sbill if (!didfds) { 931291Sbill register int oerrno = errno; 941291Sbill 95*17510Sedward (void) dcopy(SHDIAG, 2); 961291Sbill errno = oerrno; 971291Sbill } 981291Sbill perror(s); 991291Sbill error(NOSTR); /* To exit or unwind */ 1001291Sbill } 1011291Sbill 1021291Sbill bferr(cp) 1031291Sbill char *cp; 1041291Sbill { 1051291Sbill 1061291Sbill flush(); 1071291Sbill haderr = 1; 1081291Sbill printf("%s: ", bname); 1091291Sbill error(cp); 1101291Sbill } 1111291Sbill 1121291Sbill /* 1131291Sbill * The parser and scanner set up errors for later by calling seterr, 1141291Sbill * which sets the variable err as a side effect; later to be tested, 1151291Sbill * e.g. in process. 1161291Sbill */ 1171291Sbill seterr(s) 1181291Sbill char *s; 1191291Sbill { 1201291Sbill 1211291Sbill if (err == 0) 1221291Sbill err = s, errspl = 0; 1231291Sbill } 1241291Sbill 1251291Sbill /* Set err to a splice of cp and dp, to be freed later in error() */ 1261291Sbill seterr2(cp, dp) 1271291Sbill char *cp, *dp; 1281291Sbill { 1291291Sbill 1301291Sbill if (err) 1311291Sbill return; 1321291Sbill err = strspl(cp, dp); 1331291Sbill errspl++; 1341291Sbill } 1351291Sbill 1361291Sbill /* Set err to a splice of cp with a string form of character d */ 1371291Sbill seterrc(cp, d) 1381291Sbill char *cp, d; 1391291Sbill { 1401291Sbill char chbuf[2]; 1411291Sbill 1421291Sbill chbuf[0] = d; 1431291Sbill chbuf[1] = 0; 1441291Sbill seterr2(cp, chbuf); 1451291Sbill } 146