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