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