"Fossies" - the Fresh Open Source Software Archive

Member "cpio-2.13/gnu/error.c" (2 Jan 2017, 10446 Bytes) of package /linux/misc/cpio-2.13.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "error.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.12_vs_2.13.

    1 /* Error handler for noninteractive utilities
    2    Copyright (C) 1990-1998, 2000-2007, 2009-2017 Free Software Foundation, Inc.
    3    This file is part of the GNU C Library.
    4 
    5    This program is free software: you can redistribute it and/or modify
    6    it under the terms of the GNU General Public License as published by
    7    the Free Software Foundation; either version 3 of the License, or
    8    (at your option) any later version.
    9 
   10    This program is distributed in the hope that it will be useful,
   11    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13    GNU General Public License for more details.
   14 
   15    You should have received a copy of the GNU General Public License
   16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   17 
   18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
   19 
   20 #if !_LIBC
   21 # include <config.h>
   22 #endif
   23 
   24 #include "error.h"
   25 
   26 #include <stdarg.h>
   27 #include <stdio.h>
   28 #include <stdlib.h>
   29 #include <string.h>
   30 
   31 #if !_LIBC && ENABLE_NLS
   32 # include "gettext.h"
   33 # define _(msgid) gettext (msgid)
   34 #endif
   35 
   36 #ifdef _LIBC
   37 # include <libintl.h>
   38 # include <stdbool.h>
   39 # include <stdint.h>
   40 # include <wchar.h>
   41 # define mbsrtowcs __mbsrtowcs
   42 # define USE_UNLOCKED_IO 0
   43 # define _GL_ATTRIBUTE_FORMAT_PRINTF(a, b)
   44 # define _GL_ARG_NONNULL(a)
   45 #else
   46 # include "getprogname.h"
   47 #endif
   48 
   49 #if USE_UNLOCKED_IO
   50 # include "unlocked-io.h"
   51 #endif
   52 
   53 #ifndef _
   54 # define _(String) String
   55 #endif
   56 
   57 /* If NULL, error will flush stdout, then print on stderr the program
   58    name, a colon and a space.  Otherwise, error will call this
   59    function without parameters instead.  */
   60 void (*error_print_progname) (void);
   61 
   62 /* This variable is incremented each time 'error' is called.  */
   63 unsigned int error_message_count;
   64 
   65 #ifdef _LIBC
   66 /* In the GNU C library, there is a predefined variable for this.  */
   67 
   68 # define program_name program_invocation_name
   69 # include <errno.h>
   70 # include <limits.h>
   71 # include <libio/libioP.h>
   72 
   73 /* In GNU libc we want do not want to use the common name 'error' directly.
   74    Instead make it a weak alias.  */
   75 extern void __error (int status, int errnum, const char *message, ...)
   76      __attribute__ ((__format__ (__printf__, 3, 4)));
   77 extern void __error_at_line (int status, int errnum, const char *file_name,
   78                              unsigned int line_number, const char *message,
   79                              ...)
   80      __attribute__ ((__format__ (__printf__, 5, 6)));
   81 # define error __error
   82 # define error_at_line __error_at_line
   83 
   84 # include <libio/iolibio.h>
   85 # define fflush(s) _IO_fflush (s)
   86 # undef putc
   87 # define putc(c, fp) _IO_putc (c, fp)
   88 
   89 # include <bits/libc-lock.h>
   90 
   91 #else /* not _LIBC */
   92 
   93 # include <fcntl.h>
   94 # include <unistd.h>
   95 
   96 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   97 /* Get declarations of the native Windows API functions.  */
   98 #  define WIN32_LEAN_AND_MEAN
   99 #  include <windows.h>
  100 /* Get _get_osfhandle.  */
  101 #  include "msvc-nothrow.h"
  102 # endif
  103 
  104 /* The gnulib override of fcntl is not needed in this file.  */
  105 # undef fcntl
  106 
  107 # if !HAVE_DECL_STRERROR_R
  108 #  ifndef HAVE_DECL_STRERROR_R
  109 "this configure-time declaration test was not run"
  110 #  endif
  111 #  if STRERROR_R_CHAR_P
  112 char *strerror_r ();
  113 #  else
  114 int strerror_r ();
  115 #  endif
  116 # endif
  117 
  118 #define program_name getprogname ()
  119 
  120 # if HAVE_STRERROR_R || defined strerror_r
  121 #  define __strerror_r strerror_r
  122 # endif /* HAVE_STRERROR_R || defined strerror_r */
  123 #endif  /* not _LIBC */
  124 
  125 #if !_LIBC
  126 /* Return non-zero if FD is open.  */
  127 static int
  128 is_open (int fd)
  129 {
  130 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  131   /* On native Windows: The initial state of unassigned standard file
  132      descriptors is that they are open but point to an INVALID_HANDLE_VALUE.
  133      There is no fcntl, and the gnulib replacement fcntl does not support
  134      F_GETFL.  */
  135   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
  136 # else
  137 #  ifndef F_GETFL
  138 #   error Please port fcntl to your platform
  139 #  endif
  140   return 0 <= fcntl (fd, F_GETFL);
  141 # endif
  142 }
  143 #endif
  144 
  145 static void
  146 flush_stdout (void)
  147 {
  148 #if !_LIBC
  149   int stdout_fd;
  150 
  151 # if GNULIB_FREOPEN_SAFER
  152   /* Use of gnulib's freopen-safer module normally ensures that
  153        fileno (stdout) == 1
  154      whenever stdout is open.  */
  155   stdout_fd = STDOUT_FILENO;
  156 # else
  157   /* POSIX states that fileno (stdout) after fclose is unspecified.  But in
  158      practice it is not a problem, because stdout is statically allocated and
  159      the fd of a FILE stream is stored as a field in its allocated memory.  */
  160   stdout_fd = fileno (stdout);
  161 # endif
  162   /* POSIX states that fflush (stdout) after fclose is unspecified; it
  163      is safe in glibc, but not on all other platforms.  fflush (NULL)
  164      is always defined, but too draconian.  */
  165   if (0 <= stdout_fd && is_open (stdout_fd))
  166 #endif
  167     fflush (stdout);
  168 }
  169 
  170 static void
  171 print_errno_message (int errnum)
  172 {
  173   char const *s;
  174 
  175 #if defined HAVE_STRERROR_R || _LIBC
  176   char errbuf[1024];
  177 # if _LIBC || STRERROR_R_CHAR_P
  178   s = __strerror_r (errnum, errbuf, sizeof errbuf);
  179 # else
  180   if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
  181     s = errbuf;
  182   else
  183     s = 0;
  184 # endif
  185 #else
  186   s = strerror (errnum);
  187 #endif
  188 
  189 #if !_LIBC
  190   if (! s)
  191     s = _("Unknown system error");
  192 #endif
  193 
  194 #if _LIBC
  195   __fxprintf (NULL, ": %s", s);
  196 #else
  197   fprintf (stderr, ": %s", s);
  198 #endif
  199 }
  200 
  201 static void _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) _GL_ARG_NONNULL ((3))
  202 error_tail (int status, int errnum, const char *message, va_list args)
  203 {
  204 #if _LIBC
  205   if (_IO_fwide (stderr, 0) > 0)
  206     {
  207       size_t len = strlen (message) + 1;
  208       wchar_t *wmessage = NULL;
  209       mbstate_t st;
  210       size_t res;
  211       const char *tmp;
  212       bool use_malloc = false;
  213 
  214       while (1)
  215         {
  216           if (__libc_use_alloca (len * sizeof (wchar_t)))
  217             wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
  218           else
  219             {
  220               if (!use_malloc)
  221                 wmessage = NULL;
  222 
  223               wchar_t *p = (wchar_t *) realloc (wmessage,
  224                                                 len * sizeof (wchar_t));
  225               if (p == NULL)
  226                 {
  227                   free (wmessage);
  228                   fputws_unlocked (L"out of memory\n", stderr);
  229                   return;
  230                 }
  231               wmessage = p;
  232               use_malloc = true;
  233             }
  234 
  235           memset (&st, '\0', sizeof (st));
  236           tmp = message;
  237 
  238           res = mbsrtowcs (wmessage, &tmp, len, &st);
  239           if (res != len)
  240             break;
  241 
  242           if (__builtin_expect (len >= SIZE_MAX / sizeof (wchar_t) / 2, 0))
  243             {
  244               /* This really should not happen if everything is fine.  */
  245               res = (size_t) -1;
  246               break;
  247             }
  248 
  249           len *= 2;
  250         }
  251 
  252       if (res == (size_t) -1)
  253         {
  254           /* The string cannot be converted.  */
  255           if (use_malloc)
  256             {
  257               free (wmessage);
  258               use_malloc = false;
  259             }
  260           wmessage = (wchar_t *) L"???";
  261         }
  262 
  263       __vfwprintf (stderr, wmessage, args);
  264 
  265       if (use_malloc)
  266         free (wmessage);
  267     }
  268   else
  269 #endif
  270     vfprintf (stderr, message, args);
  271   va_end (args);
  272 
  273   ++error_message_count;
  274   if (errnum)
  275     print_errno_message (errnum);
  276 #if _LIBC
  277   __fxprintf (NULL, "\n");
  278 #else
  279   putc ('\n', stderr);
  280 #endif
  281   fflush (stderr);
  282   if (status)
  283     exit (status);
  284 }
  285 
  286 
  287 /* Print the program name and error message MESSAGE, which is a printf-style
  288    format string with optional args.
  289    If ERRNUM is nonzero, print its corresponding system error message.
  290    Exit with status STATUS if it is nonzero.  */
  291 void
  292 error (int status, int errnum, const char *message, ...)
  293 {
  294   va_list args;
  295 
  296 #if defined _LIBC && defined __libc_ptf_call
  297   /* We do not want this call to be cut short by a thread
  298      cancellation.  Therefore disable cancellation for now.  */
  299   int state = PTHREAD_CANCEL_ENABLE;
  300   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
  301                    0);
  302 #endif
  303 
  304   flush_stdout ();
  305 #ifdef _LIBC
  306   _IO_flockfile (stderr);
  307 #endif
  308   if (error_print_progname)
  309     (*error_print_progname) ();
  310   else
  311     {
  312 #if _LIBC
  313       __fxprintf (NULL, "%s: ", program_name);
  314 #else
  315       fprintf (stderr, "%s: ", program_name);
  316 #endif
  317     }
  318 
  319   va_start (args, message);
  320   error_tail (status, errnum, message, args);
  321 
  322 #ifdef _LIBC
  323   _IO_funlockfile (stderr);
  324 # ifdef __libc_ptf_call
  325   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
  326 # endif
  327 #endif
  328 }
  329 
  330 /* Sometimes we want to have at most one error per line.  This
  331    variable controls whether this mode is selected or not.  */
  332 int error_one_per_line;
  333 
  334 void
  335 error_at_line (int status, int errnum, const char *file_name,
  336                unsigned int line_number, const char *message, ...)
  337 {
  338   va_list args;
  339 
  340   if (error_one_per_line)
  341     {
  342       static const char *old_file_name;
  343       static unsigned int old_line_number;
  344 
  345       if (old_line_number == line_number
  346           && (file_name == old_file_name
  347               || (old_file_name != NULL
  348                   && file_name != NULL
  349                   && strcmp (old_file_name, file_name) == 0)))
  350 
  351         /* Simply return and print nothing.  */
  352         return;
  353 
  354       old_file_name = file_name;
  355       old_line_number = line_number;
  356     }
  357 
  358 #if defined _LIBC && defined __libc_ptf_call
  359   /* We do not want this call to be cut short by a thread
  360      cancellation.  Therefore disable cancellation for now.  */
  361   int state = PTHREAD_CANCEL_ENABLE;
  362   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
  363                    0);
  364 #endif
  365 
  366   flush_stdout ();
  367 #ifdef _LIBC
  368   _IO_flockfile (stderr);
  369 #endif
  370   if (error_print_progname)
  371     (*error_print_progname) ();
  372   else
  373     {
  374 #if _LIBC
  375       __fxprintf (NULL, "%s:", program_name);
  376 #else
  377       fprintf (stderr, "%s:", program_name);
  378 #endif
  379     }
  380 
  381 #if _LIBC
  382   __fxprintf (NULL, file_name != NULL ? "%s:%u: " : " ",
  383               file_name, line_number);
  384 #else
  385   fprintf (stderr, file_name != NULL ? "%s:%u: " : " ",
  386            file_name, line_number);
  387 #endif
  388 
  389   va_start (args, message);
  390   error_tail (status, errnum, message, args);
  391 
  392 #ifdef _LIBC
  393   _IO_funlockfile (stderr);
  394 # ifdef __libc_ptf_call
  395   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
  396 # endif
  397 #endif
  398 }
  399 
  400 #ifdef _LIBC
  401 /* Make the weak alias.  */
  402 # undef error
  403 # undef error_at_line
  404 weak_alias (__error, error)
  405 weak_alias (__error_at_line, error_at_line)
  406 #endif