]> git.ipfire.org Git - thirdparty/bash.git/blob - error.c
Bash-4.2 patch 2
[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 int last_command_exit_value;
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 const char * const 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 const char * const 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 || *name == '\0') /* XXX - was just 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 error_prolog (1);
261 fprintf (stderr, _("warning: "));
262
263 SH_VA_START (args, format);
264
265 vfprintf (stderr, format, args);
266 fprintf (stderr, "\n");
267
268 va_end (args);
269 }
270
271 void
272 #if defined (PREFER_STDARG)
273 sys_error (const char *format, ...)
274 #else
275 sys_error (format, va_alist)
276 const char *format;
277 va_dcl
278 #endif
279 {
280 int e;
281 va_list args;
282
283 e = errno;
284 error_prolog (0);
285
286 SH_VA_START (args, format);
287
288 vfprintf (stderr, format, args);
289 fprintf (stderr, ": %s\n", strerror (e));
290
291 va_end (args);
292 }
293
294 /* An error from the parser takes the general form
295
296 shell_name: input file name: line number: message
297
298 The input file name and line number are omitted if the shell is
299 currently interactive. If the shell is not currently interactive,
300 the input file name is inserted only if it is different from the
301 shell name. */
302 void
303 #if defined (PREFER_STDARG)
304 parser_error (int lineno, const char *format, ...)
305 #else
306 parser_error (lineno, format, va_alist)
307 int lineno;
308 const char *format;
309 va_dcl
310 #endif
311 {
312 va_list args;
313 char *ename, *iname;
314
315 ename = get_name_for_error ();
316 iname = yy_input_name ();
317
318 if (interactive)
319 fprintf (stderr, "%s: ", ename);
320 else if (interactive_shell)
321 fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
322 else if (STREQ (ename, iname))
323 fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno);
324 else
325 fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
326
327 SH_VA_START (args, format);
328
329 vfprintf (stderr, format, args);
330 fprintf (stderr, "\n");
331
332 va_end (args);
333
334 if (exit_immediately_on_error)
335 exit_shell (last_command_exit_value = 2);
336 }
337
338 #ifdef DEBUG
339 void
340 #if defined (PREFER_STDARG)
341 itrace (const char *format, ...)
342 #else
343 itrace (format, va_alist)
344 const char *format;
345 va_dcl
346 #endif
347 {
348 va_list args;
349
350 fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
351
352 SH_VA_START (args, format);
353
354 vfprintf (stderr, format, args);
355 fprintf (stderr, "\n");
356
357 va_end (args);
358
359 fflush(stderr);
360 }
361
362 /* A trace function for silent debugging -- doesn't require a control
363 terminal. */
364 void
365 #if defined (PREFER_STDARG)
366 trace (const char *format, ...)
367 #else
368 trace (format, va_alist)
369 const char *format;
370 va_dcl
371 #endif
372 {
373 va_list args;
374 static FILE *tracefp = (FILE *)NULL;
375
376 if (tracefp == NULL)
377 tracefp = fopen("/tmp/bash-trace.log", "a+");
378
379 if (tracefp == NULL)
380 tracefp = stderr;
381 else
382 fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
383
384 fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
385
386 SH_VA_START (args, format);
387
388 vfprintf (tracefp, format, args);
389 fprintf (tracefp, "\n");
390
391 va_end (args);
392
393 fflush(tracefp);
394 }
395
396 #endif /* DEBUG */
397
398 /* **************************************************************** */
399 /* */
400 /* Common error reporting */
401 /* */
402 /* **************************************************************** */
403
404
405 static const char * const cmd_error_table[] = {
406 N_("unknown command error"), /* CMDERR_DEFAULT */
407 N_("bad command type"), /* CMDERR_BADTYPE */
408 N_("bad connector"), /* CMDERR_BADCONN */
409 N_("bad jump"), /* CMDERR_BADJUMP */
410 0
411 };
412
413 void
414 command_error (func, code, e, flags)
415 const char *func;
416 int code, e, flags; /* flags currently unused */
417 {
418 if (code > CMDERR_LAST)
419 code = CMDERR_DEFAULT;
420
421 programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
422 }
423
424 char *
425 command_errstr (code)
426 int code;
427 {
428 if (code > CMDERR_LAST)
429 code = CMDERR_DEFAULT;
430
431 return (_(cmd_error_table[code]));
432 }
433
434 #ifdef ARRAY_VARS
435 void
436 err_badarraysub (s)
437 const char *s;
438 {
439 report_error ("%s: %s", s, _(bash_badsub_errmsg));
440 }
441 #endif
442
443 void
444 err_unboundvar (s)
445 const char *s;
446 {
447 report_error (_("%s: unbound variable"), s);
448 }
449
450 void
451 err_readonly (s)
452 const char *s;
453 {
454 report_error (_("%s: readonly variable"), s);
455 }