X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Ferror.c;h=3177bd5d2cbc3802e3590e40732ca6c376762a31;hb=17ef7533a2d2a52e7d12448a76ffb06efeb3f47b;hp=858ad247785611bf5166b7d971c6a987c8df1552;hpb=c5467a5a59852da74dc849497f47b4966fcba269;p=gnulib.git
diff --git a/lib/error.c b/lib/error.c
index 858ad2477..3177bd5d2 100644
--- a/lib/error.c
+++ b/lib/error.c
@@ -1,22 +1,23 @@
/* Error handler for noninteractive utilities
- Copyright (C) 1990-1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ Copyright (C) 1990-1998, 2000-2007 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)
- any later version.
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
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 General Public License for more details.
- 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. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
/* Written by David MacKenzie . */
-#ifdef HAVE_CONFIG_H
+#if !_LIBC
# include
#endif
@@ -27,18 +28,20 @@
#include
#include
-#ifdef _LIBC
-# include
-#else
+#if !_LIBC && ENABLE_NLS
# include "gettext.h"
+# define _(msgid) gettext (msgid)
#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,14 +126,10 @@ 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
@@ -141,36 +144,61 @@ error_tail (int status, int errnum, const char *message, va_list args)
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
@@ -181,11 +209,10 @@ error_tail (int status, int errnum, const char *message, va_list args)
if (errnum)
print_errno_message (errnum);
#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- putwc (L'\n', stderr);
- else
+ __fxprintf (NULL, "\n");
+#else
+ putc ('\n', stderr);
#endif
- putc ('\n', stderr);
fflush (stderr);
if (status)
exit (status);
@@ -201,6 +228,14 @@ 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);
@@ -210,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);
@@ -222,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
}
@@ -250,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);
@@ -259,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
}