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