]> git.ipfire.org Git - thirdparty/bash.git/blob - error.c
Imported from ../bash-4.0-rc1.tar.gz.
[thirdparty/bash.git] / error.c
1 /* error.c -- Functions for handling errors. */
2
3 /* Copyright (C) 1993-2009 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include "bashtypes.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 # include <varargs.h>
34 #endif
35
36 #include <stdio.h>
37
38 #include <errno.h>
39 #if !defined (errno)
40 extern int errno;
41 #endif /* !errno */
42
43 #include "bashansi.h"
44 #include "bashintl.h"
45
46 #include "shell.h"
47 #include "flags.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 char *shell_name;
57 #if defined (JOB_CONTROL)
58 extern pid_t shell_pgrp;
59 extern int give_terminal_to __P((pid_t, int));
60 #endif /* JOB_CONTROL */
61
62 #if defined (ARRAY_VARS)
63 extern const char * const bash_badsub_errmsg;
64 #endif
65
66 static void error_prolog __P((int));
67
68 /* The current maintainer of the shell. You change this in the
69 Makefile. */
70 #if !defined (MAINTAINER)
71 #define MAINTAINER "bash-maintainers@gnu.org"
72 #endif
73
74 const char * const the_current_maintainer = MAINTAINER;
75
76 int gnu_error_format = 0;
77
78 static void
79 error_prolog (print_lineno)
80 int print_lineno;
81 {
82 char *ename;
83 int line;
84
85 ename = get_name_for_error ();
86 line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
87
88 if (line > 0)
89 fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line);
90 else
91 fprintf (stderr, "%s: ", ename);
92 }
93
94 /* Return the name of the shell or the shell script for error reporting. */
95 char *
96 get_name_for_error ()
97 {
98 char *name;
99 #if defined (ARRAY_VARS)
100 SHELL_VAR *bash_source_v;
101 ARRAY *bash_source_a;
102 #endif
103
104 name = (char *)NULL;
105 if (interactive_shell == 0)
106 {
107 #if defined (ARRAY_VARS)
108 bash_source_v = find_variable ("BASH_SOURCE");
109 if (bash_source_v && array_p (bash_source_v) &&
110 (bash_source_a = array_cell (bash_source_v)))
111 name = array_reference (bash_source_a, 0);
112 if (name == 0 || *name == '\0') /* XXX - was just name == 0 */
113 #endif
114 name = dollar_vars[0];
115 }
116 if (name == 0 && shell_name && *shell_name)
117 name = base_pathname (shell_name);
118 if (name == 0)
119 #if defined (PROGRAM)
120 name = PROGRAM;
121 #else
122 name = "bash";
123 #endif
124
125 return (name);
126 }
127
128 /* Report an error having to do with FILENAME. This does not use
129 sys_error so the filename is not interpreted as a printf-style
130 format string. */
131 void
132 file_error (filename)
133 const char *filename;
134 {
135 report_error ("%s: %s", filename, strerror (errno));
136 }
137
138 void
139 #if defined (PREFER_STDARG)
140 programming_error (const char *format, ...)
141 #else
142 programming_error (format, va_alist)
143 const char *format;
144 va_dcl
145 #endif
146 {
147 va_list args;
148 char *h;
149
150 #if defined (JOB_CONTROL)
151 give_terminal_to (shell_pgrp, 0);
152 #endif /* JOB_CONTROL */
153
154 SH_VA_START (args, format);
155
156 vfprintf (stderr, format, args);
157 fprintf (stderr, "\n");
158 va_end (args);
159
160 #if defined (HISTORY)
161 if (remember_on_history)
162 {
163 h = last_history_line ();
164 fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
165 }
166 #endif
167
168 #if 0
169 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
170 #endif
171
172 fprintf (stderr, _("Aborting..."));
173 fflush (stderr);
174
175 abort ();
176 }
177
178 /* Print an error message and, if `set -e' has been executed, exit the
179 shell. Used in this file by file_error and programming_error. Used
180 outside this file mostly to report substitution and expansion errors,
181 and for bad invocation options. */
182 void
183 #if defined (PREFER_STDARG)
184 report_error (const char *format, ...)
185 #else
186 report_error (format, va_alist)
187 const char *format;
188 va_dcl
189 #endif
190 {
191 va_list args;
192
193 error_prolog (1);
194
195 SH_VA_START (args, format);
196
197 vfprintf (stderr, format, args);
198 fprintf (stderr, "\n");
199
200 va_end (args);
201 if (exit_immediately_on_error)
202 exit_shell (1);
203 }
204
205 void
206 #if defined (PREFER_STDARG)
207 fatal_error (const char *format, ...)
208 #else
209 fatal_error (format, va_alist)
210 const char *format;
211 va_dcl
212 #endif
213 {
214 va_list args;
215
216 error_prolog (0);
217
218 SH_VA_START (args, format);
219
220 vfprintf (stderr, format, args);
221 fprintf (stderr, "\n");
222
223 va_end (args);
224 sh_exit (2);
225 }
226
227 void
228 #if defined (PREFER_STDARG)
229 internal_error (const char *format, ...)
230 #else
231 internal_error (format, va_alist)
232 const char *format;
233 va_dcl
234 #endif
235 {
236 va_list args;
237
238 error_prolog (1);
239
240 SH_VA_START (args, format);
241
242 vfprintf (stderr, format, args);
243 fprintf (stderr, "\n");
244
245 va_end (args);
246 }
247
248 void
249 #if defined (PREFER_STDARG)
250 internal_warning (const char *format, ...)
251 #else
252 internal_warning (format, va_alist)
253 const char *format;
254 va_dcl
255 #endif
256 {
257 va_list args;
258
259 error_prolog (1);
260 fprintf (stderr, _("warning: "));
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 const char * const 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 }