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