Blame gnulib/lib/error.c

Packit eba2e2
/* Error handler for noninteractive utilities
Packit eba2e2
   Copyright (C) 1990-1998, 2000-2007, 2009-2014 Free Software Foundation, Inc.
Packit eba2e2
   This file is part of the GNU C Library.
Packit eba2e2
Packit eba2e2
   This program is free software: you can redistribute it and/or modify
Packit eba2e2
   it under the terms of the GNU General Public License as published by
Packit eba2e2
   the Free Software Foundation; either version 3 of the License, or
Packit eba2e2
   (at your option) any later version.
Packit eba2e2
Packit eba2e2
   This program is distributed in the hope that it will be useful,
Packit eba2e2
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit eba2e2
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit eba2e2
   GNU General Public License for more details.
Packit eba2e2
Packit eba2e2
   You should have received a copy of the GNU General Public License
Packit eba2e2
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit eba2e2
Packit eba2e2
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
Packit eba2e2
Packit eba2e2
#if !_LIBC
Packit eba2e2
# include <config.h>
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
#include "error.h"
Packit eba2e2
Packit eba2e2
#include <stdarg.h>
Packit eba2e2
#include <stdio.h>
Packit eba2e2
#include <stdlib.h>
Packit eba2e2
#include <string.h>
Packit eba2e2
Packit eba2e2
#if !_LIBC && ENABLE_NLS
Packit eba2e2
# include "gettext.h"
Packit eba2e2
# define _(msgid) gettext (msgid)
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
# include <libintl.h>
Packit eba2e2
# include <stdbool.h>
Packit eba2e2
# include <stdint.h>
Packit eba2e2
# include <wchar.h>
Packit eba2e2
# define mbsrtowcs __mbsrtowcs
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
#if USE_UNLOCKED_IO
Packit eba2e2
# include "unlocked-io.h"
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
#ifndef _
Packit eba2e2
# define _(String) String
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
/* If NULL, error will flush stdout, then print on stderr the program
Packit eba2e2
   name, a colon and a space.  Otherwise, error will call this
Packit eba2e2
   function without parameters instead.  */
Packit eba2e2
void (*error_print_progname) (void);
Packit eba2e2
Packit eba2e2
/* This variable is incremented each time 'error' is called.  */
Packit eba2e2
unsigned int error_message_count;
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
/* In the GNU C library, there is a predefined variable for this.  */
Packit eba2e2
Packit eba2e2
# define program_name program_invocation_name
Packit eba2e2
# include <errno.h>
Packit eba2e2
# include <limits.h>
Packit eba2e2
# include <libio/libioP.h>
Packit eba2e2
Packit eba2e2
/* In GNU libc we want do not want to use the common name 'error' directly.
Packit eba2e2
   Instead make it a weak alias.  */
Packit eba2e2
extern void __error (int status, int errnum, const char *message, ...)
Packit eba2e2
     __attribute__ ((__format__ (__printf__, 3, 4)));
Packit eba2e2
extern void __error_at_line (int status, int errnum, const char *file_name,
Packit eba2e2
                             unsigned int line_number, const char *message,
Packit eba2e2
                             ...)
Packit eba2e2
     __attribute__ ((__format__ (__printf__, 5, 6)));;
Packit eba2e2
# define error __error
Packit eba2e2
# define error_at_line __error_at_line
Packit eba2e2
Packit eba2e2
# include <libio/iolibio.h>
Packit eba2e2
# define fflush(s) INTUSE(_IO_fflush) (s)
Packit eba2e2
# undef putc
Packit eba2e2
# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
Packit eba2e2
Packit eba2e2
# include <bits/libc-lock.h>
Packit eba2e2
Packit eba2e2
#else /* not _LIBC */
Packit eba2e2
Packit eba2e2
# include <fcntl.h>
Packit eba2e2
# include <unistd.h>
Packit eba2e2
Packit eba2e2
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
Packit eba2e2
/* Get declarations of the native Windows API functions.  */
Packit eba2e2
#  define WIN32_LEAN_AND_MEAN
Packit eba2e2
#  include <windows.h>
Packit eba2e2
/* Get _get_osfhandle.  */
Packit eba2e2
#  include "msvc-nothrow.h"
Packit eba2e2
# endif
Packit eba2e2
Packit eba2e2
/* The gnulib override of fcntl is not needed in this file.  */
Packit eba2e2
# undef fcntl
Packit eba2e2
Packit eba2e2
# if !HAVE_DECL_STRERROR_R
Packit eba2e2
#  ifndef HAVE_DECL_STRERROR_R
Packit eba2e2
"this configure-time declaration test was not run"
Packit eba2e2
#  endif
Packit eba2e2
#  if STRERROR_R_CHAR_P
Packit eba2e2
char *strerror_r ();
Packit eba2e2
#  else
Packit eba2e2
int strerror_r ();
Packit eba2e2
#  endif
Packit eba2e2
# endif
Packit eba2e2
Packit eba2e2
/* The calling program should define program_name and set it to the
Packit eba2e2
   name of the executing program.  */
