xref: /titanic_52/usr/src/cmd/csh/sh.err.c (revision 6c02b4a4b46fecc2fa6bf1ab6b5e3255ad1d0767)
17c478bd9Sstevel@tonic-gate /*
2*6c02b4a4Smuffin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include "sh.h"
187c478bd9Sstevel@tonic-gate #include <locale.h>
197c478bd9Sstevel@tonic-gate #include <dirent.h>
20*6c02b4a4Smuffin #include <string.h>
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate  * #include <sys/ioctl.h>
237c478bd9Sstevel@tonic-gate  * #include <stdlib.h>
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * C Shell
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate bool	errspl;			/* Argument to error was spliced by seterr2 */
327c478bd9Sstevel@tonic-gate tchar one[2] = { '1', 0 };
337c478bd9Sstevel@tonic-gate tchar *onev[2] = { one, NOSTR };
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  *    contains DIR * for last opendir_(), its left open if an error
367c478bd9Sstevel@tonic-gate  *    longjmp (reset) occurs before it gets closed via closedir.
377c478bd9Sstevel@tonic-gate  *    if its not null in the error handler, then closedir it.
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate DIR *Dirp = NULL;
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * Print error string s with optional argument arg.
437c478bd9Sstevel@tonic-gate  * This routine always resets or exits.  The flag haderr
447c478bd9Sstevel@tonic-gate  * is set so the routine who catches the unwind can propogate
457c478bd9Sstevel@tonic-gate  * it if they want.
467c478bd9Sstevel@tonic-gate  *
477c478bd9Sstevel@tonic-gate  * Note that any open files at the point of error will eventually
487c478bd9Sstevel@tonic-gate  * be closed in the routine process in sh.c which is the only
497c478bd9Sstevel@tonic-gate  * place error unwinds are ever caught.
507c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate /*VARARGS1*/
52*6c02b4a4Smuffin void
537c478bd9Sstevel@tonic-gate error(s, a1, a2)
547c478bd9Sstevel@tonic-gate      char	*s;
557c478bd9Sstevel@tonic-gate {
56*6c02b4a4Smuffin 	tchar **v;
57*6c02b4a4Smuffin 	char *ep;
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate 	/*
607c478bd9Sstevel@tonic-gate 	 * Must flush before we print as we wish output before the error
617c478bd9Sstevel@tonic-gate 	 * to go on (some form of) standard output, while output after
627c478bd9Sstevel@tonic-gate 	 * goes on (some form of) diagnostic output.
637c478bd9Sstevel@tonic-gate 	 * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG.
647c478bd9Sstevel@tonic-gate 	 * See flush in sh.print.c.
657c478bd9Sstevel@tonic-gate 	 */
667c478bd9Sstevel@tonic-gate 	flush();
677c478bd9Sstevel@tonic-gate 	haderr = 1;		/* Now to diagnostic output */
687c478bd9Sstevel@tonic-gate 	timflg = 0;		/* This isn't otherwise reset */
697c478bd9Sstevel@tonic-gate 	if (v = pargv)
707c478bd9Sstevel@tonic-gate 		pargv = 0, blkfree(v);
717c478bd9Sstevel@tonic-gate 	if (v = gargv)
727c478bd9Sstevel@tonic-gate 		gargv = 0, blkfree(v);
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 	/*
757c478bd9Sstevel@tonic-gate 	 * A zero arguments causes no printing, else print
767c478bd9Sstevel@tonic-gate 	 * an error diagnostic here.
777c478bd9Sstevel@tonic-gate 	 */
787c478bd9Sstevel@tonic-gate 	if (s) {
797c478bd9Sstevel@tonic-gate 			printf(s, a1, a2), printf("\n");
807c478bd9Sstevel@tonic-gate 	}
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 	didfds = 0;		/* Forget about 0,1,2 */
847c478bd9Sstevel@tonic-gate 	if ((ep = err) && errspl) {
857c478bd9Sstevel@tonic-gate 		errspl = 0;
867c478bd9Sstevel@tonic-gate 		xfree(ep);
877c478bd9Sstevel@tonic-gate 	}
887c478bd9Sstevel@tonic-gate 	errspl = 0;
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	if ( Dirp ){
917c478bd9Sstevel@tonic-gate 		closedir(Dirp);
927c478bd9Sstevel@tonic-gate 		Dirp = NULL;
937c478bd9Sstevel@tonic-gate 	}
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	/*
967c478bd9Sstevel@tonic-gate 	 * Go away if -e or we are a child shell
977c478bd9Sstevel@tonic-gate 	 */
987c478bd9Sstevel@tonic-gate 	if (exiterr || child) {
997c478bd9Sstevel@tonic-gate 		exit(1);
1007c478bd9Sstevel@tonic-gate 	}
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	/*
1037c478bd9Sstevel@tonic-gate 	 * Reset the state of the input.
1047c478bd9Sstevel@tonic-gate 	 * This buffered seek to end of file will also
1057c478bd9Sstevel@tonic-gate 	 * clear the while/foreach stack.
1067c478bd9Sstevel@tonic-gate 	 */
1077c478bd9Sstevel@tonic-gate 	btoeof();
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 	setq(S_status, onev, &shvhed);
1107c478bd9Sstevel@tonic-gate 	if (tpgrp > 0)
1117c478bd9Sstevel@tonic-gate 		(void) ioctl(FSHTTY, TIOCSPGRP,  (char *)&tpgrp);
1127c478bd9Sstevel@tonic-gate 	reset();		/* Unwind */
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate /*
1167c478bd9Sstevel@tonic-gate  * Perror is the shells version of perror which should otherwise
1177c478bd9Sstevel@tonic-gate  * never be called.
1187c478bd9Sstevel@tonic-gate  */
119*6c02b4a4Smuffin void
120*6c02b4a4Smuffin Perror(tchar *s)
1217c478bd9Sstevel@tonic-gate {
1227c478bd9Sstevel@tonic-gate 	char	chbuf[BUFSIZ];
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 	/*
1257c478bd9Sstevel@tonic-gate 	 * Perror uses unit 2, thus if we didn't set up the fd's
1267c478bd9Sstevel@tonic-gate 	 * we must set up unit 2 now else the diagnostic will disappear
1277c478bd9Sstevel@tonic-gate 	 */
1287c478bd9Sstevel@tonic-gate 	if (!didfds) {
129*6c02b4a4Smuffin 		int oerrno = errno;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 		(void) dcopy(SHDIAG, 2);
1327c478bd9Sstevel@tonic-gate 		errno = oerrno;
1337c478bd9Sstevel@tonic-gate 	}
1347c478bd9Sstevel@tonic-gate 	tstostr(chbuf, s);
1357c478bd9Sstevel@tonic-gate 	perror(chbuf);
1367c478bd9Sstevel@tonic-gate 	error(NULL);		/* To exit or unwind */
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate 
139*6c02b4a4Smuffin void
140*6c02b4a4Smuffin bferr(char *cp)
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	flush();
1447c478bd9Sstevel@tonic-gate 	haderr = 1;
1457c478bd9Sstevel@tonic-gate 	if( bname) printf("%t: ", bname);
1467c478bd9Sstevel@tonic-gate 	error("%s", gettext(cp));
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate  * The parser and scanner set up errors for later by calling seterr,
1517c478bd9Sstevel@tonic-gate  * which sets the variable err as a side effect; later to be tested,
1527c478bd9Sstevel@tonic-gate  * e.g. in process.
1537c478bd9Sstevel@tonic-gate  */
154*6c02b4a4Smuffin void
155*6c02b4a4Smuffin seterr(char *s)
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	if (err == 0)
1597c478bd9Sstevel@tonic-gate 		err = s, errspl = 0;
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate /* Set err to a splice of cp and dp, to be freed later in error() */
163*6c02b4a4Smuffin void
164*6c02b4a4Smuffin seterr2(tchar *cp, char *dp)
1657c478bd9Sstevel@tonic-gate {
1667c478bd9Sstevel@tonic-gate 	char	chbuf[BUFSIZ];
1677c478bd9Sstevel@tonic-gate 	char	*gdp;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	if (err)
1707c478bd9Sstevel@tonic-gate 		return;
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	/* Concatinate cp and dp in the allocated space. */
1737c478bd9Sstevel@tonic-gate 	tstostr(chbuf, cp);
1747c478bd9Sstevel@tonic-gate 	gdp = gettext(dp);
1757c478bd9Sstevel@tonic-gate 	err = (char *)xalloc(strlen(chbuf)+strlen(gdp)+1);
1767c478bd9Sstevel@tonic-gate 	strcpy(err, chbuf);
1777c478bd9Sstevel@tonic-gate 	strcat(err, gdp);
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	errspl++;/* Remember to xfree(err). */
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate /* Set err to a splice of cp with a string form of character d */
183*6c02b4a4Smuffin void
184*6c02b4a4Smuffin seterrc(char *cp, tchar d)
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate 	char	chbuf[MB_LEN_MAX+1];
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	/* don't overwrite an existing error message */
1897c478bd9Sstevel@tonic-gate 	if (err)
1907c478bd9Sstevel@tonic-gate 		return;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate #ifdef MBCHAR
1937c478bd9Sstevel@tonic-gate 	{
1947c478bd9Sstevel@tonic-gate 	wchar_t	wcd=(wchar_t)(d&TRIM);
1957c478bd9Sstevel@tonic-gate 	int	i;
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 	i = wctomb(chbuf, wcd); /* chbuf holds d in multibyte representation. */
1987c478bd9Sstevel@tonic-gate 	chbuf[(i>0)?i:0] = (char) 0;
1997c478bd9Sstevel@tonic-gate 	}
2007c478bd9Sstevel@tonic-gate #else
2017c478bd9Sstevel@tonic-gate 	chbuf[0]=(char)(d&TRIM); chbuf[1]=(char)0;
2027c478bd9Sstevel@tonic-gate #endif
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	/* Concatinate cp and d in the allocated space. */
2067c478bd9Sstevel@tonic-gate 	err = (char *)xalloc(strlen(cp)+strlen(chbuf)+1);
2077c478bd9Sstevel@tonic-gate 	strcpy(err, cp);
2087c478bd9Sstevel@tonic-gate 	strcat(err, chbuf);
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	errspl++; /* Remember to xfree(err). */
2117c478bd9Sstevel@tonic-gate }
212