Imported from ../bash-3.1.tar.gz.
[platform/upstream/bash.git] / error.c
1 /* error.c -- Functions for handling errors. */
2 /* Copyright (C) 1993-2003 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 #  include <varargs.h>
33 #endif
34
35 #include <stdio.h>
36
37 #include <errno.h>
38 #if !defined (errno)
39 extern int errno;
40 #endif /* !errno */
41
42 #include "bashansi.h"
43 #include "bashintl.h"
44
45 #include "shell.h"
46 #include "flags.h"
47 #include "input.h"
48
49 #if defined (HISTORY)
50 #  include "bashhist.h"
51 #endif
52
53 extern int executing_line_number __P((void));
54
55 extern int interactive_shell, interactive, startup_state;
56 extern char *dollar_vars[];
57 extern char *shell_name;
58 #if defined (JOB_CONTROL)
59 extern pid_t shell_pgrp;
60 extern int give_terminal_to __P((pid_t, int));
61 #endif /* JOB_CONTROL */
62
63 #if defined (ARRAY_VARS)
64 extern char *bash_badsub_errmsg;
65 #endif
66
67 static void error_prolog __P((int));
68
69 /* The current maintainer of the shell.  You change this in the
70    Makefile. */
71 #if !defined (MAINTAINER)
72 #define MAINTAINER "bash-maintainers@gnu.org"
73 #endif
74
75 char *the_current_maintainer = MAINTAINER;
76
77 int gnu_error_format = 0;
78
79 static void
80 error_prolog (print_lineno)
81      int print_lineno;
82 {
83   char *ename;
84   int line;
85
86   ename = get_name_for_error ();
87   line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
88
89   if (line > 0)
90     fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : " line ", line);
91   else
92     fprintf (stderr, "%s: ", ename);
93 }
94
95 /* Return the name of the shell or the shell script for error reporting. */
96 char *
97 get_name_for_error ()
98 {
99   char *name;
100 #if defined (ARRAY_VARS)
101   SHELL_VAR *bash_source_v;
102   ARRAY *bash_source_a;
103 #endif
104
105   name = (char *)NULL;
106   if (interactive_shell == 0)
107     {
108 #if defined (ARRAY_VARS)
109       bash_source_v = find_variable ("BASH_SOURCE");
110       if (bash_source_v && array_p (bash_source_v) &&
111           (bash_source_a = array_cell (bash_source_v)))
112         name = array_reference (bash_source_a, 0);
113       if (name == 0)
114 #endif
115         name = dollar_vars[0];
116     }
117   if (name == 0 && shell_name && *shell_name)
118     name = base_pathname (shell_name);
119   if (name == 0)
120 #if defined (PROGRAM)
121     name = PROGRAM;
122 #else
123     name = "bash";
124 #endif
125
126   return (name);
127 }
128
129 /* Report an error having to do with FILENAME.  This does not use
130    sys_error so the filename is not interpreted as a printf-style
131    format string. */
132 void
133 file_error (filename)
134      const char *filename;
135 {
136   report_error ("%s: %s", filename, strerror (errno));
137 }
138
139 void
140 #if defined (PREFER_STDARG)
141 programming_error (const char *format, ...)
142 #else
143 programming_error (format, va_alist)
144      const char *format;
145      va_dcl
146 #endif
147 {
148   va_list args;
149   char *h;
150
151 #if defined (JOB_CONTROL)
152   give_terminal_to (shell_pgrp, 0);
153 #endif /* JOB_CONTROL */
154
155   SH_VA_START (args, format);
156
157   vfprintf (stderr, format, args);
158   fprintf (stderr, "\n");
159   va_end (args);
160
161 #if defined (HISTORY)
162   if (remember_on_history)
163     {
164       h = last_history_line ();
165       fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
166     }
167 #endif
168
169 #if 0
170   fprintf (stderr, "Report this to %s\n", the_current_maintainer);
171 #endif
172
173   fprintf (stderr, _("Aborting..."));
174   fflush (stderr);
175
176   abort ();
177 }
178
179 /* Print an error message and, if `set -e' has been executed, exit the
180    shell.  Used in this file by file_error and programming_error.  Used
181    outside this file mostly to report substitution and expansion errors,
182    and for bad invocation options. */
183 void
184 #if defined (PREFER_STDARG)
185 report_error (const char *format, ...)
186 #else
187 report_error (format, va_alist)
188      const char *format;
189      va_dcl
190 #endif
191 {
192   va_list args;
193
194   error_prolog (1);
195
196   SH_VA_START (args, format);
197
198   vfprintf (stderr, format, args);
199   fprintf (stderr, "\n");
200
201   va_end (args);
202   if (exit_immediately_on_error)
203     exit_shell (1);
204 }
205
206 void
207 #if defined (PREFER_STDARG)
208 fatal_error (const char *format, ...)
209 #else
210 fatal_error (format, va_alist)
211      const char *format;
212      va_dcl
213 #endif
214 {
215   va_list args;
216
217   error_prolog (0);
218
219   SH_VA_START (args, format);
220
221   vfprintf (stderr, format, args);
222   fprintf (stderr, "\n");
223
224   va_end (args);
225   sh_exit (2);
226 }
227
228 void
229 #if defined (PREFER_STDARG)
230 internal_error (const char *format, ...)
231 #else
232 internal_error (format, va_alist)
233      const char *format;
234      va_dcl
235 #endif
236 {
237   va_list args;
238
239   error_prolog (1);
240
241   SH_VA_START (args, format);
242
243   vfprintf (stderr, format, args);
244   fprintf (stderr, "\n");
245
246   va_end (args);
247 }
248
249 void
250 #if defined (PREFER_STDARG)
251 internal_warning (const char *format, ...)
252 #else
253 internal_warning (format, va_alist)
254      const char *format;
255      va_dcl
256 #endif
257 {
258   va_list args;
259
260   fprintf (stderr, _("%s: warning: "), get_name_for_error ());
261
262   SH_VA_START (args, format);
263
264   vfprintf (stderr, format, args);
265   fprintf (stderr, "\n");
266
267   va_end (args);
268 }
269
270 void
271 #if defined (PREFER_STDARG)
272 sys_error (const char *format, ...)
273 #else
274 sys_error (format, va_alist)
275      const char *format;
276      va_dcl
277 #endif
278 {
279   int e;
280   va_list args;
281
282   e = errno;
283   error_prolog (0);
284
285   SH_VA_START (args, format);
286
287   vfprintf (stderr, format, args);
288   fprintf (stderr, ": %s\n", strerror (e));
289
290   va_end (args);
291 }
292
293 /* An error from the parser takes the general form
294
295         shell_name: input file name: line number: message
296
297    The input file name and line number are omitted if the shell is
298    currently interactive.  If the shell is not currently interactive,
299    the input file name is inserted only if it is different from the
300    shell name. */
301 void
302 #if defined (PREFER_STDARG)
303 parser_error (int lineno, const char *format, ...)
304 #else
305 parser_error (lineno, format, va_alist)
306      int lineno;
307      const char *format;
308      va_dcl
309 #endif
310 {
311   va_list args;
312   char *ename, *iname;
313
314   ename = get_name_for_error ();
315   iname = yy_input_name ();
316
317   if (interactive)
318     fprintf (stderr, "%s: ", ename);
319   else if (interactive_shell)
320     fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : " line ", lineno);
321   else if (STREQ (ename, iname))
322     fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : " line ", lineno);
323   else
324     fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : " line ", lineno);
325
326   SH_VA_START (args, format);
327
328   vfprintf (stderr, format, args);
329   fprintf (stderr, "\n");
330
331   va_end (args);
332
333   if (exit_immediately_on_error)
334     exit_shell (2);
335 }
336
337 #ifdef DEBUG
338 void
339 #if defined (PREFER_STDARG)
340 itrace (const char *format, ...)
341 #else
342 itrace (format, va_alist)
343      const char *format;
344      va_dcl
345 #endif
346 {
347   va_list args;
348
349   fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
350
351   SH_VA_START (args, format);
352
353   vfprintf (stderr, format, args);
354   fprintf (stderr, "\n");
355
356   va_end (args);
357
358   fflush(stderr);
359 }
360
361 /* A trace function for silent debugging -- doesn't require a control
362    terminal. */
363 void
364 #if defined (PREFER_STDARG)
365 trace (const char *format, ...)
366 #else
367 trace (format, va_alist)
368      const char *format;
369      va_dcl
370 #endif
371 {
372   va_list args;
373   static FILE *tracefp = (FILE *)NULL;
374
375   if (tracefp == NULL)
376     tracefp = fopen("/tmp/bash-trace.log", "a+");
377
378   if (tracefp == NULL)
379     tracefp = stderr;
380   else
381     fcntl (fileno (tracefp), F_SETFD, 1);     /* close-on-exec */
382
383   fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
384
385   SH_VA_START (args, format);
386
387   vfprintf (tracefp, format, args);
388   fprintf (tracefp, "\n");
389
390   va_end (args);
391
392   fflush(tracefp);
393 }
394
395 #endif /* DEBUG */
396
397 /* **************************************************************** */
398 /*                                                                  */
399 /*                  Common error reporting                          */
400 /*                                                                  */
401 /* **************************************************************** */
402
403
404 static char *cmd_error_table[] = {
405         N_("unknown command error"),    /* CMDERR_DEFAULT */
406         N_("bad command type"),         /* CMDERR_BADTYPE */
407         N_("bad connector"),            /* CMDERR_BADCONN */
408         N_("bad jump"),                 /* CMDERR_BADJUMP */
409         0
410 };
411
412 void
413 command_error (func, code, e, flags)
414      const char *func;
415      int code, e, flags;        /* flags currently unused */
416 {
417   if (code > CMDERR_LAST)
418     code = CMDERR_DEFAULT;
419
420   programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
421 }
422
423 char *
424 command_errstr (code)
425      int code;
426 {
427   if (code > CMDERR_LAST)
428     code = CMDERR_DEFAULT;
429
430   return (_(cmd_error_table[code]));
431 }
432
433 #ifdef ARRAY_VARS
434 void
435 err_badarraysub (s)
436      const char *s;
437 {
438   report_error ("%s: %s", s, _(bash_badsub_errmsg));
439 }
440 #endif
441
442 void
443 err_unboundvar (s)
444      const char *s;
445 {
446   report_error (_("%s: unbound variable"), s);
447 }
448
449 void
450 err_readonly (s)
451      const char *s;
452 {
453   report_error (_("%s: readonly variable"), s);
454 }