]> git.ipfire.org Git - thirdparty/bash.git/blame - error.c
Bash-4.2 patch 22
[thirdparty/bash.git] / error.c
CommitLineData
726f6388 1/* error.c -- Functions for handling errors. */
3185942a
JA
2
3/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
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.
726f6388 11
3185942a
JA
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.
726f6388 16
3185942a
JA
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*/
726f6388 20
ccc6cda3
JA
21#include "config.h"
22
d166f048 23#include "bashtypes.h"
726f6388
JA
24#include <fcntl.h>
25
ccc6cda3
JA
26#if defined (HAVE_UNISTD_H)
27# include <unistd.h>
28#endif
29
30#if defined (PREFER_STDARG)
31# include <stdarg.h>
32#else
7117c2d2 33# include <varargs.h>
726f6388
JA
34#endif
35
d166f048
JA
36#include <stdio.h>
37
726f6388
JA
38#include <errno.h>
39#if !defined (errno)
40extern int errno;
41#endif /* !errno */
42
43#include "bashansi.h"
b80f6443
JA
44#include "bashintl.h"
45
46#include "shell.h"
726f6388 47#include "flags.h"
ccc6cda3 48#include "input.h"
726f6388 49
ccc6cda3
JA
50#if defined (HISTORY)
51# include "bashhist.h"
52#endif
53
7117c2d2
JA
54extern int executing_line_number __P((void));
55
0001803f 56extern int last_command_exit_value;
726f6388 57extern char *shell_name;
726f6388
JA
58#if defined (JOB_CONTROL)
59extern pid_t shell_pgrp;
f73dda09 60extern int give_terminal_to __P((pid_t, int));
726f6388
JA
61#endif /* JOB_CONTROL */
62
b80f6443 63#if defined (ARRAY_VARS)
3185942a 64extern const char * const bash_badsub_errmsg;
b80f6443
JA
65#endif
66
7117c2d2
JA
67static void error_prolog __P((int));
68
ccc6cda3
JA
69/* The current maintainer of the shell. You change this in the
70 Makefile. */
71#if !defined (MAINTAINER)
bb70624e 72#define MAINTAINER "bash-maintainers@gnu.org"
ccc6cda3
JA
73#endif
74
3185942a 75const char * const the_current_maintainer = MAINTAINER;
ccc6cda3 76
b80f6443
JA
77int gnu_error_format = 0;
78
7117c2d2
JA
79static void
80error_prolog (print_lineno)
81 int print_lineno;
82{
b80f6443 83 char *ename;
7117c2d2
JA
84 int line;
85
b80f6443
JA
86 ename = get_name_for_error ();
87 line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
7117c2d2 88
b80f6443 89 if (line > 0)
3185942a 90 fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line);
b80f6443
JA
91 else
92 fprintf (stderr, "%s: ", ename);
7117c2d2
JA
93}
94
726f6388
JA
95/* Return the name of the shell or the shell script for error reporting. */
96char *
97get_name_for_error ()
98{
ccc6cda3 99 char *name;
b80f6443
JA
100#if defined (ARRAY_VARS)
101 SHELL_VAR *bash_source_v;
102 ARRAY *bash_source_a;
103#endif
726f6388 104
ccc6cda3
JA
105 name = (char *)NULL;
106 if (interactive_shell == 0)
b80f6443
JA
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);
3185942a 113 if (name == 0 || *name == '\0') /* XXX - was just name == 0 */
b80f6443
JA
114#endif
115 name = dollar_vars[0];
116 }
ccc6cda3 117 if (name == 0 && shell_name && *shell_name)
726f6388 118 name = base_pathname (shell_name);
ccc6cda3
JA
119 if (name == 0)
120#if defined (PROGRAM)
121 name = PROGRAM;
122#else
726f6388 123 name = "bash";
ccc6cda3 124#endif
726f6388
JA
125
126 return (name);
127}
128
ccc6cda3
JA
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. */
726f6388
JA
132void
133file_error (filename)
f73dda09 134 const char *filename;
726f6388
JA
135{
136 report_error ("%s: %s", filename, strerror (errno));
137}
138
726f6388 139void
ccc6cda3
JA
140#if defined (PREFER_STDARG)
141programming_error (const char *format, ...)
142#else
143programming_error (format, va_alist)
144 const char *format;
726f6388 145 va_dcl
ccc6cda3 146#endif
726f6388
JA
147{
148 va_list args;
ccc6cda3 149 char *h;
726f6388
JA
150
151#if defined (JOB_CONTROL)
f73dda09 152 give_terminal_to (shell_pgrp, 0);
726f6388
JA
153#endif /* JOB_CONTROL */
154
7117c2d2 155 SH_VA_START (args, format);
ccc6cda3 156
726f6388
JA
157 vfprintf (stderr, format, args);
158 fprintf (stderr, "\n");
159 va_end (args);
160
ccc6cda3
JA
161#if defined (HISTORY)
162 if (remember_on_history)
163 {
164 h = last_history_line ();
b80f6443 165 fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
ccc6cda3
JA
166 }
167#endif
168
bb70624e 169#if 0
d166f048 170 fprintf (stderr, "Report this to %s\n", the_current_maintainer);
bb70624e
JA
171#endif
172
b80f6443 173 fprintf (stderr, _("Aborting..."));
726f6388 174 fflush (stderr);
ccc6cda3 175
726f6388
JA
176 abort ();
177}
178
7117c2d2
JA
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. */
726f6388 183void
ccc6cda3
JA
184#if defined (PREFER_STDARG)
185report_error (const char *format, ...)
186#else
187report_error (format, va_alist)
188 const char *format;
726f6388 189 va_dcl
ccc6cda3 190#endif
726f6388
JA
191{
192 va_list args;
726f6388 193
7117c2d2 194 error_prolog (1);
ccc6cda3 195
7117c2d2 196 SH_VA_START (args, format);
ccc6cda3 197
726f6388
JA
198 vfprintf (stderr, format, args);
199 fprintf (stderr, "\n");
200
201 va_end (args);
202 if (exit_immediately_on_error)
b80f6443 203 exit_shell (1);
726f6388
JA
204}
205
206void
ccc6cda3
JA
207#if defined (PREFER_STDARG)
208fatal_error (const char *format, ...)
209#else
210fatal_error (format, va_alist)
211 const char *format;
726f6388 212 va_dcl
ccc6cda3 213#endif
726f6388
JA
214{
215 va_list args;
726f6388 216
7117c2d2 217 error_prolog (0);
ccc6cda3 218
7117c2d2 219 SH_VA_START (args, format);
ccc6cda3 220
726f6388
JA
221 vfprintf (stderr, format, args);
222 fprintf (stderr, "\n");
223
224 va_end (args);
7117c2d2 225 sh_exit (2);
726f6388
JA
226}
227
228void
ccc6cda3
JA
229#if defined (PREFER_STDARG)
230internal_error (const char *format, ...)
231#else
232internal_error (format, va_alist)
233 const char *format;
234 va_dcl
235#endif
236{
237 va_list args;
238
7117c2d2 239 error_prolog (1);
ccc6cda3 240
7117c2d2 241 SH_VA_START (args, format);
ccc6cda3
JA
242
243 vfprintf (stderr, format, args);
244 fprintf (stderr, "\n");
245
246 va_end (args);
247}
248
cce855bc
JA
249void
250#if defined (PREFER_STDARG)
251internal_warning (const char *format, ...)
252#else
253internal_warning (format, va_alist)
254 const char *format;
255 va_dcl
256#endif
257{
258 va_list args;
259
3185942a
JA
260 error_prolog (1);
261 fprintf (stderr, _("warning: "));
cce855bc 262
7117c2d2 263 SH_VA_START (args, format);
cce855bc
JA
264
265 vfprintf (stderr, format, args);
266 fprintf (stderr, "\n");
267
268 va_end (args);
269}
270
ccc6cda3
JA
271void
272#if defined (PREFER_STDARG)
273sys_error (const char *format, ...)
274#else
275sys_error (format, va_alist)
276 const char *format;
726f6388 277 va_dcl
ccc6cda3 278#endif
726f6388 279{
7117c2d2 280 int e;
726f6388 281 va_list args;
726f6388 282
7117c2d2
JA
283 e = errno;
284 error_prolog (0);
ccc6cda3 285
7117c2d2 286 SH_VA_START (args, format);
ccc6cda3
JA
287
288 vfprintf (stderr, format, args);
7117c2d2 289 fprintf (stderr, ": %s\n", strerror (e));
ccc6cda3
JA
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. */
302void
303#if defined (PREFER_STDARG)
304parser_error (int lineno, const char *format, ...)
305#else
306parser_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 ();
7117c2d2 316 iname = yy_input_name ();
ccc6cda3
JA
317
318 if (interactive)
319 fprintf (stderr, "%s: ", ename);
320 else if (interactive_shell)
3185942a 321 fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
ccc6cda3 322 else if (STREQ (ename, iname))
3185942a 323 fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno);
ccc6cda3 324 else
3185942a 325 fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
ccc6cda3 326
7117c2d2 327 SH_VA_START (args, format);
ccc6cda3 328
726f6388
JA
329 vfprintf (stderr, format, args);
330 fprintf (stderr, "\n");
331
332 va_end (args);
ccc6cda3
JA
333
334 if (exit_immediately_on_error)
0001803f 335 exit_shell (last_command_exit_value = 2);
726f6388
JA
336}
337
28ef6c31 338#ifdef DEBUG
ccc6cda3
JA
339void
340#if defined (PREFER_STDARG)
341itrace (const char *format, ...)
342#else
343itrace (format, va_alist)
344 const char *format;
726f6388 345 va_dcl
ccc6cda3 346#endif
726f6388
JA
347{
348 va_list args;
726f6388 349
f73dda09 350 fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
ccc6cda3 351
7117c2d2 352 SH_VA_START (args, format);
ccc6cda3 353
726f6388
JA
354 vfprintf (stderr, format, args);
355 fprintf (stderr, "\n");
356
357 va_end (args);
358
359 fflush(stderr);
360}
361
726f6388
JA
362/* A trace function for silent debugging -- doesn't require a control
363 terminal. */
ccc6cda3
JA
364void
365#if defined (PREFER_STDARG)
366trace (const char *format, ...)
367#else
368trace (format, va_alist)
369 const char *format;
726f6388 370 va_dcl
ccc6cda3 371#endif
726f6388
JA
372{
373 va_list args;
726f6388
JA
374 static FILE *tracefp = (FILE *)NULL;
375
376 if (tracefp == NULL)
bb70624e 377 tracefp = fopen("/tmp/bash-trace.log", "a+");
726f6388
JA
378
379 if (tracefp == NULL)
380 tracefp = stderr;
381 else
382 fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
383
f73dda09 384 fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
726f6388 385
7117c2d2 386 SH_VA_START (args, format);
ccc6cda3 387
726f6388
JA
388 vfprintf (tracefp, format, args);
389 fprintf (tracefp, "\n");
390
391 va_end (args);
392
393 fflush(tracefp);
394}
ccc6cda3 395
28ef6c31 396#endif /* DEBUG */
b72432fd 397
7117c2d2
JA
398/* **************************************************************** */
399/* */
400/* Common error reporting */
401/* */
402/* **************************************************************** */
403
404
3185942a 405static const char * const cmd_error_table[] = {
b80f6443
JA
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 */
b72432fd
JA
410 0
411};
412
413void
414command_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
b80f6443 421 programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
b72432fd
JA
422}
423
424char *
425command_errstr (code)
426 int code;
427{
428 if (code > CMDERR_LAST)
429 code = CMDERR_DEFAULT;
430
b80f6443 431 return (_(cmd_error_table[code]));
b72432fd 432}
7117c2d2
JA
433
434#ifdef ARRAY_VARS
435void
436err_badarraysub (s)
437 const char *s;
438{
b80f6443 439 report_error ("%s: %s", s, _(bash_badsub_errmsg));
7117c2d2
JA
440}
441#endif
442
443void
444err_unboundvar (s)
445 const char *s;
446{
b80f6443 447 report_error (_("%s: unbound variable"), s);
7117c2d2
JA
448}
449
450void
451err_readonly (s)
452 const char *s;
453{
b80f6443 454 report_error (_("%s: readonly variable"), s);
7117c2d2 455}