Packit eba2e2
extern char *program_name;
Packit eba2e2
Packit eba2e2
# if HAVE_STRERROR_R || defined strerror_r
Packit eba2e2
#  define __strerror_r strerror_r
Packit eba2e2
# endif /* HAVE_STRERROR_R || defined strerror_r */
Packit eba2e2
#endif  /* not _LIBC */
Packit eba2e2
Packit eba2e2
#if !_LIBC
Packit eba2e2
/* Return non-zero if FD is open.  */
Packit eba2e2
static int
Packit eba2e2
is_open (int fd)
Packit eba2e2
{
Packit eba2e2
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
Packit eba2e2
  /* On native Windows: The initial state of unassigned standard file
Packit eba2e2
     descriptors is that they are open but point to an INVALID_HANDLE_VALUE.
Packit eba2e2
     There is no fcntl, and the gnulib replacement fcntl does not support
Packit eba2e2
     F_GETFL.  */
Packit eba2e2
  return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
Packit eba2e2
# else
Packit eba2e2
#  ifndef F_GETFL
Packit eba2e2
#   error Please port fcntl to your platform
Packit eba2e2
#  endif
Packit eba2e2
  return 0 <= fcntl (fd, F_GETFL);
Packit eba2e2
# endif
Packit eba2e2
}
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
static void
Packit eba2e2
flush_stdout (void)
Packit eba2e2
{
Packit eba2e2
#if !_LIBC
Packit eba2e2
  int stdout_fd;
Packit eba2e2
Packit eba2e2
# if GNULIB_FREOPEN_SAFER
Packit eba2e2
  /* Use of gnulib's freopen-safer module normally ensures that
Packit eba2e2
       fileno (stdout) == 1
Packit eba2e2
     whenever stdout is open.  */
Packit eba2e2
  stdout_fd = STDOUT_FILENO;
Packit eba2e2
# else
Packit eba2e2
  /* POSIX states that fileno (stdout) after fclose is unspecified.  But in
Packit eba2e2
     practice it is not a problem, because stdout is statically allocated and
Packit eba2e2
     the fd of a FILE stream is stored as a field in its allocated memory.  */
Packit eba2e2
  stdout_fd = fileno (stdout);
Packit eba2e2
# endif
Packit eba2e2
  /* POSIX states that fflush (stdout) after fclose is unspecified; it
Packit eba2e2
     is safe in glibc, but not on all other platforms.  fflush (NULL)
Packit eba2e2
     is always defined, but too draconian.  */
Packit eba2e2
  if (0 <= stdout_fd && is_open (stdout_fd))
Packit eba2e2
#endif
Packit eba2e2
    fflush (stdout);
Packit eba2e2
}
Packit eba2e2
Packit eba2e2
static void
Packit eba2e2
print_errno_message (int errnum)
Packit eba2e2
{
Packit eba2e2
  char const *s;
Packit eba2e2
Packit eba2e2
#if defined HAVE_STRERROR_R || _LIBC
Packit eba2e2
  char errbuf[1024];
Packit eba2e2
# if STRERROR_R_CHAR_P || _LIBC
Packit eba2e2
  s = __strerror_r (errnum, errbuf, sizeof errbuf);
Packit eba2e2
# else
Packit eba2e2
  if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
Packit eba2e2
    s = errbuf;
Packit eba2e2
  else
Packit eba2e2
    s = 0;
Packit eba2e2
# endif
Packit eba2e2
#else
Packit eba2e2
  s = strerror (errnum);
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
#if !_LIBC
Packit eba2e2
  if (! s)
Packit eba2e2
    s = _("Unknown system error");
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
#if _LIBC
Packit eba2e2
  __fxprintf (NULL, ": %s", s);
Packit eba2e2
#else
Packit eba2e2
  fprintf (stderr, ": %s", s);
Packit eba2e2
#endif
Packit eba2e2
}
Packit eba2e2
Packit eba2e2
static void _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) _GL_ARG_NONNULL ((3))
Packit eba2e2
error_tail (int status, int errnum, const char *message, va_list args)
Packit eba2e2
{
Packit eba2e2
#if _LIBC
Packit eba2e2
  if (_IO_fwide (stderr, 0) > 0)
Packit eba2e2
    {
Packit eba2e2
# define ALLOCA_LIMIT 2000
Packit eba2e2
      size_t len = strlen (message) + 1;
Packit eba2e2
      wchar_t *wmessage = NULL;
Packit eba2e2
      mbstate_t st;
Packit eba2e2
      size_t res;
Packit eba2e2
      const char *tmp;
Packit eba2e2
      bool use_malloc = false;
Packit eba2e2
Packit eba2e2
      while (1)
Packit eba2e2
        {
Packit eba2e2
          if (__libc_use_alloca (len * sizeof (wchar_t)))
Packit eba2e2
            wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
Packit eba2e2
          else
Packit eba2e2
            {
Packit eba2e2
              if (!use_malloc)
Packit eba2e2
                wmessage = NULL;
Packit eba2e2
Packit eba2e2
              wchar_t *p = (wchar_t *) realloc (wmessage,
Packit eba2e2
                                                len * sizeof (wchar_t));
Packit eba2e2
              if (p == NULL)
Packit eba2e2
                {
Packit eba2e2
                  free (wmessage);
Packit eba2e2
                  fputws_unlocked (L"out of memory\n", stderr);
Packit eba2e2
                  return;
Packit eba2e2
                }
Packit eba2e2
              wmessage = p;
Packit eba2e2
              use_malloc = true;
Packit eba2e2
            }
Packit eba2e2
Packit eba2e2
          memset (&st, '\0', sizeof (st));
Packit eba2e2
          tmp = message;
Packit eba2e2
Packit eba2e2
          res = mbsrtowcs (wmessage, &tmp, len, &st);
Packit eba2e2
          if (res != len)
Packit eba2e2
            break;
Packit eba2e2
Packit eba2e2
          if (__builtin_expect (len >= SIZE_MAX / 2, 0))
Packit eba2e2
            {
Packit eba2e2
              /* This really should not happen if everything is fine.  */
Packit eba2e2
              res = (size_t) -1;
Packit eba2e2
              break;
Packit eba2e2
            }
Packit eba2e2
Packit eba2e2
          len *= 2;
Packit eba2e2
        }
Packit eba2e2
Packit eba2e2
      if (res == (size_t) -1)
Packit eba2e2
        {
Packit eba2e2
          /* The string cannot be converted.  */
Packit eba2e2
          if (use_malloc)
Packit eba2e2
            {
Packit eba2e2
              free (wmessage);
Packit eba2e2
              use_malloc = false;
Packit eba2e2
            }
Packit eba2e2
          wmessage = (wchar_t *) L"???";
Packit eba2e2
        }
Packit eba2e2
Packit eba2e2
      __vfwprintf (stderr, wmessage, args);
Packit eba2e2
Packit eba2e2
      if (use_malloc)
Packit eba2e2
        free (wmessage);
Packit eba2e2
    }
Packit eba2e2
  else
Packit eba2e2
#endif
Packit eba2e2
    vfprintf (stderr, message, args);
Packit eba2e2
  va_end (args);
Packit eba2e2
Packit eba2e2
  ++error_message_count;
Packit eba2e2
  if (errnum)
Packit eba2e2
    print_errno_message (errnum);
Packit eba2e2
#if _LIBC
Packit eba2e2
  __fxprintf (NULL, "\n");
Packit eba2e2
#else
Packit eba2e2
  putc ('\n', stderr);
Packit eba2e2
#endif
Packit eba2e2
  fflush (stderr);
Packit eba2e2
  if (status)
Packit eba2e2
    exit (status);
Packit eba2e2
}
Packit eba2e2
Packit eba2e2
Packit eba2e2
/* Print the program name and error message MESSAGE, which is a printf-style
Packit eba2e2
   format string with optional args.
Packit eba2e2
   If ERRNUM is nonzero, print its corresponding system error message.
Packit eba2e2
   Exit with status STATUS if it is nonzero.  */
