Back to index

glibc  2.9
error.c
Go to the documentation of this file.
00001 /* Error handler for noninteractive utilities
00002    Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 # include <config.h>
00024 #endif
00025 
00026 #include <stdarg.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 
00031 #ifdef _LIBC
00032 # include <libintl.h>
00033 # include <stdbool.h>
00034 # include <stdint.h>
00035 # include <wchar.h>
00036 # define mbsrtowcs __mbsrtowcs
00037 #endif
00038 
00039 #include "error.h"
00040 
00041 #ifndef _
00042 # define _(String) String
00043 #endif
00044 
00045 /* If NULL, error will flush stdout, then print on stderr the program
00046    name, a colon and a space.  Otherwise, error will call this
00047    function without parameters instead.  */
00048 void (*error_print_progname) (void);
00049 
00050 /* This variable is incremented each time `error' is called.  */
00051 unsigned int error_message_count;
00052 
00053 #ifdef _LIBC
00054 /* In the GNU C library, there is a predefined variable for this.  */
00055 
00056 # define program_name program_invocation_name
00057 # include <errno.h>
00058 # include <limits.h>
00059 # include <libio/libioP.h>
00060 
00061 /* In GNU libc we want do not want to use the common name `error' directly.
00062    Instead make it a weak alias.  */
00063 extern void __error (int status, int errnum, const char *message, ...)
00064      __attribute__ ((__format__ (__printf__, 3, 4)));
00065 extern void __error_at_line (int status, int errnum, const char *file_name,
00066                           unsigned int line_number, const char *message,
00067                           ...)
00068      __attribute__ ((__format__ (__printf__, 5, 6)));;
00069 # define error __error
00070 # define error_at_line __error_at_line
00071 
00072 # include <libio/iolibio.h>
00073 # define fflush(s) INTUSE(_IO_fflush) (s)
00074 # undef putc
00075 # define putc(c, fp) INTUSE(_IO_putc) (c, fp)
00076 
00077 # include <bits/libc-lock.h>
00078 
00079 #else /* not _LIBC */
00080 
00081 # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
00082 #  ifndef HAVE_DECL_STRERROR_R
00083 "this configure-time declaration test was not run"
00084 #  endif
00085 char *strerror_r ();
00086 # endif
00087 
00088 /* The calling program should define program_name and set it to the
00089    name of the executing program.  */
00090 extern char *program_name;
00091 
00092 # if HAVE_STRERROR_R || defined strerror_r
00093 #  define __strerror_r strerror_r
00094 # endif       /* HAVE_STRERROR_R || defined strerror_r */
00095 #endif /* not _LIBC */
00096 
00097 static void
00098 print_errno_message (int errnum)
00099 {
00100   char const *s;
00101 
00102 #if defined HAVE_STRERROR_R || _LIBC
00103   char errbuf[1024];
00104 # if STRERROR_R_CHAR_P || _LIBC
00105   s = __strerror_r (errnum, errbuf, sizeof errbuf);
00106 # else
00107   if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
00108     s = errbuf;
00109   else
00110     s = 0;
00111 # endif
00112 #else
00113   s = strerror (errnum);
00114 #endif
00115 
00116 #if !_LIBC
00117   if (! s)
00118     s = _("Unknown system error");
00119 #endif
00120 
00121 #if _LIBC
00122   __fxprintf (NULL, ": %s", s);
00123 #else
00124   fprintf (stderr, ": %s", s);
00125 #endif
00126 }
00127 
00128 static void
00129 error_tail (int status, int errnum, const char *message, va_list args)
00130 {
00131 #if _LIBC
00132   if (_IO_fwide (stderr, 0) > 0)
00133     {
00134 # define ALLOCA_LIMIT 2000
00135       size_t len = strlen (message) + 1;
00136       wchar_t *wmessage = NULL;
00137       mbstate_t st;
00138       size_t res;
00139       const char *tmp;
00140       bool use_malloc = false;
00141 
00142       while (1)
00143        {
00144          if (__libc_use_alloca (len * sizeof (wchar_t)))
00145            wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
00146          else
00147            {
00148              if (!use_malloc)
00149               wmessage = NULL;
00150 
00151              wchar_t *p = (wchar_t *) realloc (wmessage,
00152                                           len * sizeof (wchar_t));
00153              if (p == NULL)
00154               {
00155                 free (wmessage);
00156                 fputws_unlocked (L"out of memory\n", stderr);
00157                 return;
00158               }
00159              wmessage = p;
00160              use_malloc = true;
00161            }
00162 
00163          memset (&st, '\0', sizeof (st));
00164          tmp = message;
00165 
00166          res = mbsrtowcs (wmessage, &tmp, len, &st);
00167          if (res != len)
00168            break;
00169 
00170          if (__builtin_expect (len >= SIZE_MAX / 2, 0))
00171            {
00172              /* This really should not happen if everything is fine.  */
00173              res = (size_t) -1;
00174              break;
00175            }
00176 
00177          len *= 2;
00178        }
00179 
00180       if (res == (size_t) -1)
00181        {
00182          /* The string cannot be converted.  */
00183          if (use_malloc)
00184            {
00185              free (wmessage);
00186              use_malloc = false;
00187            }
00188          wmessage = (wchar_t *) L"???";
00189        }
00190 
00191       __vfwprintf (stderr, wmessage, args);
00192 
00193       if (use_malloc)
00194        free (wmessage);
00195     }
00196   else
00197 #endif
00198     vfprintf (stderr, message, args);
00199   va_end (args);
00200 
00201   ++error_message_count;
00202   if (errnum)
00203     print_errno_message (errnum);
00204 #if _LIBC
00205   __fxprintf (NULL, "\n");
00206 #else
00207   putc ('\n', stderr);
00208 #endif
00209   fflush (stderr);
00210   if (status)
00211     exit (status);
00212 }
00213 
00214 
00215 /* Print the program name and error message MESSAGE, which is a printf-style
00216    format string with optional args.
00217    If ERRNUM is nonzero, print its corresponding system error message.
00218    Exit with status STATUS if it is nonzero.  */
00219 void
00220 error (int status, int errnum, const char *message, ...)
00221 {
00222   va_list args;
00223 
00224 #if defined _LIBC && defined __libc_ptf_call
00225   /* We do not want this call to be cut short by a thread
00226      cancellation.  Therefore disable cancellation for now.  */
00227   int state = PTHREAD_CANCEL_ENABLE;
00228   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
00229                  0);
00230 #endif
00231 
00232   fflush (stdout);
00233 #ifdef _LIBC
00234   _IO_flockfile (stderr);
00235 #endif
00236   if (error_print_progname)
00237     (*error_print_progname) ();
00238   else
00239     {
00240 #if _LIBC
00241       __fxprintf (NULL, "%s: ", program_name);
00242 #else
00243       fprintf (stderr, "%s: ", program_name);
00244 #endif
00245     }
00246 
00247   va_start (args, message);
00248   error_tail (status, errnum, message, args);
00249 
00250 #ifdef _LIBC
00251   _IO_funlockfile (stderr);
00252 # ifdef __libc_ptf_call
00253   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
00254 # endif
00255 #endif
00256 }
00257 
00258 /* Sometimes we want to have at most one error per line.  This
00259    variable controls whether this mode is selected or not.  */
00260 int error_one_per_line;
00261 
00262 void
00263 error_at_line (int status, int errnum, const char *file_name,
00264               unsigned int line_number, const char *message, ...)
00265 {
00266   va_list args;
00267 
00268   if (error_one_per_line)
00269     {
00270       static const char *old_file_name;
00271       static unsigned int old_line_number;
00272 
00273       if (old_line_number == line_number
00274          && (file_name == old_file_name
00275              || strcmp (old_file_name, file_name) == 0))
00276        /* Simply return and print nothing.  */
00277        return;
00278 
00279       old_file_name = file_name;
00280       old_line_number = line_number;
00281     }
00282 
00283 #if defined _LIBC && defined __libc_ptf_call
00284   /* We do not want this call to be cut short by a thread
00285      cancellation.  Therefore disable cancellation for now.  */
00286   int state = PTHREAD_CANCEL_ENABLE;
00287   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
00288                  0);
00289 #endif
00290 
00291   fflush (stdout);
00292 #ifdef _LIBC
00293   _IO_flockfile (stderr);
00294 #endif
00295   if (error_print_progname)
00296     (*error_print_progname) ();
00297   else
00298     {
00299 #if _LIBC
00300       __fxprintf (NULL, "%s:", program_name);
00301 #else
00302       fprintf (stderr, "%s:", program_name);
00303 #endif
00304     }
00305 
00306 #if _LIBC
00307   __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
00308              file_name, line_number);
00309 #else
00310   fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
00311           file_name, line_number);
00312 #endif
00313 
00314   va_start (args, message);
00315   error_tail (status, errnum, message, args);
00316 
00317 #ifdef _LIBC
00318   _IO_funlockfile (stderr);
00319 # ifdef __libc_ptf_call
00320   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
00321 # endif
00322 #endif
00323 }
00324 
00325 #ifdef _LIBC
00326 /* Make the weak alias.  */
00327 # undef error
00328 # undef error_at_line
00329 weak_alias (__error, error)
00330 weak_alias (__error_at_line, error_at_line)
00331 #endif