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