#include "config.h"
#include "bashtypes.h"
#include <fcntl.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# include <varargs.h>
#endif
#include <stdio.h>
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif
#include "bashansi.h"
#include "flags.h"
#include "error.h"
#include "command.h"
#include "general.h"
#include "externs.h"
#include "input.h"
#if defined (HISTORY)
# include "bashhist.h"
#endif
extern int executing_line_number __P((void));
extern int interactive_shell, interactive, startup_state;
extern char *dollar_vars[];
extern char *shell_name;
#if defined (JOB_CONTROL)
extern pid_t shell_pgrp;
extern int give_terminal_to __P((pid_t, int));
#endif
static void error_prolog __P((int));
#if !defined (MAINTAINER)
#define MAINTAINER "bash-maintainers@gnu.org"
#endif
char *the_current_maintainer = MAINTAINER;
static void
error_prolog (print_lineno)
int print_lineno;
{
int line;
fprintf (stderr, "%s: ", get_name_for_error ());
if (print_lineno && interactive_shell == 0)
{
line = executing_line_number ();
if (line > 0)
fprintf (stderr, "line %d: ", line);
}
}
char *
get_name_for_error ()
{
char *name;
name = (char *)NULL;
if (interactive_shell == 0)
name = dollar_vars[0];
if (name == 0 && shell_name && *shell_name)
name = base_pathname (shell_name);
if (name == 0)
#if defined (PROGRAM)
name = PROGRAM;
#else
name = "bash";
#endif
return (name);
}
void
file_error (filename)
const char *filename;
{
report_error ("%s: %s", filename, strerror (errno));
}
void
#if defined (PREFER_STDARG)
programming_error (const char *format, ...)
#else
programming_error (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
char *h;
#if defined (JOB_CONTROL)
give_terminal_to (shell_pgrp, 0);
#endif
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
#if defined (HISTORY)
if (remember_on_history)
{
h = last_history_line ();
fprintf (stderr, "last command: %s\n", h ? h : "(null)");
}
#endif
#if 0
fprintf (stderr, "Report this to %s\n", the_current_maintainer);
#endif
fprintf (stderr, "Stopping myself...");
fflush (stderr);
abort ();
}
void
#if defined (PREFER_STDARG)
report_error (const char *format, ...)
#else
report_error (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
error_prolog (1);
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
if (exit_immediately_on_error)
sh_exit (1);
}
void
#if defined (PREFER_STDARG)
fatal_error (const char *format, ...)
#else
fatal_error (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
error_prolog (0);
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
sh_exit (2);
}
void
#if defined (PREFER_STDARG)
internal_error (const char *format, ...)
#else
internal_error (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
error_prolog (1);
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
}
void
#if defined (PREFER_STDARG)
internal_warning (const char *format, ...)
#else
internal_warning (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
fprintf (stderr, "%s: warning: ", get_name_for_error ());
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
}
void
#if defined (PREFER_STDARG)
sys_error (const char *format, ...)
#else
sys_error (format, va_alist)
const char *format;
va_dcl
#endif
{
int e;
va_list args;
e = errno;
error_prolog (0);
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, ": %s\n", strerror (e));
va_end (args);
}
void
#if defined (PREFER_STDARG)
parser_error (int lineno, const char *format, ...)
#else
parser_error (lineno, format, va_alist)
int lineno;
const char *format;
va_dcl
#endif
{
va_list args;
char *ename, *iname;
ename = get_name_for_error ();
iname = yy_input_name ();
if (interactive)
fprintf (stderr, "%s: ", ename);
else if (interactive_shell)
fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
else if (STREQ (ename, iname))
fprintf (stderr, "%s: line %d: ", ename, lineno);
else
fprintf (stderr, "%s: %s: line %d: ", ename, iname, lineno);
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
if (exit_immediately_on_error)
sh_exit (2);
}
#ifdef DEBUG
void
#if defined (PREFER_STDARG)
itrace (const char *format, ...)
#else
itrace (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
SH_VA_START (args, format);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
fflush(stderr);
}
void
#if defined (PREFER_STDARG)
trace (const char *format, ...)
#else
trace (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
static FILE *tracefp = (FILE *)NULL;
if (tracefp == NULL)
tracefp = fopen("/tmp/bash-trace.log", "a+");
if (tracefp == NULL)
tracefp = stderr;
else
fcntl (fileno (tracefp), F_SETFD, 1);
fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
SH_VA_START (args, format);
vfprintf (tracefp, format, args);
fprintf (tracefp, "\n");
va_end (args);
fflush(tracefp);
}
#endif
static char *cmd_error_table[] = {
"unknown command error",
"bad command type",
"bad connector",
"bad jump",
0
};
void
command_error (func, code, e, flags)
const char *func;
int code, e, flags;
{
if (code > CMDERR_LAST)
code = CMDERR_DEFAULT;
programming_error ("%s: %s: %d", func, cmd_error_table[code], e);
}
char *
command_errstr (code)
int code;
{
if (code > CMDERR_LAST)
code = CMDERR_DEFAULT;
return (cmd_error_table[code]);
}
#ifdef ARRAY_VARS
void
err_badarraysub (s)
const char *s;
{
report_error ("%s: bad array subscript", s);
}
#endif
void
err_unboundvar (s)
const char *s;
{
report_error ("%s: unbound variable", s);
}
void
err_readonly (s)
const char *s;
{
report_error ("%s: readonly variable", s);
}