diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-07-19 23:46:55 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-07-19 23:46:55 +0000 |
commit | 10ffcd52f0578b13b48bdf84e73759353b29b673 (patch) | |
tree | ad0a30eb784d7b5d2cb83c7bd12c4303f5901fac /misc/error.c | |
parent | 401a9ec9cad6fe21a6471f926152dbaff64d2212 (diff) | |
download | glibc-10ffcd52f0578b13b48bdf84e73759353b29b673.tar.gz |
* stdio-common/Makefile (aux): Add fxprintf.
* stdio-common/fxprintf.c: New file.
* include/stdio.h: Add declaration for stdio.h.
* argp/argp-fmtstream.c: Use __fxprintf instead of inline stream
orientation test and two separate function calls.
* argp/argp-help.c: Likewise.
* assert/assert-perr.c: Likewise.
* assert/assert.c: Likewise.
* gmon/gmon.c: Likewise.
* inet/rcmd.c: Likewise.
* malloc/obstack.c: Likewise.
* misc/error.c: Likewise.
* misc/getpass.c: Likewise.
* posix/getopt.c: Likewise.
* resolv/res_hconf.c: Likewise.
* stdio-common/perror.c: Likewise.
* stdio-common/psignal.c: Likewise.
* stdlib/fmtmsg.c: Likewise.
* sunrpc/auth_unix.c: Likewise.
* sunrpc/clnt_perr.c: Likewise.
* sunrpc/clnt_tcp.c: Likewise.
* sunrpc/clnt_udp.c: Likewise.
* sunrpc/clnt_unix.c: Likewise.
* sunrpc/svc_simple.c: Likewise.
* sunrpc/svc_tcp.c: Likewise.
* sunrpc/svc_udp.c: Likewise.
* sunrpc/svc_unix.c: Likewise.
* sunrpc/xdr.c: Likewise.
* sunrpc/xdr_array.c: Likewise.
* sunrpc/xdr_rec.c: Likewise.
* sunrpc/xdr_ref.c: Likewise.
* sysdeps/generic/wordexp.c: Likewise.
* misc/Makefile: Add rules to build and run tst-error1.
* misc/tst-error1.c: New file.
* misc/error.c: Fix memory leak and possibly endless loop.
Diffstat (limited to 'misc/error.c')
-rw-r--r-- | misc/error.c | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/misc/error.c b/misc/error.c index 2501583366..5f00ae97de 100644 --- a/misc/error.c +++ b/misc/error.c @@ -1,7 +1,6 @@ /* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000-2003, 2004 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-2004, 2005 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 @@ -74,6 +73,7 @@ unsigned int error_message_count; # define program_name program_invocation_name # include <errno.h> +# include <limits.h> # include <libio/libioP.h> /* In GNU libc we want do not want to use the common name `error' directly. @@ -158,14 +158,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", L": %s", s); +#else fprintf (stderr, ": %s", s); +#endif } #ifdef VA_START @@ -182,14 +178,15 @@ 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; wchar_t *p = (wchar_t *) realloc (wmessage, @@ -201,18 +198,38 @@ error_tail (int status, int errnum, const char *message, va_list args) return; } wmessage = p; + use_malloc = true; } memset (&st, '\0', sizeof (st)); tmp = message; + + res = mbsrtowcs (wmessage, &tmp, len, &st); + if (res != len) + break; + + if (__builtin_expect (len >= SIZE_MAX / 2, 0)) + { + /* This reallyy 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); + wmessage = (wchar_t *) L"???"; + } __vfwprintf (stderr, wmessage, args); + + if (use_malloc) + free (wmessage); } else # endif @@ -226,11 +243,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", L"\n"); +# else + putc ('\n', stderr); # endif - putc ('\n', stderr); fflush (stderr); if (status) exit (status); @@ -275,11 +291,10 @@ error (status, errnum, message, va_alist) else { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s: ", program_name); - else + __fxprintf (NULL, "%s: ", L"%s: ", program_name); +#else + fprintf (stderr, "%s: ", program_name); #endif - fprintf (stderr, "%s: ", program_name); } #ifdef VA_START @@ -359,21 +374,19 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) else { #if _LIBC - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s: ", program_name); - else + __fxprintf (NULL, "%s:", L"%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, "%s:%d: ", L"%s:%d: ", file_name, line_number); +#else + fprintf (stderr, "%s:%d: ", file_name, line_number); #endif - fprintf (stderr, "%s:%d: ", file_name, line_number); } #ifdef VA_START |