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