Packit eba2e2
void
Packit eba2e2
error (int status, int errnum, const char *message, ...)
Packit eba2e2
{
Packit eba2e2
  va_list args;
Packit eba2e2
Packit eba2e2
#if defined _LIBC && defined __libc_ptf_call
Packit eba2e2
  /* We do not want this call to be cut short by a thread
Packit eba2e2
     cancellation.  Therefore disable cancellation for now.  */
Packit eba2e2
  int state = PTHREAD_CANCEL_ENABLE;
Packit eba2e2
  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
Packit eba2e2
                   0);
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
  flush_stdout ();
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
  _IO_flockfile (stderr);
Packit eba2e2
#endif
Packit eba2e2
  if (error_print_progname)
Packit eba2e2
    (*error_print_progname) ();
Packit eba2e2
  else
Packit eba2e2
    {
Packit eba2e2
#if _LIBC
Packit eba2e2
      __fxprintf (NULL, "%s: ", program_name);
Packit eba2e2
#else
Packit eba2e2
      fprintf (stderr, "%s: ", program_name);
Packit eba2e2
#endif
Packit eba2e2
    }
Packit eba2e2
Packit eba2e2
  va_start (args, message);
Packit eba2e2
  error_tail (status, errnum, message, args);
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
  _IO_funlockfile (stderr);
