1 /* 2 * Copyright 1997 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 /* 21 * #include <sys/ioctl.h> 22 * #include <stdlib.h> 23 */ 24 #include "sh.tconst.h" 25 /* 26 * C Shell 27 */ 28 29 30 bool errspl; /* Argument to error was spliced by seterr2 */ 31 tchar one[2] = { '1', 0 }; 32 tchar *onev[2] = { one, NOSTR }; 33 /* 34 * contains DIR * for last opendir_(), its left open if an error 35 * longjmp (reset) occurs before it gets closed via closedir. 36 * if its not null in the error handler, then closedir it. 37 */ 38 DIR *Dirp = NULL; 39 40 /* 41 * Print error string s with optional argument arg. 42 * This routine always resets or exits. The flag haderr 43 * is set so the routine who catches the unwind can propogate 44 * it if they want. 45 * 46 * Note that any open files at the point of error will eventually 47 * be closed in the routine process in sh.c which is the only 48 * place error unwinds are ever caught. 49 */ 50 /*VARARGS1*/ 51 error(s, a1, a2) 52 char *s; 53 { 54 register tchar **v; 55 register char *ep; 56 57 /* 58 * Must flush before we print as we wish output before the error 59 * to go on (some form of) standard output, while output after 60 * goes on (some form of) diagnostic output. 61 * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG. 62 * See flush in sh.print.c. 63 */ 64 flush(); 65 haderr = 1; /* Now to diagnostic output */ 66 timflg = 0; /* This isn't otherwise reset */ 67 if (v = pargv) 68 pargv = 0, blkfree(v); 69 if (v = gargv) 70 gargv = 0, blkfree(v); 71 72 /* 73 * A zero arguments causes no printing, else print 74 * an error diagnostic here. 75 */ 76 if (s) { 77 printf(s, a1, a2), printf("\n"); 78 } 79 80 81 didfds = 0; /* Forget about 0,1,2 */ 82 if ((ep = err) && errspl) { 83 errspl = 0; 84 xfree(ep); 85 } 86 errspl = 0; 87 88 if ( Dirp ){ 89 closedir(Dirp); 90 Dirp = NULL; 91 } 92 93 /* 94 * Go away if -e or we are a child shell 95 */ 96 if (exiterr || child) { 97 exit(1); 98 } 99 100 /* 101 * Reset the state of the input. 102 * This buffered seek to end of file will also 103 * clear the while/foreach stack. 104 */ 105 btoeof(); 106 107 setq(S_status, onev, &shvhed); 108 if (tpgrp > 0) 109 (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp); 110 reset(); /* Unwind */ 111 } 112 113 /* 114 * Perror is the shells version of perror which should otherwise 115 * never be called. 116 */ 117 Perror(s) 118 tchar *s; 119 { 120 char chbuf[BUFSIZ]; 121 122 /* 123 * Perror uses unit 2, thus if we didn't set up the fd's 124 * we must set up unit 2 now else the diagnostic will disappear 125 */ 126 if (!didfds) { 127 register int oerrno = errno; 128 129 (void) dcopy(SHDIAG, 2); 130 errno = oerrno; 131 } 132 tstostr(chbuf, s); 133 perror(chbuf); 134 error(NULL); /* To exit or unwind */ 135 } 136 137 bferr(cp) 138 char *cp; 139 { 140 141 flush(); 142 haderr = 1; 143 if( bname) printf("%t: ", bname); 144 error("%s", gettext(cp)); 145 } 146 147 /* 148 * The parser and scanner set up errors for later by calling seterr, 149 * which sets the variable err as a side effect; later to be tested, 150 * e.g. in process. 151 */ 152 seterr(s) 153 char *s; 154 { 155 156 if (err == 0) 157 err = s, errspl = 0; 158 } 159 160 /* Set err to a splice of cp and dp, to be freed later in error() */ 161 seterr2(cp, dp) 162 tchar *cp; 163 char *dp; 164 { 165 char chbuf[BUFSIZ]; 166 char *gdp; 167 168 if (err) 169 return; 170 171 /* Concatinate cp and dp in the allocated space. */ 172 tstostr(chbuf, cp); 173 gdp = gettext(dp); 174 err = (char *)xalloc(strlen(chbuf)+strlen(gdp)+1); 175 strcpy(err, chbuf); 176 strcat(err, gdp); 177 178 errspl++;/* Remember to xfree(err). */ 179 } 180 181 /* Set err to a splice of cp with a string form of character d */ 182 seterrc(cp, d) 183 char *cp; 184 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