xref: /titanic_44/usr/src/cmd/csh/sh.err.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 /*
2  * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7 /*	  All Rights Reserved  	*/
8 
9 /*
10  * Copyright (c) 1980 Regents of the University of California.
11  * All rights reserved.  The Berkeley Software License Agreement
12  * specifies the terms and conditions for redistribution.
13  */
14 
15 #pragma ident	"%Z%%M%	%I%	%E% SMI"
16 
17 #include "sh.h"
18 #include <locale.h>
19 #include <dirent.h>
20 /*
21  * #include <sys/ioctl.h>
22  * #include <stdlib.h>
23  */
24 #include "sh.tconst.h"
25 /*
26  * C Shell
27  */
28 
29 
30 bool	errspl;			/* Argument to error was spliced by seterr2 */
31 tchar one[2] = { '1', 0 };
32 tchar *onev[2] = { one, NOSTR };
33 /*
34  *    contains DIR * for last opendir_(), its left open if an error
35  *    longjmp (reset) occurs before it gets closed via closedir.
36  *    if its not null in the error handler, then closedir it.
37  */
38 DIR *Dirp = NULL;
39 
40 /*
41  * Print error string s with optional argument arg.
42  * This routine always resets or exits.  The flag haderr
43  * is set so the routine who catches the unwind can propogate
44  * it if they want.
45  *
46  * Note that any open files at the point of error will eventually
47  * be closed in the routine process in sh.c which is the only
48  * place error unwinds are ever caught.
49  */
50 /*VARARGS1*/
51 error(s, a1, a2)
52      char	*s;
53 {
54 	register	tchar **v;
55 	register	char *ep;
56 
57 	/*
58 	 * Must flush before we print as we wish output before the error
59 	 * to go on (some form of) standard output, while output after
60 	 * goes on (some form of) diagnostic output.
61 	 * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG.
62 	 * See flush in sh.print.c.
63 	 */
64 	flush();
65 	haderr = 1;		/* Now to diagnostic output */
66 	timflg = 0;		/* This isn't otherwise reset */
67 	if (v = pargv)
68 		pargv = 0, blkfree(v);
69 	if (v = gargv)
70 		gargv = 0, blkfree(v);
71 
72 	/*
73 	 * A zero arguments causes no printing, else print
74 	 * an error diagnostic here.
75 	 */
76 	if (s) {
77 			printf(s, a1, a2), printf("\n");
78 	}
79 
80 
81 	didfds = 0;		/* Forget about 0,1,2 */
82 	if ((ep = err) && errspl) {
83 		errspl = 0;
84 		xfree(ep);
85 	}
86 	errspl = 0;
87 
88 	if ( Dirp ){
89 		closedir(Dirp);
90 		Dirp = NULL;
91 	}
92 
93 	/*
94 	 * Go away if -e or we are a child shell
95 	 */
96 	if (exiterr || child) {
97 		exit(1);
98 	}
99 
100 	/*
101 	 * Reset the state of the input.
102 	 * This buffered seek to end of file will also
103 	 * clear the while/foreach stack.
104 	 */
105 	btoeof();
106 
107 	setq(S_status, onev, &shvhed);
108 	if (tpgrp > 0)
109 		(void) ioctl(FSHTTY, TIOCSPGRP,  (char *)&tpgrp);
110 	reset();		/* Unwind */
111 }
112 
113 /*
114  * Perror is the shells version of perror which should otherwise
115  * never be called.
116  */
117 Perror(s)
118      tchar *s;
119 {
120 	char	chbuf[BUFSIZ];
121 
122 	/*
123 	 * Perror uses unit 2, thus if we didn't set up the fd's
124 	 * we must set up unit 2 now else the diagnostic will disappear
125 	 */
126 	if (!didfds) {
127 		register int oerrno = errno;
128 
129 		(void) dcopy(SHDIAG, 2);
130 		errno = oerrno;
131 	}
132 	tstostr(chbuf, s);
133 	perror(chbuf);
134 	error(NULL);		/* To exit or unwind */
135 }
136 
137 bferr(cp)
138      char *cp;
139 {
140 
141 	flush();
142 	haderr = 1;
143 	if( bname) printf("%t: ", bname);
144 	error("%s", gettext(cp));
145 }
146 
147 /*
148  * The parser and scanner set up errors for later by calling seterr,
149  * which sets the variable err as a side effect; later to be tested,
150  * e.g. in process.
151  */
152 seterr(s)
153      char *s;
154 {
155 
156 	if (err == 0)
157 		err = s, errspl = 0;
158 }
159 
160 /* Set err to a splice of cp and dp, to be freed later in error() */
161 seterr2(cp, dp)
162      tchar *cp;
163      char *dp;
164 {
165 	char	chbuf[BUFSIZ];
166 	char	*gdp;
167 
168 	if (err)
169 		return;
170 
171 	/* Concatinate cp and dp in the allocated space. */
172 	tstostr(chbuf, cp);
173 	gdp = gettext(dp);
174 	err = (char *)xalloc(strlen(chbuf)+strlen(gdp)+1);
175 	strcpy(err, chbuf);
176 	strcat(err, gdp);
177 
178 	errspl++;/* Remember to xfree(err). */
179 }
180 
181 /* Set err to a splice of cp with a string form of character d */
182 seterrc(cp, d)
183      char	*cp;
184      tchar	 d;
185 {
186 	char	chbuf[MB_LEN_MAX+1];
187 
188 	/* don't overwrite an existing error message */
189 	if (err)
190 		return;
191 
192 #ifdef MBCHAR
193 	{
194 	wchar_t	wcd=(wchar_t)(d&TRIM);
195 	int	i;
196 
197 	i = wctomb(chbuf, wcd); /* chbuf holds d in multibyte representation. */
198 	chbuf[(i>0)?i:0] = (char) 0;
199 	}
200 #else
201 	chbuf[0]=(char)(d&TRIM); chbuf[1]=(char)0;
202 #endif
203 
204 
205 	/* Concatinate cp and d in the allocated space. */
206 	err = (char *)xalloc(strlen(cp)+strlen(chbuf)+1);
207 	strcpy(err, cp);
208 	strcat(err, chbuf);
209 
210 	errspl++; /* Remember to xfree(err). */
211 }
212