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