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