summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-07-19 23:46:55 +0000
committerUlrich Drepper <drepper@redhat.com>2005-07-19 23:46:55 +0000
commit10ffcd52f0578b13b48bdf84e73759353b29b673 (patch)
treead0a30eb784d7b5d2cb83c7bd12c4303f5901fac /misc
parent401a9ec9cad6fe21a6471f926152dbaff64d2212 (diff)
downloadglibc-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')
-rw-r--r--misc/Makefile15
-rw-r--r--misc/error.c77
-rw-r--r--misc/tst-error1.c26
3 files changed, 84 insertions, 34 deletions
diff --git a/misc/Makefile b/misc/Makefile
index 862eb1b800..cd5b64e7ab 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1991-2002, 2003, 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
@@ -65,6 +65,8 @@ routines := brk sbrk sstk ioctl \
distribute := device-nrs.h
+generated := tst-error1.mtrace tst-error1-mem
+
include ../Makeconfig
aux := init-misc
@@ -73,7 +75,11 @@ install-lib := libbsd-compat.a libg.a
endif
gpl2lgpl := error.c error.h
-tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch
+tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
+ tst-error1
+ifeq (no,$(cross-compiling))
+tests: $(objpfx)tst-error1-mem
+endif
CFLAGS-tsearch.c = $(uses-callbacks)
CFLAGS-lsearch.c = $(uses-callbacks)
@@ -106,3 +112,8 @@ endif
ifeq ($(build-bounded),yes)
$(objpfx)tst-tsearch-bp: $(common-objpfx)math/libm_b.a
endif
+
+tst-error1-ENV = MALLOC_TRACE=$(objpfx)tst-error1.mtrace
+tst-error1-ARGS = $(objpfx)tst-error1.out
+$(objpfx)tst-error1-mem: $(objpfx)tst-error1.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-error1.mtrace > $@
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
diff --git a/misc/tst-error1.c b/misc/tst-error1.c
new file mode 100644
index 0000000000..e84843ed2f
--- /dev/null
+++ b/misc/tst-error1.c
@@ -0,0 +1,26 @@
+#include <error.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+static int
+do_test (int argc, char *argv[])
+{
+ mtrace ();
+ (void) freopen (argc == 1 ? "/dev/stdout" : argv[1], "a", stderr);
+ /* Orient the stream. */
+ fwprintf (stderr, L"hello world\n");
+ char buf[20000];
+ static const char str[] = "hello world! ";
+ for (int i = 0; i < 1000; ++i)
+ memcpy (&buf[i * (sizeof (str) - 1)], str, sizeof (str));
+ error (0, 0, str);
+ error (0, 0, buf);
+ error (0, 0, buf);
+ error (0, 0, str);
+ return 0;
+}
+
+#define TEST_FUNCTION do_test (argc, argv)
+#include "../test-skeleton.c"