/* error.c -- Functions for handling errors. */ /* Copyright (C) 1993 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #if defined (HAVE_VFPRINTF) #include #endif #include #if !defined (errno) extern int errno; #endif /* !errno */ #include "bashansi.h" #include "flags.h" #include "error.h" #include "command.h" #include "general.h" extern int interactive_shell; extern char *dollar_vars[]; extern char *shell_name; extern char *the_current_maintainer; #if defined (JOB_CONTROL) extern pid_t shell_pgrp; #endif /* JOB_CONTROL */ /* Return the name of the shell or the shell script for error reporting. */ char * get_name_for_error () { char *name = (char *) NULL; if (!interactive_shell) name = dollar_vars[0]; if (!name && shell_name && *shell_name) name = base_pathname (shell_name); if (!name) name = "bash"; return (name); } /* Report an error having to do with FILENAME. */ void file_error (filename) char *filename; { report_error ("%s: %s", filename, strerror (errno)); } #if !defined (HAVE_VFPRINTF) void programming_error (reason, arg1, arg2, arg3, arg4, arg5) char *reason; { #if defined (JOB_CONTROL) give_terminal_to (shell_pgrp); #endif /* JOB_CONTROL */ report_error (reason, arg1, arg2); fprintf (stderr, "Report this to %s\n", the_current_maintainer); fprintf (stderr, "Stopping myself..."); fflush (stderr); abort (); } void report_error (format, arg1, arg2, arg3, arg4, arg5) char *format; { fprintf (stderr, "%s: ", get_name_for_error ()); fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); fprintf (stderr, "\n"); if (exit_immediately_on_error) exit (1); } void fatal_error (format, arg1, arg2, arg3, arg4, arg5) char *format; { fprintf (stderr, "%s: ", get_name_for_error ()); fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); fprintf (stderr, "\n"); exit (2); } void internal_error (format, arg1, arg2, arg3, arg4, arg5) char *format; { fprintf (stderr, "%s: ", get_name_for_error ()); fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); fprintf (stderr, "\n"); } #else /* We have VARARGS support, so use it. */ void programming_error (va_alist) va_dcl { va_list args; char *format; #if defined (JOB_CONTROL) give_terminal_to (shell_pgrp); #endif /* JOB_CONTROL */ va_start (args); format = va_arg (args, char *); vfprintf (stderr, format, args); fprintf (stderr, "\n"); va_end (args); fprintf (stderr, "Tell %s to fix this someday.\n", the_current_maintainer); fprintf (stderr, "Stopping myself..."); fflush (stderr); abort (); } void report_error (va_alist) va_dcl { va_list args; char *format; fprintf (stderr, "%s: ", get_name_for_error ()); va_start (args); format = va_arg (args, char *); vfprintf (stderr, format, args); fprintf (stderr, "\n"); va_end (args); if (exit_immediately_on_error) exit (1); } void fatal_error (va_alist) va_dcl { va_list args; char *format; fprintf (stderr, "%s: ", get_name_for_error ()); va_start (args); format = va_arg (args, char *); vfprintf (stderr, format, args); fprintf (stderr, "\n"); va_end (args); exit (2); } void internal_error (va_alist) va_dcl { va_list args; char *format; fprintf (stderr, "%s: ", get_name_for_error ()); va_start (args); format = va_arg (args, char *); vfprintf (stderr, format, args); fprintf (stderr, "\n"); va_end (args); } itrace (va_alist) va_dcl { va_list args; char *format; fprintf(stderr, "TRACE: pid %d: ", getpid()); va_start (args); format = va_arg (args, char *); vfprintf (stderr, format, args); fprintf (stderr, "\n"); va_end (args); fflush(stderr); } #if 0 /* A trace function for silent debugging -- doesn't require a control terminal. */ trace (va_alist) va_dcl { va_list args; char *format; static FILE *tracefp = (FILE *)NULL; if (tracefp == NULL) tracefp = fopen("/usr/tmp/bash-trace.log", "a+"); if (tracefp == NULL) tracefp = stderr; else fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */ fprintf(tracefp, "TRACE: pid %d: ", getpid()); va_start (args); format = va_arg (args, char *); vfprintf (tracefp, format, args); fprintf (tracefp, "\n"); va_end (args); fflush(tracefp); } #endif #endif /* HAVE_VFPRINTF */