aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rwxr-xr-xconfigure30
-rw-r--r--include/stdio.h2
-rw-r--r--misc/Makefile15
-rw-r--r--misc/error.c77
-rw-r--r--misc/tst-error1.c26
-rw-r--r--stdio-common/Makefile2
-rw-r--r--stdio-common/fxprintf.c42
8 files changed, 195 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 72659d6fbf..dd4c6b89b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,42 @@
2005-07-19 Ulrich Drepper <drepper@redhat.com>
+ * 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.
+
* configure.in: Check for -fstack-protector gcc option.
* config.make.in (have-ssp): Add template.
* nscd/Makefile (nscd-cflags): Add -fstack-protector if supported.
diff --git a/configure b/configure
index 402da463f9..a449415c01 100755
--- a/configure
+++ b/configure
@@ -313,7 +313,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_cc_with_libunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie fno_unit_at_a_time libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_cc_with_libunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie fno_unit_at_a_time libc_cv_ssp libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -5799,6 +5799,33 @@ if test $libc_cv_fno_unit_at_a_time = yes; then
fi
+echo "$as_me:$LINENO: checking for -fstack-protector" >&5
+echo $ECHO_N "checking for -fstack-protector... $ECHO_C" >&6
+if test "${libc_cv_ssp+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.c <<EOF
+int foo;
+main () { return 0;}
+EOF
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fstack-protector
+ -o conftest conftest.c 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+then
+ libc_cv_ssp=yes
+else
+ libc_cv_ssp=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ssp" >&5
+echo "${ECHO_T}$libc_cv_ssp" >&6
+
+
if test $elf != yes; then
echo "$as_me:$LINENO: checking for .init and .fini sections" >&5
echo $ECHO_N "checking for .init and .fini sections... $ECHO_C" >&6
@@ -8434,6 +8461,7 @@ s,@libc_cv_z_combreloc@,$libc_cv_z_combreloc,;t t
s,@libc_cv_z_execstack@,$libc_cv_z_execstack,;t t
s,@libc_cv_fpie@,$libc_cv_fpie,;t t
s,@fno_unit_at_a_time@,$fno_unit_at_a_time,;t t
+s,@libc_cv_ssp@,$libc_cv_ssp,;t t
s,@libc_cv_have_initfini@,$libc_cv_have_initfini,;t t
s,@no_whole_archive@,$no_whole_archive,;t t
s,@exceptions@,$exceptions,;t t
diff --git a/include/stdio.h b/include/stdio.h
index c8c89ad878..5b47c53883 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -79,6 +79,8 @@ extern int __ftrylockfile (FILE *__stream);
extern int __getc_unlocked (FILE *__fp);
extern wint_t __getwc_unlocked (FILE *__fp);
+extern int __fxprintf (FILE *__fp, const char *__fmt, const wchar_t *__wfmt,
+ ...) __attribute__ ((__format__ (__printf__, 2, 4)));
extern __const char *__const _sys_errlist_internal[] attribute_hidden;
extern int _sys_nerr_internal attribute_hidden;
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"
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 2e797e4dfe..d860d75dee 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -40,7 +40,7 @@ install-others = $(inst_includedir)/bits/stdio_lim.h
include ../Makeconfig
-aux := errlist siglist printf-parsemb printf-parsewc
+aux := errlist siglist printf-parsemb printf-parsewc fxprintf
distribute := _itoa.h _itowa.h _i18n_number.h \
printf-parse.h stdio_lim.h.in tst-unbputc.sh tst-printf.sh
diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c
new file mode 100644
index 0000000000..82a2ac8bd7
--- /dev/null
+++ b/stdio-common/fxprintf.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@gnu.org>.
+
+ 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.
+
+ The GNU C Library 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.
+
+ 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. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+
+int
+__fxprintf (FILE *fp, const char *fmt, const wchar_t *wfmt, ...)
+{
+ if (fp == NULL)
+ fp = stderr;
+
+ va_list ap;
+ va_start (ap, wfmt);
+
+ int res;
+ if (_IO_fwide (fp, 0) > 0)
+ res = __vfwprintf (fp, wfmt, ap);
+ else
+ res = _IO_vfprintf (fp, fmt, ap);
+
+ va_end (ap);
+
+ return res;
+}