xref: /csrg-svn/bin/csh/err.c (revision 17510)
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