]> git.ipfire.org Git - thirdparty/bash.git/blob - error.c
Imported from ../bash-2.05.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 #ifdef DEBUG
438 void
439 #if defined (PREFER_STDARG)
440 itrace (const char *format, ...)
441 #else
442 itrace (format, va_alist)
443 const char *format;
444 va_dcl
445 #endif
446 {
447 va_list args;
448
449 fprintf(stderr, "TRACE: pid %d: ", (int)getpid());
450
451 #if defined (PREFER_STDARG)
452 va_start (args, format);
453 #else
454 va_start (args);
455 #endif
456
457 vfprintf (stderr, format, args);
458 fprintf (stderr, "\n");
459
460 va_end (args);
461
462 fflush(stderr);
463 }
464
465 /* A trace function for silent debugging -- doesn't require a control
466 terminal. */
467 void
468 #if defined (PREFER_STDARG)
469 trace (const char *format, ...)
470 #else
471 trace (format, va_alist)
472 const char *format;
473 va_dcl
474 #endif
475 {
476 va_list args;
477 static FILE *tracefp = (FILE *)NULL;
478
479 if (tracefp == NULL)
480 tracefp = fopen("/tmp/bash-trace.log", "a+");
481
482 if (tracefp == NULL)
483 tracefp = stderr;
484 else
485 fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
486
487 fprintf(tracefp, "TRACE: pid %d: ", getpid());
488
489 #if defined (PREFER_STDARG)
490 va_start (args, format);
491 #else
492 va_start (args);
493 #endif
494
495 vfprintf (tracefp, format, args);
496 fprintf (tracefp, "\n");
497
498 va_end (args);
499
500 fflush(tracefp);
501 }
502
503 #endif /* USE_VARARGS */
504 #endif /* DEBUG */
505
506 static char *cmd_error_table[] = {
507 "unknown command error", /* CMDERR_DEFAULT */
508 "bad command type", /* CMDERR_BADTYPE */
509 "bad connector", /* CMDERR_BADCONN */
510 "bad jump", /* CMDERR_BADJUMP */
511 0
512 };
513
514 void
515 command_error (func, code, e, flags)
516 const char *func;
517 int code, e, flags; /* flags currently unused */
518 {
519 if (code > CMDERR_LAST)
520 code = CMDERR_DEFAULT;
521
522 programming_error ("%s: %s: %d", func, cmd_error_table[code], e);
523 }
524
525 char *
526 command_errstr (code)
527 int code;
528 {
529 if (code > CMDERR_LAST)
530 code = CMDERR_DEFAULT;
531
532 return (cmd_error_table[code]);
533 }