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