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