OpenSolaris_b135/cmd/csh/sh.err.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved  	*/

/*
 * Copyright (c) 1980 Regents of the University of California.
 * All rights reserved.  The Berkeley Software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include "sh.h"
#include <locale.h>
#include <dirent.h>
#include <string.h>
/*
 * #include <sys/ioctl.h>
 * #include <stdlib.h>
 */
#include "sh.tconst.h"
/*
 * C Shell
 */


bool	errspl;			/* Argument to error was spliced by seterr2 */
tchar one[2] = { '1', 0 };
tchar *onev[2] = { one, NOSTR };
/* 
 *    contains DIR * for last opendir_(), its left open if an error
 *    longjmp (reset) occurs before it gets closed via closedir.
 *    if its not null in the error handler, then closedir it.
 */
DIR *Dirp = NULL;

/*
 * Print error string s with optional argument arg.
 * This routine always resets or exits.  The flag haderr
 * is set so the routine who catches the unwind can propogate
 * it if they want.
 *
 * Note that any open files at the point of error will eventually
 * be closed in the routine process in sh.c which is the only
 * place error unwinds are ever caught.
 */
/*VARARGS1*/
void
error(s, a1, a2)
     char	*s;
{
	tchar **v;
	char *ep;

	/*
	 * Must flush before we print as we wish output before the error
	 * to go on (some form of) standard output, while output after
	 * goes on (some form of) diagnostic output.
	 * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG.
	 * See flush in sh.print.c.
	 */
	flush();
	haderr = 1;		/* Now to diagnostic output */
	timflg = 0;		/* This isn't otherwise reset */
	if (v = pargv)
		pargv = 0, blkfree(v);
	if (v = gargv)
		gargv = 0, blkfree(v);

	/*
	 * A zero arguments causes no printing, else print
	 * an error diagnostic here.
	 */
	if (s) {
			printf(s, a1, a2), printf("\n"); 
	}
			

	didfds = 0;		/* Forget about 0,1,2 */
	if ((ep = err) && errspl) {
		errspl = 0;
		xfree(ep);
	}
	errspl = 0;

	if ( Dirp ){
		closedir(Dirp);
		Dirp = NULL;
	}

	/*
	 * Go away if -e or we are a child shell
	 */
	if (exiterr || child) {
		exit(1);
	}

	/*
	 * Reset the state of the input.
	 * This buffered seek to end of file will also
	 * clear the while/foreach stack.
	 */
	btoeof();

	setq(S_status, onev, &shvhed);
	if (tpgrp > 0)
		(void) ioctl(FSHTTY, TIOCSPGRP,  (char *)&tpgrp);
	reset();		/* Unwind */
}

/*
 * Perror is the shells version of perror which should otherwise
 * never be called.
 */
void
Perror(tchar *s)
{
	char	chbuf[BUFSIZ];

	/*
	 * Perror uses unit 2, thus if we didn't set up the fd's
	 * we must set up unit 2 now else the diagnostic will disappear
	 */
	if (!didfds) {
		int oerrno = errno;

		(void) dcopy(SHDIAG, 2);
		errno = oerrno;
	}
	tstostr(chbuf, s);
	perror(chbuf);
	error(NULL);		/* To exit or unwind */
}

void
bferr(char *cp)
{

	flush();
	haderr = 1;
	if( bname) printf("%t: ", bname);
	error("%s", gettext(cp));
}

/*
 * The parser and scanner set up errors for later by calling seterr,
 * which sets the variable err as a side effect; later to be tested,
 * e.g. in process.
 */
void
seterr(char *s)
{

	if (err == 0)
		err = s, errspl = 0;
}

/* Set err to a splice of cp and dp, to be freed later in error() */
void
seterr2(tchar *cp, char *dp)
{
	char	chbuf[BUFSIZ];
	char	*gdp;

	if (err)
		return;

	/* Concatinate cp and dp in the allocated space. */
	tstostr(chbuf, cp);
	gdp = gettext(dp);
	err = (char *)xalloc(strlen(chbuf)+strlen(gdp)+1);
	strcpy(err, chbuf);
	strcat(err, gdp);

	errspl++;/* Remember to xfree(err). */
}

/* Set err to a splice of cp with a string form of character d */
void
seterrc(char *cp, tchar d)
{
	char	chbuf[MB_LEN_MAX+1]; 

	/* don't overwrite an existing error message */
	if (err)
		return;

#ifdef MBCHAR
	{
	wchar_t	wcd=(wchar_t)(d&TRIM);
	int	i;

	i = wctomb(chbuf, wcd); /* chbuf holds d in multibyte representation. */
	chbuf[(i>0)?i:0] = (char) 0;
	}
#else
	chbuf[0]=(char)(d&TRIM); chbuf[1]=(char)0;
#endif


	/* Concatinate cp and d in the allocated space. */
	err = (char *)xalloc(strlen(cp)+strlen(chbuf)+1);
	strcpy(err, cp);
	strcat(err, chbuf);

	errspl++; /* Remember to xfree(err). */
}