]> git.ipfire.org Git - thirdparty/bash.git/blob - error.c
Imported from ../bash-2.03.tar.gz.
[thirdparty/bash.git] / error.c
1 /* error.c -- Functions for handling errors. */
2 /* Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GNU Bash, the Bourne Again SHell.
5
6 Bash is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with Bash; see the file COPYING. If not, write to the Free Software
18 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "config.h"
21
22 #include "bashtypes.h"
23 #include <fcntl.h>
24
25 #if defined (HAVE_UNISTD_H)
26 # include <unistd.h>
27 #endif
28
29 #if defined (PREFER_STDARG)
30 # include <stdarg.h>
31 #else
32 # if defined (PREFER_VARARGS)
33 # include <varargs.h>
34 # endif
35 #endif
36
37 #include <stdio.h>
38
39 #include <errno.h>
40 #if !defined (errno)
41 extern int errno;
42 #endif /* !errno */
43
44 #include "bashansi.h"
45 #include "flags.h"
46 #include "error.h"
47 #include "command.h"
48 #include "general.h"
49 #include "externs.h"
50 #include "input.h"
51
52 #if defined (HISTORY)
53 # include "bashhist.h"
54 #endif
55
56 extern int interactive_shell, interactive;
57 extern char *dollar_vars[];
58 extern char *shell_name;
59 #if defined (JOB_CONTROL)
60 extern pid_t shell_pgrp;
61 extern int give_terminal_to ();
62 #endif /* JOB_CONTROL */
63
64 /* The current maintainer of the shell. You change this in the
65 Makefile. */
66 #if !defined (MAINTAINER)
67 #define MAINTAINER "bash-maintainers@prep.ai.mit.edu"
68 #endif
69
70 char *the_current_maintainer = MAINTAINER;
71
72 /* Return the name of the shell or the shell script for error reporting. */
73 char *
74 get_name_for_error ()
75 {
76 char *name;
77
78 name = (char *)NULL;
79 if (interactive_shell == 0)
80 name = dollar_vars[0];
81 if (name == 0 && shell_name && *shell_name)
82 name = base_pathname (shell_name);
83 if (name == 0)
84 #if defined (PROGRAM)
85 name = PROGRAM;
86 #else
87 name = "bash";
88 #endif
89
90 return (name);
91 }
92
93 /* Report an error having to do with FILENAME. This does not use
94 sys_error so the filename is not interpreted as a printf-style
95 format string. */
96 void
97 file_error (filename)
98 char *filename;
99 {
100 report_error ("%s: %s", filename, strerror (errno));
101 }
102
103 #if !defined (USE_VARARGS)
104 void
105 programming_error (reason, arg1, arg2, arg3, arg4, arg5)
106 char *reason;
107 {
108 char *h;
109
110 #if defined (JOB_CONTROL)
111 give_terminal_to (shell_pgrp);
112 #endif /* JOB_CONTROL */
113
114 report_error (reason, arg1, arg2);
115
116 #if defined (HISTORY)
117 if (remember_on_history)
118 {
119 h = last_history_line ();
120 fprintf (stderr, "last command: %s\n", h ? h : "(null)");
121 }
122 #endif
123
124 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
125 fprintf (stderr, "Stopping myself...");
126 fflush (stderr);
127
128 abort ();
129 }
130
131 void
132 report_error (format, arg1, arg2, arg3, arg4, arg5)
133 char *format;
134 {
135 fprintf (stderr, "%s: ", get_name_for_error ());
136
137 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
138 fprintf (stderr, "\n");
139 if (exit_immediately_on_error)
140 exit (1);
141 }
142
143 void
144 parser_error (lineno, format, arg1, arg2, arg3, arg4, arg5);
145 int lineno;
146 char *format;
147 va_dcl
148 {
149 char *ename, *iname;
150
151 ename = get_name_for_error ();
152 iname = bash_input.name ? bash_input.name : "stdin";
153
154 if (interactive)
155 fprintf (stderr, "%s: ", ename);
156 else if (interactive_shell)
157 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
158 else if (STREQ (ename, iname))
159 fprintf (stderr, "%s: line %d: ", ename, lineno);
160 else
161 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
162
163 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
164 fprintf (stderr, "\n");
165
166 if (exit_immediately_on_error)
167 exit (2);
168 }
169
170 void
171 fatal_error (format, arg1, arg2, arg3, arg4, arg5)
172 char *format;
173 {
174 fprintf (stderr, "%s: ", get_name_for_error ());
175
176 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
177 fprintf (stderr, "\n");
178
179 exit (2);
180 }
181
182 void
183 internal_error (format, arg1, arg2, arg3, arg4, arg5)
184 char *format;
185 {
186 fprintf (stderr, "%s: ", get_name_for_error ());
187
188 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
189 fprintf (stderr, "\n");
190 }
191
192 void
193 internal_warning (format, arg1, arg2, arg3, arg4, arg5)
194 char *format;
195 {
196 fprintf (stderr, "%s: warning: ", get_name_for_error ());
197
198 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
199 fprintf (stderr, "\n");
200 }
201
202 void
203 sys_error (format, arg1, arg2, arg3, arg4, arg5)
204 char *format;
205 {
206 fprintf (stderr, "%s: ", get_name_for_error ());
207
208 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
209 fprintf (stderr, ": %s\n", strerror (errno));
210 }
211
212 #else /* We have VARARGS support, so use it. */
213
214 void
215 #if defined (PREFER_STDARG)
216 programming_error (const char *format, ...)
217 #else
218 programming_error (format, va_alist)
219 const char *format;
220 va_dcl
221 #endif
222 {
223 va_list args;
224 char *h;
225
226 #if defined (JOB_CONTROL)
227 give_terminal_to (shell_pgrp);
228 #endif /* JOB_CONTROL */
229
230 #if defined (PREFER_STDARG)
231 va_start (args, format);
232 #else
233 va_start (args);
234 #endif
235
236 vfprintf (stderr, format, args);
237 fprintf (stderr, "\n");
238 va_end (args);
239
240 #if defined (HISTORY)
241 if (remember_on_history)
242 {
243 h = last_history_line ();
244 fprintf (stderr, "last command: %s\n", h ? h : "(null)");
245 }
246 #endif
247
248 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
249 fprintf (stderr, "Stopping myself...");
250 fflush (stderr);
251
252 abort ();
253 }
254
255 void
256 #if defined (PREFER_STDARG)
257 report_error (const char *format, ...)
258 #else
259 report_error (format, va_alist)
260 const char *format;
261 va_dcl
262 #endif
263 {
264 va_list args;
265
266 fprintf (stderr, "%s: ", get_name_for_error ());
267
268 #if defined (PREFER_STDARG)
269 va_start (args, format);
270 #else
271 va_start (args);
272 #endif
273
274 vfprintf (stderr, format, args);
275 fprintf (stderr, "\n");
276
277 va_end (args);
278 if (exit_immediately_on_error)
279 exit (1);
280 }
281
282 void
283 #if defined (PREFER_STDARG)
284 fatal_error (const char *format, ...)
285 #else
286 fatal_error (format, va_alist)
287 const char *format;
288 va_dcl
289 #endif
290 {
291 va_list args;
292
293 fprintf (stderr, "%s: ", get_name_for_error ());
294
295 #if defined (PREFER_STDARG)
296 va_start (args, format);
297 #else
298 va_start (args);
299 #endif
300
301 vfprintf (stderr, format, args);
302 fprintf (stderr, "\n");
303
304 va_end (args);
305 exit (2);
306 }
307
308 void
309 #if defined (PREFER_STDARG)
310 internal_error (const char *format, ...)
311 #else
312 internal_error (format, va_alist)
313 const char *format;
314 va_dcl
315 #endif
316 {
317 va_list args;
318
319 fprintf (stderr, "%s: ", get_name_for_error ());
320
321 #if defined (PREFER_STDARG)
322 va_start (args, format);
323 #else
324 va_start (args);
325 #endif
326
327 vfprintf (stderr, format, args);
328 fprintf (stderr, "\n");
329
330 va_end (args);
331 }
332
333 void
334 #if defined (PREFER_STDARG)
335 internal_warning (const char *format, ...)
336 #else
337 internal_warning (format, va_alist)
338 const char *format;
339 va_dcl
340 #endif
341 {
342 va_list args;
343
344 fprintf (stderr, "%s: warning: ", get_name_for_error ());
345
346 #if defined (PREFER_STDARG)
347 va_start (args, format);
348 #else
349 va_start (args);
350 #endif
351
352 vfprintf (stderr, format, args);
353 fprintf (stderr, "\n");
354
355 va_end (args);
356 }
357
358 void
359 #if defined (PREFER_STDARG)
360 sys_error (const char *format, ...)
361 #else
362 sys_error (format, va_alist)
363 const char *format;
364 va_dcl
365 #endif
366 {
367 va_list args;
368
369 fprintf (stderr, "%s: ", get_name_for_error ());
370
371 #if defined (PREFER_STDARG)
372 va_start (args, format);
373 #else
374 va_start (args);
375 #endif
376
377 vfprintf (stderr, format, args);
378 fprintf (stderr, ": %s\n", strerror (errno));
379
380 va_end (args);
381 }
382
383 /* An error from the parser takes the general form
384
385 shell_name: input file name: line number: message
386
387 The input file name and line number are omitted if the shell is
388 currently interactive. If the shell is not currently interactive,
389 the input file name is inserted only if it is different from the
390 shell name. */
391 void
392 #if defined (PREFER_STDARG)
393 parser_error (int lineno, const char *format, ...)
394 #else
395 parser_error (lineno, format, va_alist)
396 int lineno;
397 const char *format;
398 va_dcl
399 #endif
400 {
401 va_list args;
402 char *ename, *iname;
403
404 ename = get_name_for_error ();
405 iname = bash_input.name ? bash_input.name : "stdin";
406
407 if (interactive)
408 fprintf (stderr, "%s: ", ename);
409 else if (interactive_shell)
410 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
411 else if (STREQ (ename, iname))
412 fprintf (stderr, "%s: line %d: ", ename, lineno);
413 else
414 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
415
416 #if defined (PREFER_STDARG)
417 va_start (args, format);
418 #else
419 va_start (args);
420 #endif
421
422 vfprintf (stderr, format, args);
423 fprintf (stderr, "\n");
424
425 va_end (args);
426
427 if (exit_immediately_on_error)
428 exit (2);
429 }
430
431 void
432 #if defined (PREFER_STDARG)
433 itrace (const char *format, ...)
434 #else
435 itrace (format, va_alist)
436 const char *format;
437 va_dcl
438 #endif
439 {
440 va_list args;
441
442 fprintf(stderr, "TRACE: pid %d: ", (int)getpid());
443
444 #if defined (PREFER_STDARG)
445 va_start (args, format);
446 #else
447 va_start (args);
448 #endif
449
450 vfprintf (stderr, format, args);
451 fprintf (stderr, "\n");
452
453 va_end (args);
454
455 fflush(stderr);
456 }
457
458 #if 0
459 /* A trace function for silent debugging -- doesn't require a control
460 terminal. */
461 void
462 #if defined (PREFER_STDARG)
463 trace (const char *format, ...)
464 #else
465 trace (format, va_alist)
466 const char *format;
467 va_dcl
468 #endif
469 {
470 va_list args;
471 static FILE *tracefp = (FILE *)NULL;
472
473 if (tracefp == NULL)
474 tracefp = fopen("/usr/tmp/bash-trace.log", "a+");
475
476 if (tracefp == NULL)
477 tracefp = stderr;
478 else
479 fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
480
481 fprintf(tracefp, "TRACE: pid %d: ", getpid());
482
483 #if defined (PREFER_STDARG)
484 va_start (args, format);
485 #else
486 va_start (args);
487 #endif
488
489 vfprintf (tracefp, format, args);
490 fprintf (tracefp, "\n");
491
492 va_end (args);
493
494 fflush(tracefp);
495 }
496 #endif /* 0 */
497
498 #endif /* USE_VARARGS */
499
500 static char *cmd_error_table[] = {
501 "unknown command error", /* CMDERR_DEFAULT */
502 "bad command type", /* CMDERR_BADTYPE */
503 "bad connector", /* CMDERR_BADCONN */
504 "bad jump", /* CMDERR_BADJUMP */
505 0
506 };
507
508 void
509 command_error (func, code, e, flags)
510 const char *func;
511 int code, e, flags; /* flags currently unused */
512 {
513 if (code > CMDERR_LAST)
514 code = CMDERR_DEFAULT;
515
516 programming_error ("%s: %s: %d", func, cmd_error_table[code], e);
517 }
518
519 char *
520 command_errstr (code)
521 int code;
522 {
523 if (code > CMDERR_LAST)
524 code = CMDERR_DEFAULT;
525
526 return (cmd_error_table[code]);
527 }