X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ferror.c;h=cf8634332020392497c23a438eef02aaaa0c71eb;hb=2386c2d9c0fba8dfaa939b831f00bb27ae771761;hp=31d3affcbd9804cbf176a84f9a25dfe8da38321d;hpb=9ecb52885659513fe468fa1b1dab6a7b4f2c1471;p=gnulib.git diff --git a/lib/error.c b/lib/error.c index 31d3affcb..cf8634332 100644 --- a/lib/error.c +++ b/lib/error.c @@ -1,5 +1,7 @@ /* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + 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) @@ -12,11 +14,11 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written by David MacKenzie . */ -#ifdef HAVE_CONFIG_H +#if !_LIBC # include #endif @@ -27,18 +29,19 @@ #include #include -#ifdef _LIBC -# include -#else +#if !_LIBC && ENABLE_NLS # include "gettext.h" #endif #ifdef _LIBC +# include +# include +# include # include # define mbsrtowcs __mbsrtowcs #endif -#if !_LIBC +#if USE_UNLOCKED_IO # include "unlocked-io.h" #endif @@ -58,6 +61,8 @@ unsigned int error_message_count; /* In the GNU C library, there is a predefined variable for this. */ # define program_name program_invocation_name +# include +# include # include /* In GNU libc we want do not want to use the common name `error' directly. @@ -76,6 +81,8 @@ extern void __error_at_line (int status, int errnum, const char *file_name, # undef putc # define putc(c, fp) INTUSE(_IO_putc) (c, fp) +# include + #else /* not _LIBC */ # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P @@ -91,7 +98,7 @@ extern char *program_name; # if HAVE_STRERROR_R || defined strerror_r # define __strerror_r strerror_r -# endif +# endif /* HAVE_STRERROR_R || defined strerror_r */ #endif /* not _LIBC */ static void @@ -119,77 +126,93 @@ print_errno_message (int errnum) #endif #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - { - __fwprintf (stderr, L": %s", s); - return; - } -#endif - + __fxprintf (NULL, ": %s", s); +#else fprintf (stderr, ": %s", s); +#endif } static void error_tail (int status, int errnum, const char *message, va_list args) { -# if HAVE_VPRINTF || _LIBC -# if _LIBC +#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; + bool use_malloc = false; - do + while (1) { - if (len < ALLOCA_LIMIT) + if (__libc_use_alloca (len * sizeof (wchar_t))) wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); else { - if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) + if (!use_malloc) wmessage = NULL; - wmessage = (wchar_t *) realloc (wmessage, - len * sizeof (wchar_t)); - - if (wmessage == NULL) + wchar_t *p = (wchar_t *) realloc (wmessage, + len * sizeof (wchar_t)); + if (p == NULL) { + free (wmessage); fputws_unlocked (L"out of memory\n", stderr); return; } + wmessage = p; + use_malloc = true; } memset (&st, '\0', sizeof (st)); - tmp =message; + tmp = message; + + res = mbsrtowcs (wmessage, &tmp, len, &st); + if (res != len) + break; + + if (__builtin_expect (len >= SIZE_MAX / 2, 0)) + { + /* This really should not happen if everything is fine. */ + res = (size_t) -1; + break; + } + + len *= 2; } - while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); if (res == (size_t) -1) - /* The string cannot be converted. */ - wmessage = (wchar_t *) L"???"; + { + /* The string cannot be converted. */ + if (use_malloc) + { + free (wmessage); + use_malloc = false; + } + wmessage = (wchar_t *) L"???"; + } __vfwprintf (stderr, wmessage, args); + + if (use_malloc) + free (wmessage); } else -# endif +#endif vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif va_end (args); ++error_message_count; if (errnum) print_errno_message (errnum); -# if _LIBC - if (_IO_fwide (stderr, 0) > 0) - putwc (L'\n', stderr); - else -# endif - putc ('\n', stderr); +#if _LIBC + __fxprintf (NULL, "\n"); +#else + putc ('\n', stderr); +#endif fflush (stderr); if (status) exit (status); @@ -200,12 +223,19 @@ error_tail (int status, int errnum, const char *message, va_list args) 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 error (int status, int errnum, const char *message, ...) { 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 _IO_flockfile (stderr); @@ -215,11 +245,10 @@ error (int status, int errnum, const char *message, ...) else { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s: ", program_name); - else + __fxprintf (NULL, "%s: ", program_name); +#else + fprintf (stderr, "%s: ", program_name); #endif - fprintf (stderr, "%s: ", program_name); } va_start (args, message); @@ -227,6 +256,9 @@ error (int status, int errnum, const char *message, ...) #ifdef _LIBC _IO_funlockfile (stderr); +# ifdef __libc_ptf_call + __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); +# endif #endif } @@ -255,6 +287,14 @@ error_at_line (int status, int errnum, const char *file_name, 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 _IO_flockfile (stderr); @@ -264,28 +304,28 @@ error_at_line (int status, int errnum, const char *file_name, else { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s: ", program_name); - else + __fxprintf (NULL, "%s:", program_name); +#else + fprintf (stderr, "%s:", program_name); #endif - fprintf (stderr, "%s:", program_name); } - if (file_name != NULL) - { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s:%d: ", file_name, line_number); - else + __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", + file_name, line_number); +#else + fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", + file_name, line_number); #endif - fprintf (stderr, "%s:%d: ", file_name, line_number); - } va_start (args, message); error_tail (status, errnum, message, args); #ifdef _LIBC _IO_funlockfile (stderr); +# ifdef __libc_ptf_call + __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); +# endif #endif }