]> git.ipfire.org Git - thirdparty/bash.git/blame - error.c
Imported from ../bash-2.04.tar.gz.
[thirdparty/bash.git] / error.c
CommitLineData
726f6388
JA
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
bb70624e 18 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
726f6388 19
ccc6cda3
JA
20#include "config.h"
21
d166f048 22#include "bashtypes.h"
726f6388
JA
23#include <fcntl.h>
24
ccc6cda3
JA
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
726f6388
JA
35#endif
36
d166f048
JA
37#include <stdio.h>
38
726f6388
JA
39#include <errno.h>
40#if !defined (errno)
41extern 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"
ccc6cda3
JA
49#include "externs.h"
50#include "input.h"
726f6388 51
ccc6cda3
JA
52#if defined (HISTORY)
53# include "bashhist.h"
54#endif
55
56extern int interactive_shell, interactive;
726f6388
JA
57extern char *dollar_vars[];
58extern char *shell_name;
726f6388
JA
59#if defined (JOB_CONTROL)
60extern pid_t shell_pgrp;
ccc6cda3 61extern int give_terminal_to ();
726f6388
JA
62#endif /* JOB_CONTROL */
63
ccc6cda3
JA
64/* The current maintainer of the shell. You change this in the
65 Makefile. */
66#if !defined (MAINTAINER)
bb70624e 67#define MAINTAINER "bash-maintainers@gnu.org"
ccc6cda3
JA
68#endif
69
70char *the_current_maintainer = MAINTAINER;
71
726f6388
JA
72/* Return the name of the shell or the shell script for error reporting. */
73char *
74get_name_for_error ()
75{
ccc6cda3 76 char *name;
726f6388 77
ccc6cda3
JA
78 name = (char *)NULL;
79 if (interactive_shell == 0)
726f6388 80 name = dollar_vars[0];
ccc6cda3 81 if (name == 0 && shell_name && *shell_name)
726f6388 82 name = base_pathname (shell_name);
ccc6cda3
JA
83 if (name == 0)
84#if defined (PROGRAM)
85 name = PROGRAM;
86#else
726f6388 87 name = "bash";
ccc6cda3 88#endif
726f6388
JA
89
90 return (name);
91}
92
ccc6cda3
JA
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. */
726f6388
JA
96void
97file_error (filename)
98 char *filename;
99{
100 report_error ("%s: %s", filename, strerror (errno));
101}
102
ccc6cda3 103#if !defined (USE_VARARGS)
726f6388
JA
104void
105programming_error (reason, arg1, arg2, arg3, arg4, arg5)
106 char *reason;
107{
ccc6cda3
JA
108 char *h;
109
726f6388
JA
110#if defined (JOB_CONTROL)
111 give_terminal_to (shell_pgrp);
112#endif /* JOB_CONTROL */
113
114 report_error (reason, arg1, arg2);
ccc6cda3
JA
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
bb70624e 124#if 0
726f6388 125 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
bb70624e
JA
126#endif
127
726f6388
JA
128 fprintf (stderr, "Stopping myself...");
129 fflush (stderr);
ccc6cda3 130
726f6388
JA
131 abort ();
132}
133
134void
135report_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);
ccc6cda3
JA
144}
145
146void
147parser_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}
726f6388
JA
172
173void
174fatal_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
185void
186internal_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
cce855bc
JA
195void
196internal_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
ccc6cda3
JA
205void
206sys_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
726f6388
JA
215#else /* We have VARARGS support, so use it. */
216
217void
ccc6cda3
JA
218#if defined (PREFER_STDARG)
219programming_error (const char *format, ...)
220#else
221programming_error (format, va_alist)
222 const char *format;
726f6388 223 va_dcl
ccc6cda3 224#endif
726f6388
JA
225{
226 va_list args;
ccc6cda3 227 char *h;
726f6388
JA
228
229#if defined (JOB_CONTROL)
230 give_terminal_to (shell_pgrp);
231#endif /* JOB_CONTROL */
232
ccc6cda3
JA
233#if defined (PREFER_STDARG)
234 va_start (args, format);
235#else
726f6388 236 va_start (args);
ccc6cda3
JA
237#endif
238
726f6388
JA
239 vfprintf (stderr, format, args);
240 fprintf (stderr, "\n");
241 va_end (args);
242
ccc6cda3
JA
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
bb70624e 251#if 0
d166f048 252 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
bb70624e
JA
253#endif
254
726f6388
JA
255 fprintf (stderr, "Stopping myself...");
256 fflush (stderr);
ccc6cda3 257
726f6388
JA
258 abort ();
259}
260
261void
ccc6cda3
JA
262#if defined (PREFER_STDARG)
263report_error (const char *format, ...)
264#else
265report_error (format, va_alist)
266 const char *format;
726f6388 267 va_dcl
ccc6cda3 268#endif
726f6388
JA
269{
270 va_list args;
726f6388
JA
271
272 fprintf (stderr, "%s: ", get_name_for_error ());
ccc6cda3
JA
273
274#if defined (PREFER_STDARG)
275 va_start (args, format);
276#else
726f6388 277 va_start (args);
ccc6cda3
JA
278#endif
279
726f6388
JA
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
288void
ccc6cda3
JA
289#if defined (PREFER_STDARG)
290fatal_error (const char *format, ...)
291#else
292fatal_error (format, va_alist)
293 const char *format;
726f6388 294 va_dcl
ccc6cda3 295#endif
726f6388
JA
296{
297 va_list args;
726f6388
JA
298
299 fprintf (stderr, "%s: ", get_name_for_error ());
ccc6cda3
JA
300
301#if defined (PREFER_STDARG)
302 va_start (args, format);
303#else
726f6388 304 va_start (args);
ccc6cda3
JA
305#endif
306
726f6388
JA
307 vfprintf (stderr, format, args);
308 fprintf (stderr, "\n");
309
310 va_end (args);
311 exit (2);
312}
313
314void
ccc6cda3
JA
315#if defined (PREFER_STDARG)
316internal_error (const char *format, ...)
317#else
318internal_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
cce855bc
JA
339void
340#if defined (PREFER_STDARG)
341internal_warning (const char *format, ...)
342#else
343internal_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
ccc6cda3
JA
364void
365#if defined (PREFER_STDARG)
366sys_error (const char *format, ...)
367#else
368sys_error (format, va_alist)
369 const char *format;
726f6388 370 va_dcl
ccc6cda3 371#endif
726f6388
JA
372{
373 va_list args;
726f6388
JA
374
375 fprintf (stderr, "%s: ", get_name_for_error ());
ccc6cda3
JA
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. */
397void
398#if defined (PREFER_STDARG)
399parser_error (int lineno, const char *format, ...)
400#else
401parser_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
726f6388 425 va_start (args);
ccc6cda3
JA
426#endif
427
726f6388
JA
428 vfprintf (stderr, format, args);
429 fprintf (stderr, "\n");
430
431 va_end (args);
ccc6cda3
JA
432
433 if (exit_immediately_on_error)
434 exit (2);
726f6388
JA
435}
436
ccc6cda3
JA
437void
438#if defined (PREFER_STDARG)
439itrace (const char *format, ...)
440#else
441itrace (format, va_alist)
442 const char *format;
726f6388 443 va_dcl
ccc6cda3 444#endif
726f6388
JA
445{
446 va_list args;
726f6388 447
ccc6cda3
JA
448 fprintf(stderr, "TRACE: pid %d: ", (int)getpid());
449
450#if defined (PREFER_STDARG)
451 va_start (args, format);
452#else
726f6388 453 va_start (args);
ccc6cda3
JA
454#endif
455
726f6388
JA
456 vfprintf (stderr, format, args);
457 fprintf (stderr, "\n");
458
459 va_end (args);
460
461 fflush(stderr);
462}
463
726f6388
JA
464/* A trace function for silent debugging -- doesn't require a control
465 terminal. */
ccc6cda3
JA
466void
467#if defined (PREFER_STDARG)
468trace (const char *format, ...)
469#else
470trace (format, va_alist)
471 const char *format;
726f6388 472 va_dcl
ccc6cda3 473#endif
726f6388
JA
474{
475 va_list args;
726f6388
JA
476 static FILE *tracefp = (FILE *)NULL;
477
478 if (tracefp == NULL)
bb70624e 479 tracefp = fopen("/tmp/bash-trace.log", "a+");
726f6388
JA
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
ccc6cda3
JA
488#if defined (PREFER_STDARG)
489 va_start (args, format);
490#else
726f6388 491 va_start (args);
ccc6cda3
JA
492#endif
493
726f6388
JA
494 vfprintf (tracefp, format, args);
495 fprintf (tracefp, "\n");
496
497 va_end (args);
498
499 fflush(tracefp);
500}
ccc6cda3
JA
501
502#endif /* USE_VARARGS */
b72432fd
JA
503
504static 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
512void
513command_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
523char *
524command_errstr (code)
525 int code;
526{
527 if (code > CMDERR_LAST)
528 code = CMDERR_DEFAULT;
529
530 return (cmd_error_table[code]);
531}