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