xref: /illumos-gate/usr/src/cmd/csh/sh.err.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * Copyright 2005 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 #include <string.h>
21 /*
22  * #include <sys/ioctl.h>
23  * #include <stdlib.h>
24  */
25 #include "sh.tconst.h"
26 /*
27  * C Shell
28  */
29 
30 
31 bool	errspl;			/* Argument to error was spliced by seterr2 */
32 tchar one[2] = { '1', 0 };
33 tchar *onev[2] = { one, NOSTR };
34 /*
35  *    contains DIR * for last opendir_(), its left open if an error
36  *    longjmp (reset) occurs before it gets closed via closedir.
37  *    if its not null in the error handler, then closedir it.
38  */
39 DIR *Dirp = NULL;
40 
41 /*
42  * Print error string s with optional argument arg.
43  * This routine always resets or exits.  The flag haderr
44  * is set so the routine who catches the unwind can propogate
45  * it if they want.
46  *
47  * Note that any open files at the point of error will eventually
48  * be closed in the routine process in sh.c which is the only
49  * place error unwinds are ever caught.
50  */
51 /*VARARGS1*/
52 void
53 error(s, a1, a2)
54      char	*s;
55 {
56 	tchar **v;
57 	char *ep;
58 
59 	/*
60 	 * Must flush before we print as we wish output before the error
61 	 * to go on (some form of) standard output, while output after
62 	 * goes on (some form of) diagnostic output.
63 	 * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG.
64 	 * See flush in sh.print.c.
65 	 */
66 	flush();
67 	haderr = 1;		/* Now to diagnostic output */
68 	timflg = 0;		/* This isn't otherwise reset */
69 	if (v = pargv)
70 		pargv = 0, blkfree(v);
71 	if (v = gargv)
72 		gargv = 0, blkfree(v);
73 
74 	/*
75 	 * A zero arguments causes no printing, else print
76 	 * an error diagnostic here.
77 	 */
78 	if (s) {
79 			printf(s, a1, a2), printf("\n");
80 	}
81 
82 
83 	didfds = 0;		/* Forget about 0,1,2 */
84 	if ((ep = err) && errspl) {
85 		errspl = 0;
86 		xfree(ep);
87 	}
88 	errspl = 0;
89 
90 	if ( Dirp ){
91 		closedir(Dirp);
92 		Dirp = NULL;
93 	}
94 
95 	/*
96 	 * Go away if -e or we are a child shell
97 	 */
98 	if (exiterr || child) {
99 		exit(1);
100 	}
101 
102 	/*
103 	 * Reset the state of the input.
104 	 * This buffered seek to end of file will also
105 	 * clear the while/foreach stack.
106 	 */
107 	btoeof();
108 
109 	setq(S_status, onev, &shvhed);
110 	if (tpgrp > 0)
111 		(void) ioctl(FSHTTY, TIOCSPGRP,  (char *)&tpgrp);
112 	reset();		/* Unwind */
113 }
114 
115 /*
116  * Perror is the shells version of perror which should otherwise
117  * never be called.
118  */
119 void
120 Perror(tchar *s)
121 {
122 	char	chbuf[BUFSIZ];
123 
124 	/*
125 	 * Perror uses unit 2, thus if we didn't set up the fd's
126 	 * we must set up unit 2 now else the diagnostic will disappear
127 	 */
128 	if (!didfds) {
129 		int oerrno = errno;
130 
131 		(void) dcopy(SHDIAG, 2);
132 		errno = oerrno;
133 	}
134 	tstostr(chbuf, s);
135 	perror(chbuf);
136 	error(NULL);		/* To exit or unwind */
137 }
138 
139 void
140 bferr(char *cp)
141 {
142 
143 	flush();
144 	haderr = 1;
145 	if( bname) printf("%t: ", bname);
146 	error("%s", gettext(cp));
147 }
148 
149 /*
150  * The parser and scanner set up errors for later by calling seterr,
151  * which sets the variable err as a side effect; later to be tested,
152  * e.g. in process.
153  */
154 void
155 seterr(char *s)
156 {
157 
158 	if (err == 0)
159 		err = s, errspl = 0;
160 }
161 
162 /* Set err to a splice of cp and dp, to be freed later in error() */
163 void
164 seterr2(tchar *cp, char *dp)
165 {
166 	char	chbuf[BUFSIZ];
167 	char	*gdp;
168 
169 	if (err)
170 		return;
171 
172 	/* Concatinate cp and dp in the allocated space. */
173 	tstostr(chbuf, cp);
174 	gdp = gettext(dp);
175 	err = (char *)xalloc(strlen(chbuf)+strlen(gdp)+1);
176 	strcpy(err, chbuf);
177 	strcat(err, gdp);
178 
179 	errspl++;/* Remember to xfree(err). */
180 }
181 
182 /* Set err to a splice of cp with a string form of character d */
183 void
184 seterrc(char *cp, 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