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