LCOV - code coverage report
Current view: top level - bash-4.4.23 - error.c (source / functions) Hit Total Coverage
Test: cov-sh.info Lines: 71 131 54.2 %
Date: 2020-10-29 14:49:55 Functions: 8 16 50.0 %

          Line data    Source code
       1             : /* error.c -- Functions for handling errors. */
       2             : 
       3             : /* Copyright (C) 1993-2009 Free Software Foundation, Inc.
       4             : 
       5             :    This file is part of GNU Bash, the Bourne Again SHell.
       6             : 
       7             :    Bash is free software: you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation, either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    Bash is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "config.h"
      22             : 
      23             : #include "bashtypes.h"
      24             : #include <fcntl.h>
      25             : 
      26             : #if defined (HAVE_UNISTD_H)
      27             : #  include <unistd.h>
      28             : #endif
      29             : 
      30             : #if defined (PREFER_STDARG)
      31             : #  include <stdarg.h>
      32             : #else
      33             : #  include <varargs.h>
      34             : #endif
      35             : 
      36             : #include <stdio.h>
      37             : 
      38             : #include <errno.h>
      39             : #if !defined (errno)
      40             : extern int errno;
      41             : #endif /* !errno */
      42             : 
      43             : #include "bashansi.h"
      44             : #include "bashintl.h"
      45             : 
      46             : #include "shell.h"
      47             : #include "flags.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 last_command_exit_value;
      57             : extern char *shell_name;
      58             : #if defined (JOB_CONTROL)
      59             : extern pid_t shell_pgrp;
      60             : extern int give_terminal_to __P((pid_t, int));
      61             : #endif /* JOB_CONTROL */
      62             : 
      63             : #if defined (ARRAY_VARS)
      64             : extern const char * const bash_badsub_errmsg;
      65             : #endif
      66             : 
      67             : static void error_prolog __P((int));
      68             : 
      69             : /* The current maintainer of the shell.  You change this in the
      70             :    Makefile. */
      71             : #if !defined (MAINTAINER)
      72             : #define MAINTAINER "bash-maintainers@gnu.org"
      73             : #endif
      74             : 
      75             : const char * const the_current_maintainer = MAINTAINER;
      76             : 
      77             : int gnu_error_format = 0;
      78             : 
      79             : static void
      80     8278694 : error_prolog (print_lineno)
      81             :      int print_lineno;
      82             : {
      83     8278694 :   char *ename;
      84     8278694 :   int line;
      85             : 
      86     8278694 :   ename = get_name_for_error ();
      87     8278694 :   line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
      88             : 
      89     8278694 :   if (line > 0)
      90     8278694 :     fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line);
      91             :   else
      92           0 :     fprintf (stderr, "%s: ", ename);
      93     8278694 : }
      94             : 
      95             : /* Return the name of the shell or the shell script for error reporting. */
      96             : char *
      97    12468997 : get_name_for_error ()
      98             : {
      99    12468997 :   char *name;
     100             : #if defined (ARRAY_VARS)
     101    12468997 :   SHELL_VAR *bash_source_v;
     102    12468997 :   ARRAY *bash_source_a;
     103             : #endif
     104             : 
     105    12468997 :   name = (char *)NULL;
     106    12468997 :   if (interactive_shell == 0)
     107             :     {
     108             : #if defined (ARRAY_VARS)
     109    12468997 :       bash_source_v = find_variable ("BASH_SOURCE");
     110    12468997 :       if (bash_source_v && array_p (bash_source_v) &&
     111    12468997 :           (bash_source_a = array_cell (bash_source_v)))
     112    12468997 :         name = array_reference (bash_source_a, 0);
     113    12468997 :       if (name == 0 || *name == '\0')   /* XXX - was just name == 0 */
     114             : #endif
     115    12451174 :         name = dollar_vars[0];
     116             :     }
     117    12468997 :   if (name == 0 && shell_name && *shell_name)
     118           0 :     name = base_pathname (shell_name);
     119    12468997 :   if (name == 0)
     120             : #if defined (PROGRAM)
     121           0 :     name = PROGRAM;
     122             : #else
     123             :     name = "bash";
     124             : #endif
     125             : 
     126    12468997 :   return (name);
     127             : }
     128             : 
     129             : /* Report an error having to do with FILENAME.  This does not use
     130             :    sys_error so the filename is not interpreted as a printf-style
     131             :    format string. */
     132             : void
     133      421063 : file_error (filename)
     134             :      const char *filename;
     135             : {
     136      421063 :   report_error ("%s: %s", filename, strerror (errno));
     137      421063 : }
     138             : 
     139             : void
     140             : #if defined (PREFER_STDARG)
     141           0 : programming_error (const char *format, ...)
     142             : #else
     143             : programming_error (format, va_alist)
     144             :      const char *format;
     145             :      va_dcl
     146             : #endif
     147             : {
     148           0 :   va_list args;
     149             : 
     150             : #if defined (JOB_CONTROL)
     151           0 :   give_terminal_to (shell_pgrp, 0);
     152             : #endif /* JOB_CONTROL */
     153             : 
     154           0 :   SH_VA_START (args, format);
     155             : 
     156           0 :   vfprintf (stderr, format, args);
     157           0 :   fprintf (stderr, "\n");
     158           0 :   va_end (args);
     159             : 
     160             : #if defined (HISTORY)
     161             :   if (remember_on_history)
     162             :     {
     163             :       char *h = last_history_line ();
     164             :       fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
     165             :     }
     166             : #endif
     167             : 
     168             : #if 0
     169             :   fprintf (stderr, "Report this to %s\n", the_current_maintainer);
     170             : #endif
     171             : 
     172           0 :   fprintf (stderr, _("Aborting..."));
     173           0 :   fflush (stderr);
     174             : 
     175           0 :   abort ();
     176             : }
     177             : 
     178             : /* Print an error message and, if `set -e' has been executed, exit the
     179             :    shell.  Used in this file by file_error and programming_error.  Used
     180             :    outside this file mostly to report substitution and expansion errors,
     181             :    and for bad invocation options. */
     182             : void
     183             : #if defined (PREFER_STDARG)
     184      427897 : report_error (const char *format, ...)
     185             : #else
     186             : report_error (format, va_alist)
     187             :      const char *format;
     188             :      va_dcl
     189             : #endif
     190             : {
     191      427897 :   va_list args;
     192             : 
     193      427897 :   error_prolog (1);
     194             : 
     195      427897 :   SH_VA_START (args, format);
     196             : 
     197      427897 :   vfprintf (stderr, format, args);
     198      427897 :   fprintf (stderr, "\n");
     199             : 
     200      427897 :   va_end (args);
     201      427897 :   if (exit_immediately_on_error)
     202             :     {
     203           0 :       if (last_command_exit_value == 0)
     204           0 :         last_command_exit_value = 1;
     205           0 :       exit_shell (last_command_exit_value);
     206             :     }
     207      427897 : }
     208             : 
     209             : void
     210             : #if defined (PREFER_STDARG)
     211           0 : fatal_error (const char *format, ...)
     212             : #else
     213             : fatal_error (format, va_alist)
     214             :      const char *format;
     215             :      va_dcl
     216             : #endif
     217             : {
     218           0 :   va_list args;
     219             : 
     220           0 :   error_prolog (0);
     221             : 
     222           0 :   SH_VA_START (args, format);
     223             : 
     224           0 :   vfprintf (stderr, format, args);
     225           0 :   fprintf (stderr, "\n");
     226             : 
     227           0 :   va_end (args);
     228           0 :   sh_exit (2);
     229             : }
     230             : 
     231             : void
     232             : #if defined (PREFER_STDARG)
     233     7850512 : internal_error (const char *format, ...)
     234             : #else
     235             : internal_error (format, va_alist)
     236             :      const char *format;
     237             :      va_dcl
     238             : #endif
     239             : {
     240     7850512 :   va_list args;
     241             : 
     242     7850512 :   error_prolog (1);
     243             : 
     244     7850512 :   SH_VA_START (args, format);
     245             : 
     246     7850512 :   vfprintf (stderr, format, args);
     247     7850512 :   fprintf (stderr, "\n");
     248             : 
     249     7850512 :   va_end (args);
     250     7850512 : }
     251             : 
     252             : void
     253             : #if defined (PREFER_STDARG)
     254         285 : internal_warning (const char *format, ...)
     255             : #else
     256             : internal_warning (format, va_alist)
     257             :      const char *format;
     258             :      va_dcl
     259             : #endif
     260             : {
     261         285 :   va_list args;
     262             : 
     263         285 :   error_prolog (1);
     264         285 :   fprintf (stderr, _("warning: "));
     265             : 
     266         285 :   SH_VA_START (args, format);
     267             : 
     268         285 :   vfprintf (stderr, format, args);
     269         285 :   fprintf (stderr, "\n");
     270             : 
     271         285 :   va_end (args);
     272         285 : }
     273             : 
     274             : void
     275             : #if defined (PREFER_STDARG)
     276           0 : internal_inform (const char *format, ...)
     277             : #else
     278             : internal_inform (format, va_alist)
     279             :      const char *format;
     280             :      va_dcl
     281             : #endif
     282             : {
     283           0 :   va_list args;
     284             : 
     285           0 :   error_prolog (1);
     286             :   /* TRANSLATORS: this is a prefix for informational messages. */
     287           0 :   fprintf (stderr, _("INFORM: "));
     288             : 
     289           0 :   SH_VA_START (args, format);
     290             : 
     291           0 :   vfprintf (stderr, format, args);
     292           0 :   fprintf (stderr, "\n");
     293             : 
     294           0 :   va_end (args);
     295           0 : }
     296             : 
     297             : void
     298             : #if defined (PREFER_STDARG)
     299           0 : sys_error (const char *format, ...)
     300             : #else
     301             : sys_error (format, va_alist)
     302             :      const char *format;
     303             :      va_dcl
     304             : #endif
     305             : {
     306           0 :   int e;
     307           0 :   va_list args;
     308             : 
     309           0 :   e = errno;
     310           0 :   error_prolog (0);
     311             : 
     312           0 :   SH_VA_START (args, format);
     313             : 
     314           0 :   vfprintf (stderr, format, args);
     315           0 :   fprintf (stderr, ": %s\n", strerror (e));
     316             : 
     317           0 :   va_end (args);
     318           0 : }
     319             : 
     320             : /* An error from the parser takes the general form
     321             : 
     322             :         shell_name: input file name: line number: message
     323             : 
     324             :    The input file name and line number are omitted if the shell is
     325             :    currently interactive.  If the shell is not currently interactive,
     326             :    the input file name is inserted only if it is different from the
     327             :    shell name. */
     328             : void
     329             : #if defined (PREFER_STDARG)
     330     4076511 : parser_error (int lineno, const char *format, ...)
     331             : #else
     332             : parser_error (lineno, format, va_alist)
     333             :      int lineno;
     334             :      const char *format;
     335             :      va_dcl
     336             : #endif
     337             : {
     338     4076511 :   va_list args;
     339     4076511 :   char *ename, *iname;
     340             : 
     341     4076511 :   ename = get_name_for_error ();
     342     4076511 :   iname = yy_input_name ();
     343             : 
     344     4076511 :   if (interactive)
     345           0 :     fprintf (stderr, "%s: ", ename);
     346     4076511 :   else if (interactive_shell)
     347           0 :     fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
     348     4076511 :   else if (STREQ (ename, iname))
     349     4069152 :     fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno);
     350             :   else
     351        7359 :     fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
     352             : 
     353     4076511 :   SH_VA_START (args, format);
     354             : 
     355     4076511 :   vfprintf (stderr, format, args);
     356     4076511 :   fprintf (stderr, "\n");
     357             : 
     358     4076511 :   va_end (args);
     359             : 
     360     4076511 :   if (exit_immediately_on_error)
     361           0 :     exit_shell (last_command_exit_value = 2);
     362     4076511 : }
     363             : 
     364             : #if 0
     365             : /* This assumes ASCII and is suitable only for debugging */
     366             : char *
     367             : strescape (str)
     368             :      const char *str;
     369             : {
     370             :   char *r, *result;
     371             :   unsigned char *s;
     372             : 
     373             :   r = result = (char *)xmalloc (strlen (str) * 2 + 1);
     374             : 
     375             :   for (s = (unsigned char *)str; s && *s; s++)
     376             :     {
     377             :       if (*s < ' ')
     378             :         {
     379             :           *r++ = '^';
     380             :           *r++ = *s+64;
     381             :         }
     382             :       else if (*s == 127)
     383             :         {
     384             :           *r++ = '^';
     385             :           *r++ = '?';
     386             :         }
     387             :      else
     388             :         *r++ = *s;
     389             :     }
     390             : 
     391             :   *r = '\0';
     392             :   return result;
     393             : }
     394             : 
     395             : void
     396             : #if defined (PREFER_STDARG)
     397             : itrace (const char *format, ...)
     398             : #else
     399             : itrace (format, va_alist)
     400             :      const char *format;
     401             :      va_dcl
     402             : #endif
     403             : {
     404             :   va_list args;
     405             : 
     406             :   fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
     407             : 
     408             :   SH_VA_START (args, format);
     409             : 
     410             :   vfprintf (stderr, format, args);
     411             :   fprintf (stderr, "\n");
     412             : 
     413             :   va_end (args);
     414             : 
     415             :   fflush(stderr);
     416             : }
     417             : 
     418             : /* A trace function for silent debugging -- doesn't require a control
     419             :    terminal. */
     420             : void
     421             : #if defined (PREFER_STDARG)
     422             : trace (const char *format, ...)
     423             : #else
     424             : trace (format, va_alist)
     425             :      const char *format;
     426             :      va_dcl
     427             : #endif
     428             : {
     429             :   va_list args;
     430             :   static FILE *tracefp = (FILE *)NULL;
     431             : 
     432             :   if (tracefp == NULL)
     433             :     tracefp = fopen("/var/run/bash-trace.log", "a+");
     434             : 
     435             :   if (tracefp == NULL)
     436             :     tracefp = stderr;
     437             :   else
     438             :     fcntl (fileno (tracefp), F_SETFD, 1);     /* close-on-exec */
     439             : 
     440             :   fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
     441             : 
     442             :   SH_VA_START (args, format);
     443             : 
     444             :   vfprintf (tracefp, format, args);
     445             :   fprintf (tracefp, "\n");
     446             : 
     447             :   va_end (args);
     448             : 
     449             :   fflush(tracefp);
     450             : }
     451             : 
     452             : #endif /* DEBUG */
     453             : 
     454             : /* **************************************************************** */
     455             : /*                                                                  */
     456             : /*                  Common error reporting                          */
     457             : /*                                                                  */
     458             : /* **************************************************************** */
     459             : 
     460             : 
     461             : static const char * const cmd_error_table[] = {
     462             :         N_("unknown command error"),  /* CMDERR_DEFAULT */
     463             :         N_("bad command type"),               /* CMDERR_BADTYPE */
     464             :         N_("bad connector"),          /* CMDERR_BADCONN */
     465             :         N_("bad jump"),                       /* CMDERR_BADJUMP */
     466             :         0
     467             : };
     468             : 
     469             : void
     470           0 : command_error (func, code, e, flags)
     471             :      const char *func;
     472             :      int code, e, flags;        /* flags currently unused */
     473             : {
     474           0 :   if (code > CMDERR_LAST)
     475           0 :     code = CMDERR_DEFAULT;
     476             : 
     477           0 :   programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
     478             : }
     479             : 
     480             : char *
     481           0 : command_errstr (code)
     482             :      int code;
     483             : {
     484           0 :   if (code > CMDERR_LAST)
     485           0 :     code = CMDERR_DEFAULT;
     486             : 
     487           0 :   return (_(cmd_error_table[code]));
     488             : }
     489             : 
     490             : #ifdef ARRAY_VARS
     491             : void
     492           9 : err_badarraysub (s)
     493             :      const char *s;
     494             : {
     495           9 :   report_error ("%s: %s", s, _(bash_badsub_errmsg));
     496           9 : }
     497             : #endif
     498             : 
     499             : void
     500           0 : err_unboundvar (s)
     501             :      const char *s;
     502             : {
     503           0 :   report_error (_("%s: unbound variable"), s);
     504           0 : }
     505             : 
     506             : void
     507           0 : err_readonly (s)
     508             :      const char *s;
     509             : {
     510           0 :   report_error (_("%s: readonly variable"), s);
     511           0 : }

Generated by: LCOV version 1.14.0.6.4058