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