Imported from ../bash-2.04.tar.gz.
[platform/upstream/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 }