err.c revision 1.5 1 /*-
2 * Copyright (c) 1980, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 /*static char sccsid[] = "from: @(#)err.c 8.1 (Berkeley) 5/31/93";*/
36 static char *rcsid = "$Id: err.c,v 1.5 1994/09/21 00:10:47 mycroft Exp $";
37 #endif /* not lint */
38
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #if __STDC__
43 # include <stdarg.h>
44 #else
45 # include <varargs.h>
46 #endif
47
48 #include "csh.h"
49 #include "extern.h"
50
51 char *seterr = NULL; /* Holds last error if there was one */
52
53 #define ERR_FLAGS 0xf0000000
54 #define ERR_NAME 0x10000000
55 #define ERR_SILENT 0x20000000
56 #define ERR_OLD 0x40000000
57
58 static char *errorlist[] =
59 {
60 #define ERR_SYNTAX 0
61 "Syntax Error",
62 #define ERR_NOTALLOWED 1
63 "%s is not allowed",
64 #define ERR_WTOOLONG 2
65 "Word too long",
66 #define ERR_LTOOLONG 3
67 "$< line too long",
68 #define ERR_DOLZERO 4
69 "No file for $0",
70 #define ERR_DOLQUEST 5
71 "$? not allowed here",
72 #define ERR_INCBR 6
73 "Incomplete [] modifier",
74 #define ERR_EXPORD 7
75 "$ expansion must end before ]",
76 #define ERR_BADMOD 8
77 "Bad : modifier in $ (%c)",
78 #define ERR_SUBSCRIPT 9
79 "Subscript error",
80 #define ERR_BADNUM 10
81 "Badly formed number",
82 #define ERR_NOMORE 11
83 "No more words",
84 #define ERR_FILENAME 12
85 "Missing file name",
86 #define ERR_GLOB 13
87 "Internal glob error",
88 #define ERR_COMMAND 14
89 "Command not found",
90 #define ERR_TOOFEW 15
91 "Too few arguments",
92 #define ERR_TOOMANY 16
93 "Too many arguments",
94 #define ERR_DANGER 17
95 "Too dangerous to alias that",
96 #define ERR_EMPTYIF 18
97 "Empty if",
98 #define ERR_IMPRTHEN 19
99 "Improper then",
100 #define ERR_NOPAREN 20
101 "Words not parenthesized",
102 #define ERR_NOTFOUND 21
103 "%s not found",
104 #define ERR_MASK 22
105 "Improper mask",
106 #define ERR_LIMIT 23
107 "No such limit",
108 #define ERR_TOOLARGE 24
109 "Argument too large",
110 #define ERR_SCALEF 25
111 "Improper or unknown scale factor",
112 #define ERR_UNDVAR 26
113 "Undefined variable",
114 #define ERR_DEEP 27
115 "Directory stack not that deep",
116 #define ERR_BADSIG 28
117 "Bad signal number",
118 #define ERR_UNKSIG 29
119 "Unknown signal; kill -l lists signals",
120 #define ERR_VARBEGIN 30
121 "Variable name must begin with a letter",
122 #define ERR_VARTOOLONG 31
123 "Variable name too long",
124 #define ERR_VARALNUM 32
125 "Variable name must contain alphanumeric characters",
126 #define ERR_JOBCONTROL 33
127 "No job control in this shell",
128 #define ERR_EXPRESSION 34
129 "Expression Syntax",
130 #define ERR_NOHOMEDIR 35
131 "No home directory",
132 #define ERR_CANTCHANGE 36
133 "Can't change to home directory",
134 #define ERR_NULLCOM 37
135 "Invalid null command",
136 #define ERR_ASSIGN 38
137 "Assignment missing expression",
138 #define ERR_UNKNOWNOP 39
139 "Unknown operator",
140 #define ERR_AMBIG 40
141 "Ambiguous",
142 #define ERR_EXISTS 41
143 "%s: File exists",
144 #define ERR_INTR 42
145 "Interrupted",
146 #define ERR_RANGE 43
147 "Subscript out of range",
148 #define ERR_OVERFLOW 44
149 "Line overflow",
150 #define ERR_VARMOD 45
151 "Unknown variable modifier",
152 #define ERR_NOSUCHJOB 46
153 "No such job",
154 #define ERR_TERMINAL 47
155 "Can't from terminal",
156 #define ERR_NOTWHILE 48
157 "Not in while/foreach",
158 #define ERR_NOPROC 49
159 "No more processes",
160 #define ERR_NOMATCH 50
161 "No match",
162 #define ERR_MISSING 51
163 "Missing %c",
164 #define ERR_UNMATCHED 52
165 "Unmatched %c",
166 #define ERR_NOMEM 53
167 "Out of memory",
168 #define ERR_PIPE 54
169 "Can't make pipe",
170 #define ERR_SYSTEM 55
171 "%s: %s",
172 #define ERR_STRING 56
173 "%s",
174 #define ERR_JOBS 57
175 "Usage: jobs [ -l ]",
176 #define ERR_JOBARGS 58
177 "Arguments should be jobs or process id's",
178 #define ERR_JOBCUR 59
179 "No current job",
180 #define ERR_JOBPREV 60
181 "No previous job",
182 #define ERR_JOBPAT 61
183 "No job matches pattern",
184 #define ERR_NESTING 62
185 "Fork nesting > %d; maybe `...` loop",
186 #define ERR_JOBCTRLSUB 63
187 "No job control in subshells",
188 #define ERR_BADPLPS 64
189 "Badly placed ()'s",
190 #define ERR_STOPPED 65
191 "%sThere are suspended jobs",
192 #define ERR_NODIR 66
193 "No other directory",
194 #define ERR_EMPTY 67
195 "Directory stack empty",
196 #define ERR_BADDIR 68
197 "Bad directory",
198 #define ERR_DIRUS 69
199 "Usage: %s [-lvn]%s",
200 #define ERR_HFLAG 70
201 "No operand for -h flag",
202 #define ERR_NOTLOGIN 71
203 "Not a login shell",
204 #define ERR_DIV0 72
205 "Division by 0",
206 #define ERR_MOD0 73
207 "Mod by 0",
208 #define ERR_BADSCALE 74
209 "Bad scaling; did you mean \"%s\"?",
210 #define ERR_SUSPLOG 75
211 "Can't suspend a login shell (yet)",
212 #define ERR_UNKUSER 76
213 "Unknown user: %s",
214 #define ERR_NOHOME 77
215 "No $home variable set",
216 #define ERR_HISTUS 78
217 "Usage: history [-rh] [# number of events]",
218 #define ERR_SPDOLLT 79
219 "$, ! or < not allowed with $# or $?",
220 #define ERR_NEWLINE 80
221 "Newline in variable name",
222 #define ERR_SPSTAR 81
223 "* not allowed with $# or $?",
224 #define ERR_DIGIT 82
225 "$?<digit> or $#<digit> not allowed",
226 #define ERR_VARILL 83
227 "Illegal variable name",
228 #define ERR_NLINDEX 84
229 "Newline in variable index",
230 #define ERR_EXPOVFL 85
231 "Expansion buffer overflow",
232 #define ERR_VARSYN 86
233 "Variable syntax",
234 #define ERR_BADBANG 87
235 "Bad ! form",
236 #define ERR_NOSUBST 88
237 "No previous substitute",
238 #define ERR_BADSUBST 89
239 "Bad substitute",
240 #define ERR_LHS 90
241 "No previous left hand side",
242 #define ERR_RHSLONG 91
243 "Right hand side too long",
244 #define ERR_BADBANGMOD 92
245 "Bad ! modifier: %c",
246 #define ERR_MODFAIL 93
247 "Modifier failed",
248 #define ERR_SUBOVFL 94
249 "Substitution buffer overflow",
250 #define ERR_BADBANGARG 95
251 "Bad ! arg selector",
252 #define ERR_NOSEARCH 96
253 "No prev search",
254 #define ERR_NOEVENT 97
255 "%s: Event not found",
256 #define ERR_TOOMANYRP 98
257 "Too many )'s",
258 #define ERR_TOOMANYLP 99
259 "Too many ('s",
260 #define ERR_BADPLP 100
261 "Badly placed (",
262 #define ERR_MISRED 101
263 "Missing name for redirect",
264 #define ERR_OUTRED 102
265 "Ambiguous output redirect",
266 #define ERR_REDPAR 103
267 "Can't << within ()'s",
268 #define ERR_INRED 104
269 "Ambiguous input redirect",
270 #define ERR_ALIASLOOP 105
271 "Alias loop",
272 #define ERR_HISTLOOP 106
273 "!# History loop",
274 #define ERR_ARCH 107
275 "%s: %s. Wrong Architecture",
276 #define ERR_FILEINQ 108
277 "Malformed file inquiry",
278 #define ERR_SELOVFL 109
279 "Selector overflow",
280 #define ERR_INVALID 110
281 "Invalid Error"
282 };
283
284 /*
285 * The parser and scanner set up errors for later by calling seterr,
286 * which sets the variable err as a side effect; later to be tested,
287 * e.g. in process.
288 */
289 void
290 #if __STDC__
291 seterror(int id, ...)
292 #else
293 seterror(id, va_alist)
294 int id;
295 va_dcl
296 #endif
297 {
298 if (seterr == 0) {
299 char berr[BUFSIZ];
300 va_list va;
301
302 #if __STDC__
303 va_start(va, id);
304 #else
305 va_start(va);
306 #endif
307 if (id < 0 || id > sizeof(errorlist) / sizeof(errorlist[0]))
308 id = ERR_INVALID;
309 vsprintf(berr, errorlist[id], va);
310 va_end(va);
311
312 seterr = strsave(berr);
313 }
314 }
315
316 /*
317 * Print the error with the given id.
318 *
319 * Special ids:
320 * ERR_SILENT: Print nothing.
321 * ERR_OLD: Print the previously set error if one was there.
322 * otherwise return.
323 * ERR_NAME: If this bit is set, print the name of the function
324 * in bname
325 *
326 * This routine always resets or exits. The flag haderr
327 * is set so the routine who catches the unwind can propogate
328 * it if they want.
329 *
330 * Note that any open files at the point of error will eventually
331 * be closed in the routine process in sh.c which is the only
332 * place error unwinds are ever caught.
333 */
334 void
335 #if __STDC__
336 stderror(int id, ...)
337 #else
338 stderror(id, va_alist)
339 int id;
340 va_dcl
341 #endif
342 {
343 va_list va;
344 register Char **v;
345 int flags = id & ERR_FLAGS;
346
347 id &= ~ERR_FLAGS;
348
349 if ((flags & ERR_OLD) && seterr == NULL)
350 return;
351
352 if (id < 0 || id > sizeof(errorlist) / sizeof(errorlist[0]))
353 id = ERR_INVALID;
354
355 (void) fflush(cshout);
356 (void) fflush(csherr);
357 haderr = 1; /* Now to diagnostic output */
358 timflg = 0; /* This isn't otherwise reset */
359
360
361 if (!(flags & ERR_SILENT)) {
362 if (flags & ERR_NAME)
363 (void) fprintf(csherr, "%s: ", bname);
364 if ((flags & ERR_OLD))
365 /* Old error. */
366 (void) fprintf(csherr, "%s.\n", seterr);
367 else {
368 #if __STDC__
369 va_start(va, id);
370 #else
371 va_start(va);
372 #endif
373 (void) vfprintf(csherr, errorlist[id], va);
374 va_end(va);
375 (void) fprintf(csherr, ".\n");
376 }
377 }
378
379 if (seterr) {
380 xfree((ptr_t) seterr);
381 seterr = NULL;
382 }
383
384 if ((v = pargv) != NULL)
385 pargv = 0, blkfree(v);
386 if ((v = gargv) != NULL)
387 gargv = 0, blkfree(v);
388
389 (void) fflush(cshout);
390 (void) fflush(csherr);
391 didfds = 0; /* Forget about 0,1,2 */
392 /*
393 * Go away if -e or we are a child shell
394 */
395 if (exiterr || child)
396 xexit(1);
397
398 /*
399 * Reset the state of the input. This buffered seek to end of file will
400 * also clear the while/foreach stack.
401 */
402 btoeof();
403
404 set(STRstatus, Strsave(STR1));
405 if (tpgrp > 0)
406 (void) tcsetpgrp(FSHTTY, tpgrp);
407 reset(); /* Unwind */
408 }
409