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