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