]> git.ipfire.org Git - thirdparty/bash.git/blob - error.c
Imported from ../bash-2.04.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, 59 Temple Place, Suite 330, Boston, MA 02111 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@gnu.org"
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 #if 0
125 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
126 #endif
127
128 fprintf (stderr, "Stopping myself...");
129 fflush (stderr);
130
131 abort ();
132 }
133
134 void
135 report_error (format, arg1, arg2, arg3, arg4, arg5)
136 char *format;
137 {
138 fprintf (stderr, "%s: ", get_name_for_error ());
139
140 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
141 fprintf (stderr, "\n");
142 if (exit_immediately_on_error)
143 exit (1);
144 }
145
146 void
147 parser_error (lineno, format, arg1, arg2, arg3, arg4, arg5);
148 int lineno;
149 char *format;
150 va_dcl
151 {
152 char *ename, *iname;
153
154 ename = get_name_for_error ();
155 iname = bash_input.name ? bash_input.name : "stdin";
156
157 if (interactive)
158 fprintf (stderr, "%s: ", ename);
159 else if (interactive_shell)
160 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
161 else if (STREQ (ename, iname))
162 fprintf (stderr, "%s: line %d: ", ename, lineno);
163 else
164 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
165
166 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
167 fprintf (stderr, "\n");
168
169 if (exit_immediately_on_error)
170 exit (2);
171 }
172
173 void
174 fatal_error (format, arg1, arg2, arg3, arg4, arg5)
175 char *format;
176 {
177 fprintf (stderr, "%s: ", get_name_for_error ());
178
179 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
180 fprintf (stderr, "\n");
181
182 exit (2);
183 }
184
185 void
186 internal_error (format, arg1, arg2, arg3, arg4, arg5)
187 char *format;
188 {
189 fprintf (stderr, "%s: ", get_name_for_error ());
190
191 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
192 fprintf (stderr, "\n");
193 }
194
195 void
196 internal_warning (format, arg1, arg2, arg3, arg4, arg5)
197 char *format;
198 {
199 fprintf (stderr, "%s: warning: ", get_name_for_error ());
200
201 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
202 fprintf (stderr, "\n");
203 }
204
205 void
206 sys_error (format, arg1, arg2, arg3, arg4, arg5)
207 char *format;
208 {
209 fprintf (stderr, "%s: ", get_name_for_error ());
210
211 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
212 fprintf (stderr, ": %s\n", strerror (errno));
213 }
214
215 #else /* We have VARARGS support, so use it. */
216
217 void
218 #if defined (PREFER_STDARG)
219 programming_error (const char *format, ...)
220 #else
221 programming_error (format, va_alist)
222 const char *format;
223 va_dcl
224 #endif
225 {
226 va_list args;
227 char *h;
228
229 #if defined (JOB_CONTROL)
230 give_terminal_to (shell_pgrp);
231 #endif /* JOB_CONTROL */
232
233 #if defined (PREFER_STDARG)
234 va_start (args, format);
235 #else
236 va_start (args);
237 #endif
238
239 vfprintf (stderr, format, args);
240 fprintf (stderr, "\n");
241 va_end (args);
242
243 #if defined (HISTORY)
244 if (remember_on_history)
245 {
246 h = last_history_line ();
247 fprintf (stderr, "last command: %s\n", h ? h : "(null)");
248 }
249 #endif
250
251 #if 0
252 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
253 #endif
254
255 fprintf (stderr, "Stopping myself...");
256 fflush (stderr);
257
258 abort ();
259 }
260
261 void
262 #if defined (PREFER_STDARG)
263 report_error (const char *format, ...)
264 #else
265 report_error (format, va_alist)
266 const char *format;
267 va_dcl
268 #endif
269 {
270 va_list args;
271
272 fprintf (stderr, "%s: ", get_name_for_error ());
273
274 #if defined (PREFER_STDARG)
275 va_start (args, format);
276 #else
277 va_start (args);
278 #endif
279
280 vfprintf (stderr, format, args);
281 fprintf (stderr, "\n");
282
283 va_end (args);
284 if (exit_immediately_on_error)
285 exit (1);
286 }
287
288 void
289 #if defined (PREFER_STDARG)
290 fatal_error (const char *format, ...)
291 #else
292 fatal_error (format, va_alist)
293 const char *format;
294 va_dcl
295 #endif
296 {
297 va_list args;
298
299 fprintf (stderr, "%s: ", get_name_for_error ());
300
301 #if defined (PREFER_STDARG)
302 va_start (args, format);
303 #else
304 va_start (args);
305 #endif
306
307 vfprintf (stderr, format, args);
308 fprintf (stderr, "\n");
309
310 va_end (args);
311 exit (2);
312 }
313
314 void
315 #if defined (PREFER_STDARG)
316 internal_error (const char *format, ...)
317 #else
318 internal_error (format, va_alist)
319 const char *format;
320 va_dcl
321 #endif
322 {
323 va_list args;
324
325 fprintf (stderr, "%s: ", get_name_for_error ());
326
327 #if defined (PREFER_STDARG)
328 va_start (args, format);
329 #else
330 va_start (args);
331 #endif
332
333 vfprintf (stderr, format, args);
334 fprintf (stderr, "\n");
335
336 va_end (args);
337 }
338
339 void
340 #if defined (PREFER_STDARG)
341 internal_warning (const char *format, ...)
342 #else
343 internal_warning (format, va_alist)
344 const char *format;
345 va_dcl
346 #endif
347 {
348 va_list args;
349
350 fprintf (stderr, "%s: warning: ", get_name_for_error ());
351
352 #if defined (PREFER_STDARG)
353 va_start (args, format);
354 #else
355 va_start (args);
356 #endif
357
358 vfprintf (stderr, format, args);
359 fprintf (stderr, "\n");
360
361 va_end (args);
362 }
363
364 void
365 #if defined (PREFER_STDARG)
366 sys_error (const char *format, ...)
367 #else
368 sys_error (format, va_alist)
369 const char *format;
370 va_dcl
371 #endif
372 {
373 va_list args;
374
375 fprintf (stderr, "%s: ", get_name_for_error ());
376
377 #if defined (PREFER_STDARG)
378 va_start (args, format);
379 #else
380 va_start (args);
381 #endif
382
383 vfprintf (stderr, format, args);
384 fprintf (stderr, ": %s\n", strerror (errno));
385
386 va_end (args);
387 }
388
389 /* An error from the parser takes the general form
390
391 shell_name: input file name: line number: message
392
393 The input file name and line number are omitted if the shell is
394 currently interactive. If the shell is not currently interactive,
395 the input file name is inserted only if it is different from the
396 shell name. */
397 void
398 #if defined (PREFER_STDARG)
399 parser_error (int lineno, const char *format, ...)
400 #else
401 parser_error (lineno, format, va_alist)
402 int lineno;
403 const char *format;
404 va_dcl
405 #endif
406 {
407 va_list args;
408 char *ename, *iname;
409
410 ename = get_name_for_error ();
411 iname = bash_input.name ? bash_input.name : "stdin";
412
413 if (interactive)
414 fprintf (stderr, "%s: ", ename);
415 else if (interactive_shell)
416 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
417 else if (STREQ (ename, iname))
418 fprintf (stderr, "%s: line %d: ", ename, lineno);
419 else
420 fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
421
422 #if defined (PREFER_STDARG)
423 va_start (args, format);
424 #else
425 va_start (args);
426 #endif
427
428 vfprintf (stderr, format, args);
429 fprintf (stderr, "\n");
430
431 va_end (args);
432
433 if (exit_immediately_on_error)
434 exit (2);
435 }
436
437 void
438 #if defined (PREFER_STDARG)
439 itrace (const char *format, ...)
440 #else
441 itrace (format, va_alist)
442 const char *format;
443 va_dcl
444 #endif
445 {
446 va_list args;
447
448 fprintf(stderr, "TRACE: pid %d: ", (int)getpid());
449
450 #if defined (PREFER_STDARG)
451 va_start (args, format);
452 #else
453 va_start (args);
454 #endif
455
456 vfprintf (stderr, format, args);
457 fprintf (stderr, "\n");
458
459 va_end (args);
460
461 fflush(stderr);
462 }
463
464 /* A trace function for silent debugging -- doesn't require a control
465 terminal. */
466 void
467 #if defined (PREFER_STDARG)
468 trace (const char *format, ...)
469 #else
470 trace (format, va_alist)
471 const char *format;
472 va_dcl
473 #endif
474 {
475 va_list args;
476 static FILE *tracefp = (FILE *)NULL;
477
478 if (tracefp == NULL)
479 tracefp = fopen("/tmp/bash-trace.log", "a+");
480
481 if (tracefp == NULL)
482 tracefp = stderr;
483 else
484 fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
485
486 fprintf(tracefp, "TRACE: pid %d: ", getpid());
487
488 #if defined (PREFER_STDARG)
489 va_start (args, format);
490 #else
491 va_start (args);
492 #endif
493
494 vfprintf (tracefp, format, args);
495 fprintf (tracefp, "\n");
496
497 va_end (args);
498
499 fflush(tracefp);
500 }
501
502 #endif /* USE_VARARGS */
503
504 static char *cmd_error_table[] = {
505 "unknown command error", /* CMDERR_DEFAULT */
506 "bad command type", /* CMDERR_BADTYPE */
507 "bad connector", /* CMDERR_BADCONN */
508 "bad jump", /* CMDERR_BADJUMP */
509 0
510 };
511
512 void
513 command_error (func, code, e, flags)
514 const char *func;
515 int code, e, flags; /* flags currently unused */
516 {
517 if (code > CMDERR_LAST)
518 code = CMDERR_DEFAULT;
519
520 programming_error ("%s: %s: %d", func, cmd_error_table[code], e);
521 }
522
523 char *
524 command_errstr (code)
525 int code;
526 {
527 if (code > CMDERR_LAST)
528 code = CMDERR_DEFAULT;
529
530 return (cmd_error_table[code]);
531 }