X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ferror.c;h=45698be8da0f2d3ec6b3a31508000293c992dd33;hb=b0df6af4ba3f1b975ae8a39c959862f9f4c37820;hp=b85b76d3230b800ac137d9f306c027b3065a2961;hpb=0a3f156068c386918fd8603d106effd9f31fd2fd;p=gnulib.git diff --git a/lib/error.c b/lib/error.c index b85b76d32..45698be8d 100644 --- a/lib/error.c +++ b/lib/error.c @@ -1,22 +1,20 @@ /* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. Its master source is NOT part of - the C library, however. The master source lives in /gd/gnu/lib. + Copyright (C) 1990-1998, 2000-2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. - The GNU C Library is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written by David MacKenzie . */ @@ -24,42 +22,24 @@ # include #endif +#include "error.h" + +#include #include -#if HAVE_LIBINTL_H -# include +#include +#include + +#if !_LIBC && ENABLE_NLS +# include "gettext.h" #endif + #ifdef _LIBC # include # define mbsrtowcs __mbsrtowcs #endif -#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC -# if __STDC__ -# include -# define VA_START(args, lastarg) va_start(args, lastarg) -# else -# include -# define VA_START(args, lastarg) va_start(args) -# endif -#else -# define va_alist a1, a2, a3, a4, a5, a6, a7, a8 -# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; -#endif - -#if STDC_HEADERS || _LIBC -# include -# include -#else -void exit (); -#endif - -#include "error.h" - -#ifndef HAVE_DECL_STRERROR_R -"this configure-time declaration test was not run" -#endif -#if !HAVE_DECL_STRERROR_R -char *strerror_r (); +#if USE_UNLOCKED_IO +# include "unlocked-io.h" #endif #ifndef _ @@ -69,11 +49,7 @@ char *strerror_r (); /* If NULL, error will flush stdout, then print on stderr the program name, a colon and a space. Otherwise, error will call this function without parameters instead. */ -void (*error_print_progname) ( -#if __STDC__ - 0 - void -#endif - ); +void (*error_print_progname) (void); /* This variable is incremented each time `error' is called. */ unsigned int error_message_count; @@ -83,6 +59,7 @@ unsigned int error_message_count; # define program_name program_invocation_name # include +# include /* In GNU libc we want do not want to use the common name `error' directly. Instead make it a weak alias. */ @@ -95,157 +72,141 @@ extern void __error_at_line (int status, int errnum, const char *file_name, # define error __error # define error_at_line __error_at_line -# ifdef USE_IN_LIBIO -# include -# define fflush(s) _IO_fflush (s) -# endif +# include +# define fflush(s) INTUSE(_IO_fflush) (s) +# undef putc +# define putc(c, fp) INTUSE(_IO_putc) (c, fp) + +# include #else /* not _LIBC */ +# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P +# ifndef HAVE_DECL_STRERROR_R +"this configure-time declaration test was not run" +# endif +char *strerror_r (); +# endif + +# ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +# endif + /* The calling program should define program_name and set it to the name of the executing program. */ extern char *program_name; -# ifdef HAVE_STRERROR_R +# if HAVE_STRERROR_R || defined strerror_r # define __strerror_r strerror_r -# else -# if HAVE_STRERROR -# ifndef strerror /* On some systems, strerror is a macro */ -char *strerror (); -# endif -# else -static char * -private_strerror (errnum) - int errnum; +# endif +#endif /* not _LIBC */ + +static void +print_errno_message (int errnum) { - extern char *sys_errlist[]; - extern int sys_nerr; + char const *s = NULL; - if (errnum > 0 && errnum <= sys_nerr) - return _(sys_errlist[errnum]); - return _("Unknown system error"); -} -# define strerror private_strerror -# endif /* HAVE_STRERROR */ -# endif /* HAVE_STRERROR_R */ -#endif /* not _LIBC */ +#if defined HAVE_STRERROR_R || _LIBC + char errbuf[1024]; +# if STRERROR_R_CHAR_P || _LIBC + s = __strerror_r (errnum, errbuf, sizeof errbuf); +# else + if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) + s = errbuf; +# endif +#endif +#if !_LIBC + if (! s && ! (s = strerror (errnum))) + s = _("Unknown system error"); +#endif + +#if _LIBC + if (_IO_fwide (stderr, 0) > 0) + { + __fwprintf (stderr, L": %s", s); + return; + } +#endif + + fprintf (stderr, ": %s", s); +} -#ifdef VA_START static void error_tail (int status, int errnum, const char *message, va_list args) { -# if HAVE_VPRINTF || _LIBC -# if _LIBC && USE_IN_LIBIO +#if _LIBC if (_IO_fwide (stderr, 0) > 0) { -# define ALLOCA_LIMIT 2000 +# define ALLOCA_LIMIT 2000 size_t len = strlen (message) + 1; - wchar_t *wmessage = NULL; - mbstate_t st; - size_t res; - const char *tmp; - - do + const wchar_t *wmessage = L"out of memory"; + wchar_t *wbuf = (len < ALLOCA_LIMIT + ? alloca (len * sizeof *wbuf) + : len <= SIZE_MAX / sizeof *wbuf + ? malloc (len * sizeof *wbuf) + : NULL); + + if (wbuf) { - if (len < ALLOCA_LIMIT) - wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); - else - { - if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) - wmessage = NULL; - - wmessage = (wchar_t *) realloc (wmessage, - len * sizeof (wchar_t)); - - if (wmessage == NULL) - { - fputws_unlocked (L"out of memory\n", stderr); - return; - } - } - + size_t res; + mbstate_t st; + const char *tmp = message; memset (&st, '\0', sizeof (st)); - tmp =message; + res = mbsrtowcs (wbuf, &tmp, len, &st); + wmessage = res == (size_t) -1 ? L"???" : wbuf; } - while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); - - if (res == (size_t) -1) - /* The string cannot be converted. */ - wmessage = (wchar_t *) L"???"; __vfwprintf (stderr, wmessage, args); + if (! (len < ALLOCA_LIMIT)) + free (wbuf); } else -# endif +#endif vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif va_end (args); ++error_message_count; if (errnum) - { -# if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; - char *s = __strerror_r (errnum, errbuf, sizeof errbuf); -# if _LIBC && USE_IN_LIBIO - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L": %s", s); - else -# endif - fprintf (stderr, ": %s", s); -# else - fprintf (stderr, ": %s", strerror (errnum)); -# endif - } -# if _LIBC && USE_IN_LIBIO + print_errno_message (errnum); +#if _LIBC if (_IO_fwide (stderr, 0) > 0) putwc (L'\n', stderr); else -# endif +#endif putc ('\n', stderr); fflush (stderr); if (status) exit (status); } -#endif /* Print the program name and error message MESSAGE, which is a printf-style format string with optional args. If ERRNUM is nonzero, print its corresponding system error message. Exit with status STATUS if it is nonzero. */ -/* VARARGS */ void -#if defined VA_START && __STDC__ error (int status, int errnum, const char *message, ...) -#else -error (status, errnum, message, va_alist) - int status; - int errnum; - char *message; - va_dcl -#endif { -#ifdef VA_START va_list args; + +#if defined _LIBC && defined __libc_ptf_call + /* We do not want this call to be cut short by a thread + cancellation. Therefore disable cancellation for now. */ + int state = PTHREAD_CANCEL_ENABLE; + __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), + 0); #endif fflush (stdout); #ifdef _LIBC -# ifdef USE_IN_LIBIO _IO_flockfile (stderr); -# else - __flockfile (stderr); -# endif #endif if (error_print_progname) (*error_print_progname) (); else { -#if _LIBC && USE_IN_LIBIO +#if _LIBC if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s: ", program_name); else @@ -253,36 +214,13 @@ error (status, errnum, message, va_alist) fprintf (stderr, "%s: ", program_name); } -#ifdef VA_START - VA_START (args, message); + va_start (args, message); error_tail (status, errnum, message, args); -#else - fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); - - ++error_message_count; - if (errnum) - { -# if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; - /* Don't use __strerror_r's return value because on some systems - (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ - __strerror_r (errnum, errbuf, sizeof errbuf); - fprintf (stderr, ": %s", errbuf); -# else - fprintf (stderr, ": %s", strerror (errnum)); -# endif - } - putc ('\n', stderr); - fflush (stderr); - if (status) - exit (status); -#endif #ifdef _LIBC -# ifdef USE_IN_LIBIO _IO_funlockfile (stderr); -# else - __funlockfile (stderr); +# ifdef __libc_ptf_call + __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); # endif #endif } @@ -292,22 +230,10 @@ error (status, errnum, message, va_alist) int error_one_per_line; void -#if defined VA_START && __STDC__ error_at_line (int status, int errnum, const char *file_name, unsigned int line_number, const char *message, ...) -#else -error_at_line (status, errnum, file_name, line_number, message, va_alist) - int status; - int errnum; - const char *file_name; - unsigned int line_number; - char *message; - va_dcl -#endif { -#ifdef VA_START va_list args; -#endif if (error_one_per_line) { @@ -324,19 +250,23 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) old_line_number = line_number; } +#if defined _LIBC && defined __libc_ptf_call + /* We do not want this call to be cut short by a thread + cancellation. Therefore disable cancellation for now. */ + int state = PTHREAD_CANCEL_ENABLE; + __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), + 0); +#endif + fflush (stdout); #ifdef _LIBC -# ifdef USE_IN_LIBIO _IO_flockfile (stderr); -# else - __flockfile (stderr); -# endif #endif if (error_print_progname) (*error_print_progname) (); else { -#if _LIBC && USE_IN_LIBIO +#if _LIBC if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s: ", program_name); else @@ -346,7 +276,7 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) if (file_name != NULL) { -#if _LIBC && USE_IN_LIBIO +#if _LIBC if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s:%d: ", file_name, line_number); else @@ -354,36 +284,13 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) fprintf (stderr, "%s:%d: ", file_name, line_number); } -#ifdef VA_START - VA_START (args, message); + va_start (args, message); error_tail (status, errnum, message, args); -#else - fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); - - ++error_message_count; - if (errnum) - { -# if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; - /* Don't use __strerror_r's return value because on some systems - (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ - __strerror_r (errnum, errbuf, sizeof errbuf); - fprintf (stderr, ": %s", errbuf); -# else - fprintf (stderr, ": %s", strerror (errnum)); -# endif - } - putc ('\n', stderr); - fflush (stderr); - if (status) - exit (status); -#endif #ifdef _LIBC -# ifdef USE_IN_LIBIO _IO_funlockfile (stderr); -# else - __funlockfile (stderr); +# ifdef __libc_ptf_call + __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); # endif #endif }