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