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