Packit eba2e2
# ifdef __libc_ptf_call
Packit eba2e2
  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
Packit eba2e2
# endif
Packit eba2e2
#endif
Packit eba2e2
}
Packit eba2e2

Packit eba2e2
/* Sometimes we want to have at most one error per line.  This
Packit eba2e2
   variable controls whether this mode is selected or not.  */
Packit eba2e2
int error_one_per_line;
Packit eba2e2
Packit eba2e2
void
Packit eba2e2
error_at_line (int status, int errnum, const char *file_name,
Packit eba2e2
               unsigned int line_number, const char *message, ...)
Packit eba2e2
{
Packit eba2e2
  va_list args;
Packit eba2e2
Packit eba2e2
  if (error_one_per_line)
Packit eba2e2
    {
Packit eba2e2
      static const char *old_file_name;
Packit eba2e2
      static unsigned int old_line_number;
Packit eba2e2
Packit eba2e2
      if (old_line_number == line_number
Packit eba2e2
          && (file_name == old_file_name
Packit eba2e2
              || strcmp (old_file_name, file_name) == 0))
Packit eba2e2
        /* Simply return and print nothing.  */
Packit eba2e2
        return;
Packit eba2e2
Packit eba2e2
      old_file_name = file_name;
Packit eba2e2
      old_line_number = line_number;
Packit eba2e2
    }
Packit eba2e2
Packit eba2e2
#if defined _LIBC && defined __libc_ptf_call
Packit eba2e2
  /* We do not want this call to be cut short by a thread
Packit eba2e2
     cancellation.  Therefore disable cancellation for now.  */
Packit eba2e2
  int state = PTHREAD_CANCEL_ENABLE;
Packit eba2e2
  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
Packit eba2e2
                   0);
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
  flush_stdout ();
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
  _IO_flockfile (stderr);
Packit eba2e2
#endif
Packit eba2e2
  if (error_print_progname)
Packit eba2e2
    (*error_print_progname) ();
Packit eba2e2
  else
Packit eba2e2
    {
Packit eba2e2
#if _LIBC
Packit eba2e2
      __fxprintf (NULL, "%s:", program_name);
Packit eba2e2
#else
Packit eba2e2
      fprintf (stderr, "%s:", program_name);
Packit eba2e2
#endif
Packit eba2e2
    }
Packit eba2e2
Packit eba2e2
#if _LIBC
Packit eba2e2
  __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
Packit eba2e2
              file_name, line_number);
Packit eba2e2
#else
Packit eba2e2
  fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
Packit eba2e2
           file_name, line_number);
Packit eba2e2
#endif
Packit eba2e2
Packit eba2e2
  va_start (args, message);
Packit eba2e2
  error_tail (status, errnum, message, args);
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
  _IO_funlockfile (stderr);
Packit eba2e2
# ifdef __libc_ptf_call
Packit eba2e2
  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
Packit eba2e2
# endif
Packit eba2e2
#endif
Packit eba2e2
}
Packit eba2e2
Packit eba2e2
#ifdef _LIBC
Packit eba2e2
/* Make the weak alias.  */
Packit eba2e2
# undef error
Packit eba2e2
# undef error_at_line
Packit eba2e2
weak_alias (__error, error)
Packit eba2e2
weak_alias (__error_at_line, error_at_line)
Packit eba2e2
#endif