]> git.ipfire.org Git - thirdparty/bash.git/blob - error.c
Imported from ../bash-3.0.tar.gz.
[thirdparty/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 }