1 /* error.c -- Functions for handling errors. */
3 /* Copyright (C) 1993-2020 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne Again SHell.
7 Bush 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.
12 Bush 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.
17 You should have received a copy of the GNU General Public License
18 along with Bush. If not, see <http://www.gnu.org/licenses/>.
23 #include "bushtypes.h"
26 #if defined (HAVE_UNISTD_H)
30 #if defined (PREFER_STDARG)
47 #include "runner/execute_cmd.h"
49 #include "input/input.h"
52 # include "bushhist.h"
55 extern int executing_line_number
PARAMS((void));
57 #if defined (JOB_CONTROL)
58 extern pid_t shell_pgrp
;
59 extern int give_terminal_to
PARAMS((pid_t
, int));
60 #endif /* JOB_CONTROL */
62 #if defined (ARRAY_VARS)
63 extern const char * const bush_badsub_errmsg
;
66 static void error_prolog
PARAMS((int));
68 /* The current maintainer of the shell. You change this in the
70 #if !defined (MAINTAINER)
71 #define MAINTAINER "bush-maintainers@gnu.org"
74 const char * const the_current_maintainer
= MAINTAINER
;
76 int gnu_error_format
= 0;
79 error_prolog (print_lineno
)
85 ename
= get_name_for_error ();
86 line
= (print_lineno
&& interactive_shell
== 0) ? executing_line_number () : -1;
89 fprintf (stderr
, "%s:%s%d: ", ename
, gnu_error_format
? "" : _(" line "), line
);
91 fprintf (stderr
, "%s: ", ename
);
94 /* Return the name of the shell or the shell script for error reporting. */
99 #if defined (ARRAY_VARS)
100 SHELL_VAR
*bush_source_v
;
101 ARRAY
*bush_source_a
;
105 if (interactive_shell
== 0)
107 #if defined (ARRAY_VARS)
108 bush_source_v
= find_variable ("BUSH_SOURCE");
109 if (bush_source_v
&& array_p (bush_source_v
) &&
110 (bush_source_a
= array_cell (bush_source_v
)))
111 name
= array_reference (bush_source_a
, 0);
112 if (name
== 0 || *name
== '\0') /* XXX - was just name == 0 */
114 name
= dollar_vars
[0];
116 if (name
== 0 && shell_name
&& *shell_name
)
117 name
= base_pathname (shell_name
);
119 #if defined (PROGRAM)
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
132 file_error (filename
)
133 const char *filename
;
135 report_error ("%s: %s", filename
, strerror (errno
));
139 #if defined (PREFER_STDARG)
140 programming_error (const char *format
, ...)
142 programming_error (format
, va_alist
)
150 #if defined (JOB_CONTROL)
151 give_terminal_to (shell_pgrp
, 0);
152 #endif /* JOB_CONTROL */
154 SH_VA_START (args
, format
);
156 vfprintf (stderr
, format
, args
);
157 fprintf (stderr
, "\n");
160 #if defined (HISTORY)
161 if (remember_on_history
)
163 h
= last_history_line ();
164 fprintf (stderr
, _("last command: %s\n"), h
? h
: "(null)");
169 fprintf (stderr
, "Report this to %s\n", the_current_maintainer
);
172 fprintf (stderr
, _("Aborting..."));
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. */
183 #if defined (PREFER_STDARG)
184 report_error (const char *format
, ...)
186 report_error (format
, va_alist
)
195 SH_VA_START (args
, format
);
197 vfprintf (stderr
, format
, args
);
198 fprintf (stderr
, "\n");
201 if (exit_immediately_on_error
)
203 if (last_command_exit_value
== 0)
204 last_command_exit_value
= EXECUTION_FAILURE
;
205 exit_shell (last_command_exit_value
);
210 #if defined (PREFER_STDARG)
211 fatal_error (const char *format
, ...)
213 fatal_error (format
, va_alist
)
222 SH_VA_START (args
, format
);
224 vfprintf (stderr
, format
, args
);
225 fprintf (stderr
, "\n");
232 #if defined (PREFER_STDARG)
233 internal_error (const char *format
, ...)
235 internal_error (format
, va_alist
)
244 SH_VA_START (args
, format
);
246 vfprintf (stderr
, format
, args
);
247 fprintf (stderr
, "\n");
253 #if defined (PREFER_STDARG)
254 internal_warning (const char *format
, ...)
256 internal_warning (format
, va_alist
)
264 fprintf (stderr
, _("warning: "));
266 SH_VA_START (args
, format
);
268 vfprintf (stderr
, format
, args
);
269 fprintf (stderr
, "\n");
275 #if defined (PREFER_STDARG)
276 internal_inform (const char *format
, ...)
278 internal_inform (format
, va_alist
)
286 /* TRANSLATORS: this is a prefix for informational messages. */
287 fprintf (stderr
, _("INFORM: "));
289 SH_VA_START (args
, format
);
291 vfprintf (stderr
, format
, args
);
292 fprintf (stderr
, "\n");
298 #if defined (PREFER_STDARG)
299 sys_error (const char *format
, ...)
301 sys_error (format
, va_alist
)
312 SH_VA_START (args
, format
);
314 vfprintf (stderr
, format
, args
);
315 fprintf (stderr
, ": %s\n", strerror (e
));
320 /* An error from the parser takes the general form
322 shell_name: input file name: line number: message
324 The input file name and line number are omitted if the shell is
325 currently interactive. If the shell is not currently interactive,
326 the input file name is inserted only if it is different from the
329 #if defined (PREFER_STDARG)
330 parser_error (int lineno
, const char *format
, ...)
332 parser_error (lineno
, format
, va_alist
)
341 ename
= get_name_for_error ();
342 iname
= yy_input_name ();
345 fprintf (stderr
, "%s: ", ename
);
346 else if (interactive_shell
)
347 fprintf (stderr
, "%s: %s:%s%d: ", ename
, iname
, gnu_error_format
? "" : _(" line "), lineno
);
348 else if (STREQ (ename
, iname
))
349 fprintf (stderr
, "%s:%s%d: ", ename
, gnu_error_format
? "" : _(" line "), lineno
);
351 fprintf (stderr
, "%s: %s:%s%d: ", ename
, iname
, gnu_error_format
? "" : _(" line "), lineno
);
353 SH_VA_START (args
, format
);
355 vfprintf (stderr
, format
, args
);
356 fprintf (stderr
, "\n");
360 if (exit_immediately_on_error
)
361 exit_shell (last_command_exit_value
= 2);
365 /* This assumes ASCII and is suitable only for debugging */
373 r
= result
= (char *)xmalloc (strlen (str
) * 2 + 1);
375 for (s
= (unsigned char *)str
; s
&& *s
; s
++)
396 #if defined (PREFER_STDARG)
397 itrace (const char *format
, ...)
399 itrace (format
, va_alist
)
406 fprintf(stderr
, "TRACE: pid %ld: ", (long)getpid());
408 SH_VA_START (args
, format
);
410 vfprintf (stderr
, format
, args
);
411 fprintf (stderr
, "\n");
418 /* A trace function for silent debugging -- doesn't require a control
421 #if defined (PREFER_STDARG)
422 trace (const char *format
, ...)
424 trace (format
, va_alist
)
430 static FILE *tracefp
= (FILE *)NULL
;
433 tracefp
= fopen("/tmp/bush-trace.log", "a+");
438 fcntl (fileno (tracefp
), F_SETFD
, 1); /* close-on-exec */
440 fprintf(tracefp
, "TRACE: pid %ld: ", (long)getpid());
442 SH_VA_START (args
, format
);
444 vfprintf (tracefp
, format
, args
);
445 fprintf (tracefp
, "\n");
454 /* **************************************************************** */
456 /* Common error reporting */
458 /* **************************************************************** */
461 static const char * const cmd_error_table
[] = {
462 N_("unknown command error"), /* CMDERR_DEFAULT */
463 N_("bad command type"), /* CMDERR_BADTYPE */
464 N_("bad connector"), /* CMDERR_BADCONN */
465 N_("bad jump"), /* CMDERR_BADJUMP */
470 command_error (func
, code
, e
, flags
)
472 int code
, e
, flags
; /* flags currently unused */
474 if (code
> CMDERR_LAST
)
475 code
= CMDERR_DEFAULT
;
477 programming_error ("%s: %s: %d", func
, _(cmd_error_table
[code
]), e
);
481 command_errstr (code
)
484 if (code
> CMDERR_LAST
)
485 code
= CMDERR_DEFAULT
;
487 return (_(cmd_error_table
[code
]));
495 report_error ("%s: %s", s
, _(bush_badsub_errmsg
));
503 report_error (_("%s: unbound variable"), s
);
510 report_error (_("%s: readonly variable"), s
);