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