]> git.ipfire.org Git - thirdparty/bash.git/blob - error.c
Imported from ../bash-3.2.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 char *shell_name;
56 #if defined (JOB_CONTROL)
57 extern pid_t shell_pgrp;
58 extern int give_terminal_to __P((pid_t, int));
59 #endif /* JOB_CONTROL */
60
61 #if defined (ARRAY_VARS)
62 extern char *bash_badsub_errmsg;
63 #endif
64
65 static void error_prolog __P((int));
66
67 /* The current maintainer of the shell. You change this in the
68 Makefile. */
69 #if !defined (MAINTAINER)
70 #define MAINTAINER "bash-maintainers@gnu.org"
71 #endif
72
73 char *the_current_maintainer = MAINTAINER;
74
75 int gnu_error_format = 0;
76
77 static void
78 error_prolog (print_lineno)
79 int print_lineno;
80 {
81 char *ename;
82 int line;
83
84 ename = get_name_for_error ();
85 line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
86
87 if (line > 0)
88 fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : " line ", line);
89 else
90 fprintf (stderr, "%s: ", ename);
91 }
92
93 /* Return the name of the shell or the shell script for error reporting. */
94 char *
95 get_name_for_error ()
96 {
97 char *name;
98 #if defined (ARRAY_VARS)
99 SHELL_VAR *bash_source_v;
100 ARRAY *bash_source_a;
101 #endif
102
103 name = (char *)NULL;
104 if (interactive_shell == 0)
105 {
106 #if defined (ARRAY_VARS)
107 bash_source_v = find_variable ("BASH_SOURCE");
108 if (bash_source_v && array_p (bash_source_v) &&
109 (bash_source_a = array_cell (bash_source_v)))
110 name = array_reference (bash_source_a, 0);
111 if (name == 0)
112 #endif
113 name = dollar_vars[0];
114 }
115 if (name == 0 && shell_name && *shell_name)
116 name = base_pathname (shell_name);
117 if (name == 0)
118 #if defined (PROGRAM)
119 name = PROGRAM;
120 #else
121 name = "bash";
122 #endif
123
124 return (name);
125 }
126
127 /* Report an error having to do with FILENAME. This does not use
128 sys_error so the filename is not interpreted as a printf-style
129 format string. */
130 void
131 file_error (filename)
132 const char *filename;
133 {
134 report_error ("%s: %s", filename, strerror (errno));
135 }
136
137 void
138 #if defined (PREFER_STDARG)
139 programming_error (const char *format, ...)
140 #else
141 programming_error (format, va_alist)
142 const char *format;
143 va_dcl
144 #endif
145 {
146 va_list args;
147 char *h;
148
149 #if defined (JOB_CONTROL)
150 give_terminal_to (shell_pgrp, 0);
151 #endif /* JOB_CONTROL */
152
153 SH_VA_START (args, format);
154
155 vfprintf (stderr, format, args);
156 fprintf (stderr, "\n");
157 va_end (args);
158
159 #if defined (HISTORY)
160 if (remember_on_history)
161 {
162 h = last_history_line ();
163 fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
164 }
165 #endif
166
167 #if 0
168 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
169 #endif
170
171 fprintf (stderr, _("Aborting..."));
172 fflush (stderr);
173
174 abort ();
175 }
176
177 /* Print an error message and, if `set -e' has been executed, exit the
178 shell. Used in this file by file_error and programming_error. Used
179 outside this file mostly to report substitution and expansion errors,
180 and for bad invocation options. */
181 void
182 #if defined (PREFER_STDARG)
183 report_error (const char *format, ...)
184 #else
185 report_error (format, va_alist)
186 const char *format;
187 va_dcl
188 #endif
189 {
190 va_list args;
191
192 error_prolog (1);
193
194 SH_VA_START (args, format);
195
196 vfprintf (stderr, format, args);
197 fprintf (stderr, "\n");
198
199 va_end (args);
200 if (exit_immediately_on_error)
201 exit_shell (1);
202 }
203
204 void
205 #if defined (PREFER_STDARG)
206 fatal_error (const char *format, ...)
207 #else
208 fatal_error (format, va_alist)
209 const char *format;
210 va_dcl
211 #endif
212 {
213 va_list args;
214
215 error_prolog (0);
216
217 SH_VA_START (args, format);
218
219 vfprintf (stderr, format, args);
220 fprintf (stderr, "\n");
221
222 va_end (args);
223 sh_exit (2);
224 }
225
226 void
227 #if defined (PREFER_STDARG)
228 internal_error (const char *format, ...)
229 #else
230 internal_error (format, va_alist)
231 const char *format;
232 va_dcl
233 #endif
234 {
235 va_list args;
236
237 error_prolog (1);
238
239 SH_VA_START (args, format);
240
241 vfprintf (stderr, format, args);
242 fprintf (stderr, "\n");
243
244 va_end (args);
245 }
246
247 void
248 #if defined (PREFER_STDARG)
249 internal_warning (const char *format, ...)
250 #else
251 internal_warning (format, va_alist)
252 const char *format;
253 va_dcl
254 #endif
255 {
256 va_list args;
257
258 fprintf (stderr, _("%s: warning: "), get_name_for_error ());
259
260 SH_VA_START (args, format);
261
262 vfprintf (stderr, format, args);
263 fprintf (stderr, "\n");
264
265 va_end (args);
266 }
267
268 void
269 #if defined (PREFER_STDARG)
270 sys_error (const char *format, ...)
271 #else
272 sys_error (format, va_alist)
273 const char *format;
274 va_dcl
275 #endif
276 {
277 int e;
278 va_list args;
279
280 e = errno;
281 error_prolog (0);
282
283 SH_VA_START (args, format);
284
285 vfprintf (stderr, format, args);
286 fprintf (stderr, ": %s\n", strerror (e));
287
288 va_end (args);
289 }
290
291 /* An error from the parser takes the general form
292
293 shell_name: input file name: line number: message
294
295 The input file name and line number are omitted if the shell is
296 currently interactive. If the shell is not currently interactive,
297 the input file name is inserted only if it is different from the
298 shell name. */
299 void
300 #if defined (PREFER_STDARG)
301 parser_error (int lineno, const char *format, ...)
302 #else
303 parser_error (lineno, format, va_alist)
304 int lineno;
305 const char *format;
306 va_dcl
307 #endif
308 {
309 va_list args;
310 char *ename, *iname;
311
312 ename = get_name_for_error ();
313 iname = yy_input_name ();
314
315 if (interactive)
316 fprintf (stderr, "%s: ", ename);
317 else if (interactive_shell)
318 fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : " line ", lineno);
319 else if (STREQ (ename, iname))
320 fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : " line ", lineno);
321 else
322 fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : " line ", lineno);
323
324 SH_VA_START (args, format);
325
326 vfprintf (stderr, format, args);
327 fprintf (stderr, "\n");
328
329 va_end (args);
330
331 if (exit_immediately_on_error)
332 exit_shell (2);
333 }
334
335 #ifdef DEBUG
336 void
337 #if defined (PREFER_STDARG)
338 itrace (const char *format, ...)
339 #else
340 itrace (format, va_alist)
341 const char *format;
342 va_dcl
343 #endif
344 {
345 va_list args;
346
347 fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
348
349 SH_VA_START (args, format);
350
351 vfprintf (stderr, format, args);
352 fprintf (stderr, "\n");
353
354 va_end (args);
355
356 fflush(stderr);
357 }
358
359 /* A trace function for silent debugging -- doesn't require a control
360 terminal. */
361 void
362 #if defined (PREFER_STDARG)
363 trace (const char *format, ...)
364 #else
365 trace (format, va_alist)
366 const char *format;
367 va_dcl
368 #endif
369 {
370 va_list args;
371 static FILE *tracefp = (FILE *)NULL;
372
373 if (tracefp == NULL)
374 tracefp = fopen("/tmp/bash-trace.log", "a+");
375
376 if (tracefp == NULL)
377 tracefp = stderr;
378 else
379 fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
380
381 fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
382
383 SH_VA_START (args, format);
384
385 vfprintf (tracefp, format, args);
386 fprintf (tracefp, "\n");
387
388 va_end (args);
389
390 fflush(tracefp);
391 }
392
393 #endif /* DEBUG */
394
395 /* **************************************************************** */
396 /* */
397 /* Common error reporting */
398 /* */
399 /* **************************************************************** */
400
401
402 static char *cmd_error_table[] = {
403 N_("unknown command error"), /* CMDERR_DEFAULT */
404 N_("bad command type"), /* CMDERR_BADTYPE */
405 N_("bad connector"), /* CMDERR_BADCONN */
406 N_("bad jump"), /* CMDERR_BADJUMP */
407 0
408 };
409
410 void
411 command_error (func, code, e, flags)
412 const char *func;
413 int code, e, flags; /* flags currently unused */
414 {
415 if (code > CMDERR_LAST)
416 code = CMDERR_DEFAULT;
417
418 programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
419 }
420
421 char *
422 command_errstr (code)
423 int code;
424 {
425 if (code > CMDERR_LAST)
426 code = CMDERR_DEFAULT;
427
428 return (_(cmd_error_table[code]));
429 }
430
431 #ifdef ARRAY_VARS
432 void
433 err_badarraysub (s)
434 const char *s;
435 {
436 report_error ("%s: %s", s, _(bash_badsub_errmsg));
437 }
438 #endif
439
440 void
441 err_unboundvar (s)
442 const char *s;
443 {
444 report_error (_("%s: unbound variable"), s);
445 }
446
447 void
448 err_readonly (s)
449 const char *s;
450 {
451 report_error (_("%s: readonly variable"), s);
452 }