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