xref: /onnv-gate/usr/src/cmd/csh/sh.err.c (revision 356:44e9075e1c86)
10Sstevel@tonic-gate /*
2*356Smuffin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
70Sstevel@tonic-gate /*	  All Rights Reserved  	*/
80Sstevel@tonic-gate 
90Sstevel@tonic-gate /*
100Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
110Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
120Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
130Sstevel@tonic-gate  */
140Sstevel@tonic-gate 
150Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
160Sstevel@tonic-gate 
170Sstevel@tonic-gate #include "sh.h"
180Sstevel@tonic-gate #include <locale.h>
190Sstevel@tonic-gate #include <dirent.h>
20*356Smuffin #include <string.h>
210Sstevel@tonic-gate /*
220Sstevel@tonic-gate  * #include <sys/ioctl.h>
230Sstevel@tonic-gate  * #include <stdlib.h>
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate #include "sh.tconst.h"
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * C Shell
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
310Sstevel@tonic-gate bool	errspl;			/* Argument to error was spliced by seterr2 */
320Sstevel@tonic-gate tchar one[2] = { '1', 0 };
330Sstevel@tonic-gate tchar *onev[2] = { one, NOSTR };
340Sstevel@tonic-gate /*
350Sstevel@tonic-gate  *    contains DIR * for last opendir_(), its left open if an error
360Sstevel@tonic-gate  *    longjmp (reset) occurs before it gets closed via closedir.
370Sstevel@tonic-gate  *    if its not null in the error handler, then closedir it.
380Sstevel@tonic-gate  */
390Sstevel@tonic-gate DIR *Dirp = NULL;
400Sstevel@tonic-gate 
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate  * Print error string s with optional argument arg.
430Sstevel@tonic-gate  * This routine always resets or exits.  The flag haderr
440Sstevel@tonic-gate  * is set so the routine who catches the unwind can propogate
450Sstevel@tonic-gate  * it if they want.
460Sstevel@tonic-gate  *
470Sstevel@tonic-gate  * Note that any open files at the point of error will eventually
480Sstevel@tonic-gate  * be closed in the routine process in sh.c which is the only
490Sstevel@tonic-gate  * place error unwinds are ever caught.
500Sstevel@tonic-gate  */
510Sstevel@tonic-gate /*VARARGS1*/
52*356Smuffin void
error(s,a1,a2)530Sstevel@tonic-gate error(s, a1, a2)
540Sstevel@tonic-gate      char	*s;
550Sstevel@tonic-gate {
56*356Smuffin 	tchar **v;
57*356Smuffin 	char *ep;
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	/*
600Sstevel@tonic-gate 	 * Must flush before we print as we wish output before the error
610Sstevel@tonic-gate 	 * to go on (some form of) standard output, while output after
620Sstevel@tonic-gate 	 * goes on (some form of) diagnostic output.
630Sstevel@tonic-gate 	 * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG.
640Sstevel@tonic-gate 	 * See flush in sh.print.c.
650Sstevel@tonic-gate 	 */
660Sstevel@tonic-gate 	flush();
670Sstevel@tonic-gate 	haderr = 1;		/* Now to diagnostic output */
680Sstevel@tonic-gate 	timflg = 0;		/* This isn't otherwise reset */
690Sstevel@tonic-gate 	if (v = pargv)
700Sstevel@tonic-gate 		pargv = 0, blkfree(v);
710Sstevel@tonic-gate 	if (v = gargv)
720Sstevel@tonic-gate 		gargv = 0, blkfree(v);
730Sstevel@tonic-gate 
740Sstevel@tonic-gate 	/*
750Sstevel@tonic-gate 	 * A zero arguments causes no printing, else print
760Sstevel@tonic-gate 	 * an error diagnostic here.
770Sstevel@tonic-gate 	 */
780Sstevel@tonic-gate 	if (s) {
790Sstevel@tonic-gate 			printf(s, a1, a2), printf("\n");
800Sstevel@tonic-gate 	}
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 	didfds = 0;		/* Forget about 0,1,2 */
840Sstevel@tonic-gate 	if ((ep = err) && errspl) {
850Sstevel@tonic-gate 		errspl = 0;
860Sstevel@tonic-gate 		xfree(ep);
870Sstevel@tonic-gate 	}
880Sstevel@tonic-gate 	errspl = 0;
890Sstevel@tonic-gate 
900Sstevel@tonic-gate 	if ( Dirp ){
910Sstevel@tonic-gate 		closedir(Dirp);
920Sstevel@tonic-gate 		Dirp = NULL;
930Sstevel@tonic-gate 	}
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	/*
960Sstevel@tonic-gate 	 * Go away if -e or we are a child shell
970Sstevel@tonic-gate 	 */
980Sstevel@tonic-gate 	if (exiterr || child) {
990Sstevel@tonic-gate 		exit(1);
1000Sstevel@tonic-gate 	}
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	/*
1030Sstevel@tonic-gate 	 * Reset the state of the input.
1040Sstevel@tonic-gate 	 * This buffered seek to end of file will also
1050Sstevel@tonic-gate 	 * clear the while/foreach stack.
1060Sstevel@tonic-gate 	 */
1070Sstevel@tonic-gate 	btoeof();
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	setq(S_status, onev, &shvhed);
1100Sstevel@tonic-gate 	if (tpgrp > 0)
1110Sstevel@tonic-gate 		(void) ioctl(FSHTTY, TIOCSPGRP,  (char *)&tpgrp);
1120Sstevel@tonic-gate 	reset();		/* Unwind */
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate  * Perror is the shells version of perror which should otherwise
1170Sstevel@tonic-gate  * never be called.
1180Sstevel@tonic-gate  */
119*356Smuffin void
Perror(tchar * s)120*356Smuffin Perror(tchar *s)
1210Sstevel@tonic-gate {
1220Sstevel@tonic-gate 	char	chbuf[BUFSIZ];
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 	/*
1250Sstevel@tonic-gate 	 * Perror uses unit 2, thus if we didn't set up the fd's
1260Sstevel@tonic-gate 	 * we must set up unit 2 now else the diagnostic will disappear
1270Sstevel@tonic-gate 	 */
1280Sstevel@tonic-gate 	if (!didfds) {
129*356Smuffin 		int oerrno = errno;
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 		(void) dcopy(SHDIAG, 2);
1320Sstevel@tonic-gate 		errno = oerrno;
1330Sstevel@tonic-gate 	}
1340Sstevel@tonic-gate 	tstostr(chbuf, s);
1350Sstevel@tonic-gate 	perror(chbuf);
1360Sstevel@tonic-gate 	error(NULL);		/* To exit or unwind */
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate 
139*356Smuffin void
bferr(char * cp)140*356Smuffin bferr(char *cp)
1410Sstevel@tonic-gate {
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	flush();
1440Sstevel@tonic-gate 	haderr = 1;
1450Sstevel@tonic-gate 	if( bname) printf("%t: ", bname);
1460Sstevel@tonic-gate 	error("%s", gettext(cp));
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate /*
1500Sstevel@tonic-gate  * The parser and scanner set up errors for later by calling seterr,
1510Sstevel@tonic-gate  * which sets the variable err as a side effect; later to be tested,
1520Sstevel@tonic-gate  * e.g. in process.
1530Sstevel@tonic-gate  */
154*356Smuffin void
seterr(char * s)155*356Smuffin seterr(char *s)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	if (err == 0)
1590Sstevel@tonic-gate 		err = s, errspl = 0;
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate /* Set err to a splice of cp and dp, to be freed later in error() */
163*356Smuffin void
seterr2(tchar * cp,char * dp)164*356Smuffin seterr2(tchar *cp, char *dp)
1650Sstevel@tonic-gate {
1660Sstevel@tonic-gate 	char	chbuf[BUFSIZ];
1670Sstevel@tonic-gate 	char	*gdp;
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	if (err)
1700Sstevel@tonic-gate 		return;
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	/* Concatinate cp and dp in the allocated space. */
1730Sstevel@tonic-gate 	tstostr(chbuf, cp);
1740Sstevel@tonic-gate 	gdp = gettext(dp);
1750Sstevel@tonic-gate 	err = (char *)xalloc(strlen(chbuf)+strlen(gdp)+1);
1760Sstevel@tonic-gate 	strcpy(err, chbuf);
1770Sstevel@tonic-gate 	strcat(err, gdp);
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	errspl++;/* Remember to xfree(err). */
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate /* Set err to a splice of cp with a string form of character d */
183*356Smuffin void
seterrc(char * cp,tchar d)184*356Smuffin seterrc(char *cp, tchar d)
1850Sstevel@tonic-gate {
1860Sstevel@tonic-gate 	char	chbuf[MB_LEN_MAX+1];
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	/* don't overwrite an existing error message */
1890Sstevel@tonic-gate 	if (err)
1900Sstevel@tonic-gate 		return;
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate #ifdef MBCHAR
1930Sstevel@tonic-gate 	{
1940Sstevel@tonic-gate 	wchar_t	wcd=(wchar_t)(d&TRIM);
1950Sstevel@tonic-gate 	int	i;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	i = wctomb(chbuf, wcd); /* chbuf holds d in multibyte representation. */
1980Sstevel@tonic-gate 	chbuf[(i>0)?i:0] = (char) 0;
1990Sstevel@tonic-gate 	}
2000Sstevel@tonic-gate #else
2010Sstevel@tonic-gate 	chbuf[0]=(char)(d&TRIM); chbuf[1]=(char)0;
2020Sstevel@tonic-gate #endif
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	/* Concatinate cp and d in the allocated space. */
2060Sstevel@tonic-gate 	err = (char *)xalloc(strlen(cp)+strlen(chbuf)+1);
2070Sstevel@tonic-gate 	strcpy(err, cp);
2080Sstevel@tonic-gate 	strcat(err, chbuf);
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	errspl++; /* Remember to xfree(err). */
2110Sstevel@tonic-gate }
212