about summary refs log tree commit diff
path: root/libio
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
commit0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch)
tree2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /libio
parent7d58530341304d403a6626d7f7a1913165fe2f32 (diff)
downloadglibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.xz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip
2.5-18.1
Diffstat (limited to 'libio')
-rw-r--r--libio/Makefile12
-rw-r--r--libio/Versions3
-rw-r--r--libio/bits/libio-ldbl.h25
-rw-r--r--libio/bits/stdio-ldbl.h74
-rw-r--r--libio/bits/stdio.h12
-rw-r--r--libio/bits/stdio2.h69
-rw-r--r--libio/bug-memstream1.c133
-rw-r--r--libio/bug-wmemstream1.c136
-rw-r--r--libio/fileops.c39
-rw-r--r--libio/fmemopen.c30
-rw-r--r--libio/fputwc.c4
-rw-r--r--libio/fputwc_u.c4
-rw-r--r--libio/fwprintf.c6
-rw-r--r--libio/fwscanf.c6
-rw-r--r--libio/genops.c72
-rw-r--r--libio/getwc_u.c4
-rw-r--r--libio/iofclose.c4
-rw-r--r--libio/iofgets.c10
-rw-r--r--libio/iofgets_u.c10
-rw-r--r--libio/iofgetws.c10
-rw-r--r--libio/iofgetws_u.c10
-rw-r--r--libio/iofopncook.c34
-rw-r--r--libio/iofwide.c75
-rw-r--r--libio/iogetdelim.c10
-rw-r--r--libio/iogetline.c56
-rw-r--r--libio/iogetwline.c4
-rw-r--r--libio/ioungetwc.c4
-rw-r--r--libio/iovdprintf.c10
-rw-r--r--libio/iovsprintf.c14
-rw-r--r--libio/iovsscanf.c9
-rw-r--r--libio/iovswscanf.c11
-rw-r--r--libio/libc_fatal.c31
-rw-r--r--libio/libio.h57
-rw-r--r--libio/libioP.h242
-rw-r--r--libio/memstream.c15
-rw-r--r--libio/obprintf.c12
-rw-r--r--libio/oldfileops.c13
-rw-r--r--libio/oldiofclose.c4
-rw-r--r--libio/stdio.h66
-rw-r--r--libio/strfile.h13
-rw-r--r--libio/strops.c125
-rw-r--r--libio/swprintf.c6
-rw-r--r--libio/swscanf.c7
-rw-r--r--libio/tst-fopenloc2.c116
-rw-r--r--libio/tst-memstream1.c89
-rw-r--r--libio/tst-memstream2.c104
-rw-r--r--libio/tst-setvbuf1.c39
-rw-r--r--libio/tst-wmemstream1.c7
-rw-r--r--libio/tst-wmemstream2.c7
-rw-r--r--libio/vasprintf.c9
-rw-r--r--libio/vscanf.c7
-rw-r--r--libio/vsnprintf.c9
-rw-r--r--libio/vswprintf.c19
-rw-r--r--libio/vwprintf.c9
-rw-r--r--libio/vwscanf.c7
-rw-r--r--libio/wfiledoalloc.c32
-rw-r--r--libio/wfileops.c4
-rw-r--r--libio/wgenops.c12
-rw-r--r--libio/wmemstream.c150
-rw-r--r--libio/wprintf.c7
-rw-r--r--libio/wscanf.c7
-rw-r--r--libio/wstrops.c142
62 files changed, 1739 insertions, 528 deletions
diff --git a/libio/Makefile b/libio/Makefile
index a97623f14a..553fbda74a 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1995-2002,2003,2004,2006 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
@@ -22,7 +22,7 @@
 subdir	:= libio
 
 headers	:= stdio.h libio.h _G_config.h bits/stdio.h bits/stdio-lock.h \
-	   bits/sys_errlist.h bits/stdio2.h
+	   bits/sys_errlist.h bits/stdio2.h bits/stdio-ldbl.h bits/libio-ldbl.h
 
 routines	:=							      \
 	filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
@@ -35,7 +35,7 @@ routines	:=							      \
 	iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u	      \
 	putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf      \
 	wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops   \
-	wstrops wfileops iofwide fwide					      \
+	wstrops wfileops iofwide fwide wmemstream			      \
 									      \
 	clearerr feof ferror fileno fputc freopen fseek getc getchar	      \
 	memstream pclose putc putchar rewind setbuf setlinebuf vasprintf      \
@@ -54,7 +54,11 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
 	tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
 	tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \
 	tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \
-	bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4
+	bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \
+	tst-memstream1 tst-memstream2 \
+	tst-wmemstream1 tst-wmemstream2 \
+	bug-memstream1 bug-wmemstream1 \
+	tst-setvbuf1
 test-srcs = test-freopen
 
 all: # Make this the default target; it will be defined in Rules.
diff --git a/libio/Versions b/libio/Versions
index c870494872..e7a96daca5 100644
--- a/libio/Versions
+++ b/libio/Versions
@@ -145,6 +145,9 @@ libc {
     # w*
     wprintf; wscanf;
   }
+  GLIBC_2.4 {
+    open_wmemstream;
+  }
   GLIBC_PRIVATE {
     # Used by NPTL and librt
     __libc_fatal;
diff --git a/libio/bits/libio-ldbl.h b/libio/bits/libio-ldbl.h
new file mode 100644
index 0000000000..8674bcb0b8
--- /dev/null
+++ b/libio/bits/libio-ldbl.h
@@ -0,0 +1,25 @@
+/* -mlong-double-64 compatibility mode for libio functions.
+   Copyright (C) 2006 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
+   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.  */
+
+#ifndef _IO_STDIO_H
+# error "Never include <bits/libio-ldbl.h> directly; use <libio.h> instead."
+#endif
+
+__LDBL_REDIR_DECL (_IO_vfscanf)
+__LDBL_REDIR_DECL (_IO_vfprintf)
diff --git a/libio/bits/stdio-ldbl.h b/libio/bits/stdio-ldbl.h
new file mode 100644
index 0000000000..7a4291225e
--- /dev/null
+++ b/libio/bits/stdio-ldbl.h
@@ -0,0 +1,74 @@
+/* -mlong-double-64 compatibility mode for stdio functions.
+   Copyright (C) 2006 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
+   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.  */
+
+#ifndef _STDIO_H
+# error "Never include <bits/stdio-ldbl.h> directly; use <stdio.h> instead."
+#endif
+
+__BEGIN_NAMESPACE_STD
+__LDBL_REDIR_DECL (fprintf)
+__LDBL_REDIR_DECL (printf)
+__LDBL_REDIR_DECL (sprintf)
+__LDBL_REDIR_DECL (vfprintf)
+__LDBL_REDIR_DECL (vprintf)
+__LDBL_REDIR_DECL (vsprintf)
+__LDBL_REDIR_DECL (fscanf)
+__LDBL_REDIR_DECL (scanf)
+__LDBL_REDIR_DECL (sscanf)
+__END_NAMESPACE_STD
+
+#if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
+__BEGIN_NAMESPACE_C99
+__LDBL_REDIR_DECL (snprintf)
+__LDBL_REDIR_DECL (vsnprintf)
+__END_NAMESPACE_C99
+#endif
+
+#ifdef	__USE_ISOC99
+__BEGIN_NAMESPACE_C99
+__LDBL_REDIR_DECL (vfscanf)
+__LDBL_REDIR_DECL (vsscanf)
+__LDBL_REDIR_DECL (vscanf)
+__END_NAMESPACE_C99
+#endif
+
+#ifdef __USE_GNU
+__LDBL_REDIR_DECL (vdprintf)
+__LDBL_REDIR_DECL (dprintf)
+__LDBL_REDIR_DECL (vasprintf)
+__LDBL_REDIR_DECL (__asprintf)
+__LDBL_REDIR_DECL (asprintf)
+__LDBL_REDIR_DECL (obstack_printf)
+__LDBL_REDIR_DECL (obstack_vprintf)
+#endif
+
+#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+__LDBL_REDIR_DECL (__sprintf_chk)
+__LDBL_REDIR_DECL (__vsprintf_chk)
+# if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
+__LDBL_REDIR_DECL (__snprintf_chk)
+__LDBL_REDIR_DECL (__vsnprintf_chk)
+# endif
+# if __USE_FORTIFY_LEVEL > 1
+__LDBL_REDIR_DECL (__fprintf_chk)
+__LDBL_REDIR_DECL (__printf_chk)
+__LDBL_REDIR_DECL (__vfprintf_chk)
+__LDBL_REDIR_DECL (__vprintf_chk)
+# endif
+#endif
diff --git a/libio/bits/stdio.h b/libio/bits/stdio.h
index 9e951ad8e4..2d44fad1f5 100644
--- a/libio/bits/stdio.h
+++ b/libio/bits/stdio.h
@@ -1,5 +1,5 @@
 /* Optimizing macros and inline functions for stdio functions.
-   Copyright (C) 1998, 2000, 2001, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2000, 2001, 2004, 2007 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
@@ -44,6 +44,16 @@ getchar (void)
 }
 
 
+# ifdef __USE_MISC
+/* Faster version when locking is not necessary.  */
+__STDIO_INLINE int
+fgetc_unlocked (FILE *__fp)
+{
+  return _IO_getc_unlocked (__fp);
+}
+# endif /* misc */
+
+
 # if defined __USE_POSIX || defined __USE_MISC
 /* This is defined in POSIX.1:1996.  */
 __STDIO_INLINE int
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index acf07ea91b..f1d745c699 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -1,5 +1,5 @@
 /* Checking macros for stdio functions.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -49,7 +49,7 @@ extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
   __builtin___vsnprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
 			     fmt, ap)
 
-#endif			     
+#endif
 
 #if __USE_FORTIFY_LEVEL > 1
 
@@ -61,18 +61,67 @@ extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
 extern int __vprintf_chk (int __flag, __const char *__restrict __format,
 			  _G_va_list __ap);
 
-# define printf(...) \
+# if __GNUC_PREREQ (4, 0)
+#  define printf(...) \
   __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
-# define fprintf(stream, ...) \
+#  define fprintf(stream, ...) \
   __fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
-# define vprintf(format, ap) \
+#  define vprintf(format, ap) \
   __vprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
-# define vfprintf(stream, format, ap) \
+#  define vfprintf(stream, format, ap) \
   __vfprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
+# else
+#  define printf(...) \
+  __builtin___printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
+#  define fprintf(stream, ...) \
+  __builtin___fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
+#  define vprintf(format, ap) \
+  __builtin___vprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
+#  define vfprintf(stream, format, ap) \
+  __builtin___vfprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
+# endif
 
 #endif
 
-extern char *__gets_chk (char *__str, size_t);
-#define gets(__str) \
-  ((__bos (__str) == (size_t) -1)				\
-   ? (gets) (__str) : __gets_chk (__str, __bos (__str)))
+extern char *__gets_chk (char *__str, size_t) __wur;
+extern char *__REDIRECT (__gets_alias, (char *__str), gets) __wur;
+
+extern __always_inline __wur char *
+gets (char *__str)
+{
+  if (__bos (__str) != (size_t) -1)
+    return __gets_chk (__str, __bos (__str));
+  return __gets_alias (__str);
+}
+
+extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
+			  FILE *__restrict __stream) __wur;
+extern char *__REDIRECT (__fgets_alias,
+			 (char *__restrict __s, int __n,
+			  FILE *__restrict __stream), fgets) __wur;
+
+extern __always_inline __wur char *
+fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
+{
+  if (__bos (__s) != (size_t) -1
+      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
+    return __fgets_chk (__s, __bos (__s), __n, __stream);
+  return __fgets_alias (__s, __n, __stream);
+}
+
+#ifdef __USE_GNU
+extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
+				   int __n, FILE *__restrict __stream) __wur;
+extern char *__REDIRECT (__fgets_unlocked_alias,
+			 (char *__restrict __s, int __n,
+			  FILE *__restrict __stream), fgets_unlocked) __wur;
+
+extern __always_inline __wur char *
+fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
+{
+  if (__bos (__s) != (size_t) -1
+      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
+    return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream);
+  return __fgets_unlocked_alias (__s, __n, __stream);
+}
+#endif
diff --git a/libio/bug-memstream1.c b/libio/bug-memstream1.c
new file mode 100644
index 0000000000..8af36fee2d
--- /dev/null
+++ b/libio/bug-memstream1.c
@@ -0,0 +1,133 @@
+#include <stdio.h>
+#include <string.h>
+
+
+static int
+do_test (void)
+{
+  size_t size;
+  char *buf;
+  FILE *fp = open_memstream (&buf, &size);
+  if (fp == NULL)
+    {
+      puts ("open_memstream failed");
+      return 1;
+    }
+
+  off64_t off = ftello64 (fp);
+  if (off != 0)
+    {
+      puts ("initial position wrong");
+      return 1;
+    }
+
+  if (fseek (fp, 32768, SEEK_SET) != 0)
+    {
+      puts ("fseek failed");
+      return 1;
+    }
+
+  if (fputs ("foo", fp) == EOF)
+    {
+      puts ("fputs failed");
+      return 1;
+    }
+
+  if (fclose (fp) == EOF)
+    {
+      puts ("fclose failed");
+      return 1;
+    }
+
+  if (size != 32768 + 3)
+    {
+      printf ("expected size %d, got %zu\n", 32768 + 3, size);
+      return 1;
+    }
+
+  for (int i = 0; i < 32768; ++i)
+    if (buf[i] != '\0')
+      {
+	printf ("byte at offset %d is %#hhx\n", i, buf[i]);
+	return 1;
+      }
+
+  if (memcmp (buf + 32768, "foo", 3) != 0)
+    {
+      puts ("written string incorrect");
+      return 1;
+    }
+
+  /* Mark the buffer.  */
+  memset (buf, 'A', size);
+  free (buf);
+
+  /* Try again, this time with write mode enabled before the seek.  */
+  fp = open_memstream (&buf, &size);
+  if (fp == NULL)
+    {
+      puts ("2nd open_memstream failed");
+      return 1;
+    }
+
+  off = ftello64 (fp);
+  if (off != 0)
+    {
+      puts ("2nd initial position wrong");
+      return 1;
+    }
+
+  if (fputs ("bar", fp) == EOF)
+    {
+      puts ("2nd fputs failed");
+      return 1;
+    }
+
+  if (fseek (fp, 32768, SEEK_SET) != 0)
+    {
+      puts ("2nd fseek failed");
+      return 1;
+    }
+
+  if (fputs ("foo", fp) == EOF)
+    {
+      puts ("3rd fputs failed");
+      return 1;
+    }
+
+  if (fclose (fp) == EOF)
+    {
+      puts ("2nd fclose failed");
+      return 1;
+    }
+
+  if (size != 32768 + 3)
+    {
+      printf ("2nd expected size %d, got %zu\n", 32768 + 3, size);
+      return 1;
+    }
+
+  if (memcmp (buf, "bar", 3) != 0)
+    {
+      puts ("initial string incorrect in 2nd try");
+      return 1;
+    }
+
+  for (int i = 3; i < 32768; ++i)
+    if (buf[i] != '\0')
+      {
+	printf ("byte at offset %d is %#hhx in 2nd try\n", i, buf[i]);
+	return 1;
+      }
+
+  if (memcmp (buf + 32768, "foo", 3) != 0)
+    {
+      puts ("written string incorrect in 2nd try");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libio/bug-wmemstream1.c b/libio/bug-wmemstream1.c
new file mode 100644
index 0000000000..22d67f71e9
--- /dev/null
+++ b/libio/bug-wmemstream1.c
@@ -0,0 +1,136 @@
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+
+static int
+do_test (void)
+{
+  size_t size;
+  wchar_t *buf;
+  FILE *fp = open_wmemstream (&buf, &size);
+  if (fp == NULL)
+    {
+      puts ("open_wmemstream failed");
+      return 1;
+    }
+
+  off64_t off = ftello64 (fp);
+  if (off != 0)
+    {
+      puts ("initial position wrong");
+      return 1;
+    }
+
+  if (fseek (fp, 32768, SEEK_SET) != 0)
+    {
+      puts ("fseek failed");
+      return 1;
+    }
+
+  if (fputws (L"foo", fp) == EOF)
+    {
+      puts ("fputws failed");
+      return 1;
+    }
+
+  if (fclose (fp) == EOF)
+    {
+      puts ("fclose failed");
+      return 1;
+    }
+
+  if (size != 32768 + 3)
+    {
+      printf ("expected size %d, got %zu\n", 32768 + 3, size);
+      return 1;
+    }
+
+  for (int i = 0; i < 32768; ++i)
+    if (buf[i] != L'\0')
+      {
+	printf ("wide character at offset %d is %#x\n",
+		i, (unsigned int) buf[i]);
+	return 1;
+      }
+
+  if (wmemcmp (buf + 32768, L"foo", 3) != 0)
+    {
+      puts ("written string incorrect");
+      return 1;
+    }
+
+  /* Mark the buffer.  */
+  wmemset (buf, L'A', size);
+  free (buf);
+
+  /* Try again, this time with write mode enabled before the seek.  */
+  fp = open_wmemstream (&buf, &size);
+  if (fp == NULL)
+    {
+      puts ("2nd open_wmemstream failed");
+      return 1;
+    }
+
+  off = ftello64 (fp);
+  if (off != 0)
+    {
+      puts ("2nd initial position wrong");
+      return 1;
+    }
+
+  if (fputws (L"bar", fp) == EOF)
+    {
+      puts ("2nd fputws failed");
+      return 1;
+    }
+
+  if (fseek (fp, 32768, SEEK_SET) != 0)
+    {
+      puts ("2nd fseek failed");
+      return 1;
+    }
+
+  if (fputws (L"foo", fp) == EOF)
+    {
+      puts ("3rd fputws failed");
+      return 1;
+    }
+
+  if (fclose (fp) == EOF)
+    {
+      puts ("2nd fclose failed");
+      return 1;
+    }
+
+  if (size != 32768 + 3)
+    {
+      printf ("2nd expected size %d, got %zu\n", 32768 + 3, size);
+      return 1;
+    }
+
+  if (wmemcmp (buf, L"bar", 3) != 0)
+    {
+      puts ("initial string incorrect in 2nd try");
+      return 1;
+    }
+
+  for (int i = 3; i < 32768; ++i)
+    if (buf[i] != L'\0')
+      {
+	printf ("wide character at offset %d is %#x in 2nd try\n",
+		i, (unsigned int) buf[i]);
+	return 1;
+      }
+
+  if (wmemcmp (buf + 32768, L"foo", 3) != 0)
+    {
+      puts ("written string incorrect in 2nd try");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libio/fileops.c b/libio/fileops.c
index 19151cf188..886b3729c3 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995, 1997-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997-2005, 2006, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Per Bothner <bothner@cygnus.com>.
 
@@ -174,14 +175,8 @@ _IO_new_file_close_it (fp)
   close_status = _IO_SYSCLOSE (fp);
 
   /* Free buffer. */
-  if (fp->_mode <= 0)
-    {
-      INTUSE(_IO_setb) (fp, NULL, NULL, 0);
-      _IO_setg (fp, NULL, NULL, NULL);
-      _IO_setp (fp, NULL, NULL);
-    }
 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-  else
+  if (fp->_mode > 0)
     {
       if (_IO_have_wbackup (fp))
 	INTUSE(_IO_free_wbackup_area) (fp);
@@ -190,6 +185,9 @@ _IO_new_file_close_it (fp)
       _IO_wsetp (fp, NULL, NULL);
     }
 #endif
+  INTUSE(_IO_setb) (fp, NULL, NULL, 0);
+  _IO_setg (fp, NULL, NULL, NULL);
+  _IO_setp (fp, NULL, NULL);
 
   INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
   fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
@@ -399,6 +397,9 @@ _IO_new_file_fopen (fp, filename, mode, is32not64)
 	  /* And now the transliteration.  */
 	  cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
 
+	  /* From now on use the wide character callback functions.  */
+	  ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
+
 	  /* Set the mode now.  */
 	  result->_mode = 1;
 	}
@@ -472,7 +473,7 @@ _IO_file_setbuf_mmap (fp, p, len)
   return result;
 }
 
-static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t) __THROW;
+static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
 
 /* Write TO_DO bytes from DATA to FP.
    Then mark FP as having empty buffers. */
@@ -826,10 +827,10 @@ _IO_new_file_overflow (f, ch)
       return EOF;
     }
   /* If currently reading or no buffer allocated. */
-  if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == 0)
+  if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL)
     {
       /* Allocate a buffer if needed. */
-      if (f->_IO_write_base == 0)
+      if (f->_IO_write_base == NULL)
 	{
 	  INTUSE(_IO_doallocbuf) (f);
 	  _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
@@ -1281,7 +1282,7 @@ _IO_new_file_xsputn (f, data, n)
   register const char *s = (const char *) data;
   _IO_size_t to_do = n;
   int must_flush = 0;
-  _IO_size_t count;
+  _IO_size_t count = 0;
 
   if (n <= 0)
     return 0;
@@ -1290,7 +1291,6 @@ _IO_new_file_xsputn (f, data, n)
      (or the filebuf is unbuffered), use sys_write directly. */
 
   /* First figure out how much space is available in the buffer. */
-  count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
   if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
     {
       count = f->_IO_buf_end - f->_IO_write_ptr;
@@ -1308,6 +1308,9 @@ _IO_new_file_xsputn (f, data, n)
 	    }
 	}
     }
+  else if (f->_IO_write_end > f->_IO_write_ptr)
+    count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
+
   /* Then fill the buffer. */
   if (count > 0)
     {
@@ -1338,7 +1341,9 @@ _IO_new_file_xsputn (f, data, n)
       _IO_size_t block_size, do_write;
       /* Next flush the (full) buffer. */
       if (_IO_OVERFLOW (f, EOF) == EOF)
-	return n - to_do;
+	/* If nothing else has to be written we must not signal the
+	   caller that everything has been written.  */
+	return to_do == 0 ? EOF : n - to_do;
 
       /* Try to maintain alignment: write a whole number of blocks.
 	 dont_write is what gets left over. */
@@ -1464,8 +1469,7 @@ _IO_file_xsgetn (fp, data, n)
 }
 INTDEF(_IO_file_xsgetn)
 
-static _IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *, void *, _IO_size_t)
-     __THROW;
+static _IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *, void *, _IO_size_t);
 static _IO_size_t
 _IO_file_xsgetn_mmap (fp, data, n)
      _IO_FILE *fp;
@@ -1524,8 +1528,7 @@ _IO_file_xsgetn_mmap (fp, data, n)
   return s - (char *) data;
 }
 
-static _IO_size_t _IO_file_xsgetn_maybe_mmap (_IO_FILE *, void *, _IO_size_t)
-     __THROW;
+static _IO_size_t _IO_file_xsgetn_maybe_mmap (_IO_FILE *, void *, _IO_size_t);
 static _IO_size_t
 _IO_file_xsgetn_maybe_mmap (fp, data, n)
      _IO_FILE *fp;
diff --git a/libio/fmemopen.c b/libio/fmemopen.c
index ab6ffdd678..f3b280092c 100644
--- a/libio/fmemopen.c
+++ b/libio/fmemopen.c
@@ -1,5 +1,5 @@
 /* Fmemopen implementation.
-   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by  Hanno Mueller, kontakt@hanno.de, 2000.
 
@@ -27,8 +27,6 @@
  * but couldn't find it in libio. The following snippet of code is an
  * attempt to implement what glibc's documentation describes.
  *
- * No, it isn't really tested yet. :-)
- *
  *
  *
  * I already see some potential problems:
@@ -73,6 +71,7 @@
 #include <libio.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <sys/types.h>
 #include "libioP.h"
@@ -128,7 +127,7 @@ fmemopen_write (void *cookie, const char *b, size_t s)
       if ((size_t) (c->pos + addnullc) == c->size)
 	{
 	  __set_errno (ENOSPC);
-	  return -1;
+	  return 0;
 	}
       s = c->size - c->pos - addnullc;
     }
@@ -166,7 +165,7 @@ fmemopen_seek (void *cookie, _IO_off64_t *p, int w)
       break;
 
     case SEEK_END:
-      np = c->size - *p;
+      np = c->maxpos - *p;
       break;
 
     default:
@@ -176,9 +175,9 @@ fmemopen_seek (void *cookie, _IO_off64_t *p, int w)
   if (np < 0 || (size_t) np > c->size)
     return -1;
 
-  c->pos = np;
+  *p = c->pos = np;
 
-  return np;
+  return 0;
 }
 
 
@@ -203,6 +202,13 @@ fmemopen (void *buf, size_t len, const char *mode)
   cookie_io_functions_t iof;
   fmemopen_cookie_t *c;
 
+  if (__builtin_expect (len == 0, 0))
+    {
+    einval:
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
   c = (fmemopen_cookie_t *) malloc (sizeof (fmemopen_cookie_t));
   if (c == NULL)
     return NULL;
@@ -220,7 +226,15 @@ fmemopen (void *buf, size_t len, const char *mode)
       c->buffer[0] = '\0';
     }
   else
-    c->buffer = buf;
+    {
+      if (__builtin_expect ((uintptr_t) len > -(uintptr_t) buf, 0))
+	{
+	  free (c);
+	  goto einval;
+	}
+
+      c->buffer = buf;
+    }
 
   c->size = len;
 
diff --git a/libio/fputwc.c b/libio/fputwc.c
index 8c749435a0..42cf9d716c 100644
--- a/libio/fputwc.c
+++ b/libio/fputwc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1996,1997,1998,1999,2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1996,1997,1998,1999,2003, 2006 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
@@ -33,7 +33,7 @@ fputwc (wc, fp)
      wchar_t wc;
      _IO_FILE *fp;
 {
-  int result;
+  wint_t result;
   CHECK_FILE (fp, EOF);
   _IO_acquire_lock (fp);
   if (_IO_fwide (fp, 1) < 0)
diff --git a/libio/fputwc_u.c b/libio/fputwc_u.c
index 93cbcab3d3..0478410cca 100644
--- a/libio/fputwc_u.c
+++ b/libio/fputwc_u.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1999, 2006 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
@@ -35,7 +35,7 @@ fputwc_unlocked (wc, fp)
      wchar_t wc;
      _IO_FILE *fp;
 {
-  CHECK_FILE (fp, EOF);
+  CHECK_FILE (fp, WEOF);
   if (_IO_fwide (fp, 1) < 0)
     return WEOF;
   return _IO_putwc_unlocked (wc, fp);
diff --git a/libio/fwprintf.c b/libio/fwprintf.c
index cadeda04ab..9d9111d7c6 100644
--- a/libio/fwprintf.c
+++ b/libio/fwprintf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1997, 1999, 2000, 2001, 2006
+   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
@@ -16,6 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <wchar.h>
@@ -35,4 +37,4 @@ __fwprintf (FILE *stream, const wchar_t *format, ...)
 
   return done;
 }
-weak_alias (__fwprintf, fwprintf)
+ldbl_weak_alias (__fwprintf, fwprintf)
diff --git a/libio/fwscanf.c b/libio/fwscanf.c
index 411e1825c0..17296fa3d6 100644
--- a/libio/fwscanf.c
+++ b/libio/fwscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1997, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1997, 1999, 2000, 2006 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
@@ -16,6 +16,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <wchar.h>
@@ -23,7 +24,7 @@
 /* Read formatted input from STREAM according to the format string FORMAT.  */
 /* VARARGS2 */
 int
-fwscanf (FILE *stream, const wchar_t *format, ...)
+__fwscanf (FILE *stream, const wchar_t *format, ...)
 {
   va_list arg;
   int done;
@@ -34,3 +35,4 @@ fwscanf (FILE *stream, const wchar_t *format, ...)
 
   return done;
 }
+ldbl_strong_alias (__fwscanf, fwscanf)
diff --git a/libio/genops.c b/libio/genops.c
index 741ed77f86..8d62da7781 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993,1995,1997-2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995,1997-2002, 2003, 2004, 2006
+   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
@@ -32,6 +33,10 @@
 #include <stdlib.h>
 #endif
 #include <string.h>
+#include <stdbool.h>
+#ifdef _LIBC
+#include <sched.h>
+#endif
 
 #ifdef _IO_MTSAFE_IO
 static _IO_lock_t list_all_lock = _IO_lock_initializer;
@@ -362,7 +367,7 @@ __uflow (fp)
 #endif
 
   if (fp->_mode == 0)
-    _IO_fwide (fp, -11);
+    _IO_fwide (fp, -1);
   if (_IO_in_put_mode (fp))
     if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
       return EOF;
@@ -657,6 +662,7 @@ _IO_no_init (fp, flags, orientation, wd, jmp)
       fp->_wide_data->_wide_vtable = jmp;
     }
 #endif
+  fp->_freeres_list = NULL;
 }
 
 int
@@ -914,10 +920,27 @@ INTDEF(_IO_flush_all_linebuffered)
 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
 #endif
 
+
+/* The following is a bit tricky.  In general, we want to unbuffer the
+   streams so that all output which follows is seen.  If we are not
+   looking for memory leaks it does not make much sense to free the
+   actual buffer because this will happen anyway once the program
+   terminated.  If we do want to look for memory leaks we have to free
+   the buffers.  Whether something is freed is determined by the
+   function sin the libc_freeres section.  Those are called as part of
+   the atexit routine, just like _IO_cleanup.  The problem is we do
+   not know whether the freeres code is called first or _IO_cleanup.
+   if the former is the case, we set the DEALLOC_BUFFER variable to
+   true and _IO_unbuffer_write will take care of the rest.  If
+   _IO_unbuffer_write is called first we add the streams to a list
+   which the freeres function later can walk through.  */
 static void _IO_unbuffer_write (void);
 
+static bool dealloc_buffers;
+static _IO_FILE *freeres_list;
+
 static void
-_IO_unbuffer_write ()
+_IO_unbuffer_write (void)
 {
   struct _IO_FILE *fp;
   for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
@@ -927,7 +950,32 @@ _IO_unbuffer_write ()
 	      || (fp->_flags & _IO_IS_APPENDING))
 	  /* Iff stream is un-orientated, it wasn't used. */
 	  && fp->_mode != 0)
-	_IO_SETBUF (fp, NULL, 0);
+	{
+	  int cnt;
+#define MAXTRIES 2
+	  for (cnt = 0; cnt < MAXTRIES; ++cnt)
+	    if (_IO_lock_trylock (*fp->_lock) == 0)
+	      break;
+	    else
+	      /* Give the other thread time to finish up its use of the
+		 stream.  */
+	      __sched_yield ();
+
+	  if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
+	    {
+	      fp->_flags |= _IO_USER_BUF;
+
+	      fp->_freeres_list = freeres_list;
+	      freeres_list = fp;
+	      fp->_freeres_buf = fp->_IO_buf_base;
+	      fp->_freeres_size = _IO_blen (fp);
+	    }
+
+	  _IO_SETBUF (fp, NULL, 0);
+
+	  if (cnt < MAXTRIES)
+	    _IO_lock_unlock (*fp->_lock);
+	}
 
       /* Make sure that never again the wide char functions can be
 	 used.  */
@@ -935,11 +983,25 @@ _IO_unbuffer_write ()
     }
 }
 
+
+libc_freeres_fn (buffer_free)
+{
+  dealloc_buffers = true;
+
+  while (freeres_list != NULL)
+    {
+      FREE_BUF (freeres_list->_freeres_buf, freeres_list->_freeres_size);
+
+      freeres_list = freeres_list->_freeres_list;
+    }
+}
+
+
 int
 _IO_cleanup ()
 {
   /* We do *not* want locking.  Some threads might use streams but
-     that is there problem, we flush them underneath them.  */
+     that is their problem, we flush them underneath them.  */
   int result = _IO_flush_all_lockp (0);
 
   /* We currently don't have a reliable mechanism for making sure that
diff --git a/libio/getwc_u.c b/libio/getwc_u.c
index bdad3c8bf3..229343cc61 100644
--- a/libio/getwc_u.c
+++ b/libio/getwc_u.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1996,1997,1999,2000  Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995,1996,1997,1999,2000, 2006  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
@@ -33,7 +33,7 @@
 wint_t
 __getwc_unlocked (FILE *fp)
 {
-  CHECK_FILE (fp, EOF);
+  CHECK_FILE (fp, WEOF);
   return _IO_getwc_unlocked (fp);
 }
 
diff --git a/libio/iofclose.c b/libio/iofclose.c
index a372ae2b24..aa2ba40064 100644
--- a/libio/iofclose.c
+++ b/libio/iofclose.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1997-2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995,1997-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
@@ -62,8 +62,8 @@ _IO_new_fclose (fp)
     status = INTUSE(_IO_file_close_it) (fp);
   else
     status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
-  _IO_FINISH (fp);
   _IO_release_lock (fp);
+  _IO_FINISH (fp);
   if (fp->_mode > 0)
     {
 #if _LIBC
diff --git a/libio/iofgets.c b/libio/iofgets.c
index 879cc975a3..601b1746a1 100644
--- a/libio/iofgets.c
+++ b/libio/iofgets.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2002, 2003
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -41,6 +41,14 @@ _IO_fgets (buf, n, fp)
   CHECK_FILE (fp, NULL);
   if (n <= 0)
     return NULL;
+  if (__builtin_expect (n == 1, 0))
+    {
+      /* Another irregular case: since we have to store a NUL byte and
+	 there is only room for exactly one byte, we don't have to
+	 read anything.  */
+      buf[0] = '\0';
+      return buf;
+    }
   _IO_acquire_lock (fp);
   /* This is very tricky since a file descriptor may be in the
      non-blocking mode. The error flag doesn't mean much in this
diff --git a/libio/iofgets_u.c b/libio/iofgets_u.c
index ded2a7c83c..4fb5b1c0fd 100644
--- a/libio/iofgets_u.c
+++ b/libio/iofgets_u.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1996,1997,1998,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995-1998,2002,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
@@ -40,6 +40,14 @@ fgets_unlocked (buf, n, fp)
   CHECK_FILE (fp, NULL);
   if (n <= 0)
     return NULL;
+  if (__builtin_expect (n == 1, 0))
+    {
+      /* Another irregular case: since we have to store a NUL byte and
+	 there is only room for exactly one byte, we don't have to
+	 read anything.  */
+      buf[0] = '\0';
+      return buf;
+    }
   /* This is very tricky since a file descriptor may be in the
      non-blocking mode. The error flag doesn't mean much in this
      case. We return an error only when there is a new error. */
diff --git a/libio/iofgetws.c b/libio/iofgetws.c
index 654c051a28..775391137a 100644
--- a/libio/iofgetws.c
+++ b/libio/iofgetws.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2001
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2001, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -41,6 +41,14 @@ fgetws (buf, n, fp)
   CHECK_FILE (fp, NULL);
   if (n <= 0)
     return NULL;
+  if (__builtin_expect (n == 1, 0))
+    {
+      /* Another irregular case: since we have to store a NUL byte and
+	 there is only room for exactly one byte, we don't have to
+	 read anything.  */
+      buf[0] = L'\0';
+      return buf;
+    }
   _IO_acquire_lock (fp);
   /* This is very tricky since a file descriptor may be in the
      non-blocking mode. The error flag doesn't mean much in this
diff --git a/libio/iofgetws_u.c b/libio/iofgetws_u.c
index 1253564566..9fb8a5cac1 100644
--- a/libio/iofgetws_u.c
+++ b/libio/iofgetws_u.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99, 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
@@ -40,6 +40,14 @@ fgetws_unlocked (buf, n, fp)
   CHECK_FILE (fp, NULL);
   if (n <= 0)
     return NULL;
+  if (__builtin_expect (n == 1, 0))
+    {
+      /* Another irregular case: since we have to store a NUL byte and
+	 there is only room for exactly one byte, we don't have to
+	 read anything.  */
+      buf[0] = L'\0';
+      return buf;
+    }
   /* This is very tricky since a file descriptor may be in the
      non-blocking mode. The error flag doesn't mean much in this
      case. We return an error only when there is a new error. */
diff --git a/libio/iofopncook.c b/libio/iofopncook.c
index 321eb67b8d..976ff5093a 100644
--- a/libio/iofopncook.c
+++ b/libio/iofopncook.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993,95,97,99,2000,2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993,95,97,99,2000,2002,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
@@ -36,6 +37,8 @@ static _IO_ssize_t _IO_cookie_read (register _IO_FILE* fp, void* buf,
 static _IO_ssize_t _IO_cookie_write (register _IO_FILE* fp,
 				     const void* buf, _IO_ssize_t size);
 static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir);
+static _IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset,
+				       int dir, int mode);
 static int _IO_cookie_close (_IO_FILE* fp);
 
 static _IO_ssize_t
@@ -61,9 +64,16 @@ _IO_cookie_write (fp, buf, size)
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
 
   if (cfile->__io_functions.write == NULL)
-    return -1;
+    {
+      fp->_flags |= _IO_ERR_SEEN;
+      return 0;
+    }
+
+  _IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size);
+  if (n < size)
+    fp->_flags |= _IO_ERR_SEEN;
 
-  return cfile->__io_functions.write (cfile->__cookie, buf, size);
+  return n;
 }
 
 static _IO_off64_t
@@ -94,6 +104,20 @@ _IO_cookie_close (fp)
 }
 
 
+static _IO_off64_t
+_IO_cookie_seekoff (fp, offset, dir, mode)
+     _IO_FILE *fp;
+     _IO_off64_t offset;
+     int dir;
+     int mode;
+{
+  /* We must force the fileops code to always use seek to determine
+     the position.  */
+  fp->_offset = _IO_pos_BAD;
+  return INTUSE(_IO_file_seekoff) (fp, offset, dir, mode);
+}
+
+
 static const struct _IO_jump_t _IO_cookie_jumps = {
   JUMP_INIT_DUMMY,
   JUMP_INIT(finish, INTUSE(_IO_file_finish)),
@@ -103,7 +127,7 @@ static const struct _IO_jump_t _IO_cookie_jumps = {
   JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
   JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)),
   JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
-  JUMP_INIT(seekoff, INTUSE(_IO_file_seekoff)),
+  JUMP_INIT(seekoff, _IO_cookie_seekoff),
   JUMP_INIT(seekpos, _IO_default_seekpos),
   JUMP_INIT(setbuf, INTUSE(_IO_file_setbuf)),
   JUMP_INIT(sync, INTUSE(_IO_file_sync)),
@@ -223,7 +247,7 @@ static const struct _IO_jump_t _IO_old_cookie_jumps = {
   JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
   JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)),
   JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
-  JUMP_INIT(seekoff, INTUSE(_IO_file_seekoff)),
+  JUMP_INIT(seekoff, _IO_cookie_seekoff),
   JUMP_INIT(seekpos, _IO_default_seekpos),
   JUMP_INIT(setbuf, INTUSE(_IO_file_setbuf)),
   JUMP_INIT(sync, INTUSE(_IO_file_sync)),
diff --git a/libio/iofwide.c b/libio/iofwide.c
index 03124219ad..a9936687dd 100644
--- a/libio/iofwide.c
+++ b/libio/iofwide.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2003, 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
@@ -40,6 +40,7 @@
 # include <wcsmbs/wcsmbsload.h>
 # include <iconv/gconv_int.h>
 # include <shlib-compat.h>
+# include <sysdep.h>
 #endif
 
 
@@ -68,7 +69,7 @@ static int do_always_noconv (struct _IO_codecvt *codecvt);
 
 
 /* The functions used in `codecvt' for libio are always the same.  */
-struct _IO_codecvt __libio_codecvt =
+const struct _IO_codecvt __libio_codecvt =
 {
   .__codecvt_destr = NULL,		/* Destructor, never used.  */
   .__codecvt_do_out = do_out,
@@ -82,7 +83,7 @@ struct _IO_codecvt __libio_codecvt =
 
 
 #ifdef _LIBC
-struct __gconv_trans_data __libio_translit attribute_hidden =
+const struct __gconv_trans_data __libio_translit attribute_hidden =
 {
   .__trans_fct = __gconv_transliterate
 };
@@ -126,12 +127,11 @@ _IO_fwide (fp, mode)
 	 selected locale for LC_CTYPE.  */
 #ifdef _LIBC
       {
-	struct gconv_fcts fcts;
-
 	/* Clear the state.  We start all over again.  */
 	memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
 	memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
 
+	struct gconv_fcts fcts;
 	__wcsmbs_clone_conv (&fcts);
 	assert (fcts.towc_nsteps == 1);
 	assert (fcts.tomb_nsteps == 1);
@@ -159,7 +159,8 @@ _IO_fwide (fp, mode)
 	cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
 
 	/* And now the transliteration.  */
-	cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
+	cc->__cd_out.__cd.__data[0].__trans
+	  = (struct __gconv_trans_data  *) &__libio_translit;
       }
 #else
 # ifdef _GLIBCPP_USE_WCHAR_T
@@ -228,17 +229,23 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
   size_t dummy;
   const unsigned char *from_start_copy = (unsigned char *) from_start;
 
-  codecvt->__cd_out.__cd.__data[0].__outbuf = to_start;
-  codecvt->__cd_out.__cd.__data[0].__outbufend = to_end;
+  codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
+  codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
   codecvt->__cd_out.__cd.__data[0].__statep = statep;
 
-  status = DL_CALL_FCT (gs->__fct,
+  __gconv_fct fct = gs->__fct;
+#ifdef PTR_DEMANGLE
+  if (gs->__shlib_handle != NULL)
+    PTR_DEMANGLE (fct);
+#endif
+
+  status = DL_CALL_FCT (fct,
 			(gs, codecvt->__cd_out.__cd.__data, &from_start_copy,
 			 (const unsigned char *) from_end, NULL,
 			 &dummy, 0, 0));
 
   *from_stop = (wchar_t *) from_start_copy;
-  *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf;
+  *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
 
   switch (status)
     {
@@ -294,15 +301,21 @@ do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep,
   int status;
   size_t dummy;
 
-  codecvt->__cd_out.__cd.__data[0].__outbuf = to_start;
-  codecvt->__cd_out.__cd.__data[0].__outbufend = to_end;
+  codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
+  codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
   codecvt->__cd_out.__cd.__data[0].__statep = statep;
 
-  status = DL_CALL_FCT (gs->__fct,
+  __gconv_fct fct = gs->__fct;
+#ifdef PTR_DEMANGLE
+  if (gs->__shlib_handle != NULL)
+    PTR_DEMANGLE (fct);
+#endif
+
+  status = DL_CALL_FCT (fct,
 			(gs, codecvt->__cd_out.__cd.__data, NULL, NULL,
 			 NULL, &dummy, 1, 0));
 
-  *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf;
+  *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
 
   switch (status)
     {
@@ -357,15 +370,22 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
   size_t dummy;
   const unsigned char *from_start_copy = (unsigned char *) from_start;
 
-  codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_start;
-  codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) to_end;
+  codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_start;
+  codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) to_end;
   codecvt->__cd_in.__cd.__data[0].__statep = statep;
 
-  status = DL_CALL_FCT (gs->__fct,
+  __gconv_fct fct = gs->__fct;
+#ifdef PTR_DEMANGLE
+  if (gs->__shlib_handle != NULL)
+    PTR_DEMANGLE (fct);
+#endif
+
+  status = DL_CALL_FCT (fct,
 			(gs, codecvt->__cd_in.__cd.__data, &from_start_copy,
-			 from_end, NULL, &dummy, 0, 0));
+			 (const unsigned char *) from_end, NULL,
+			 &dummy, 0, 0));
 
-  *from_stop = from_start_copy;
+  *from_stop = (const char *) from_start_copy;
   *to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf;
 
   switch (status)
@@ -454,13 +474,20 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
   int status;
   size_t dummy;
 
-  codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_buf;
-  codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) &to_buf[max];
+  codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_buf;
+  codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) &to_buf[max];
   codecvt->__cd_in.__cd.__data[0].__statep = statep;
 
-  status = DL_CALL_FCT (gs->__fct,
-			(gs, codecvt->__cd_in.__cd.__data, &cp, from_end,
-			 NULL, &dummy, 0, 0));
+  __gconv_fct fct = gs->__fct;
+#ifdef PTR_DEMANGLE
+  if (gs->__shlib_handle != NULL)
+    PTR_DEMANGLE (fct);
+#endif
+
+  status = DL_CALL_FCT (fct,
+			(gs, codecvt->__cd_in.__cd.__data, &cp,
+			 (const unsigned char *) from_end, NULL,
+			 &dummy, 0, 0));
 
   result = cp - (const unsigned char *) from_start;
 #else
diff --git a/libio/iogetdelim.c b/libio/iogetdelim.c
index 3d0c976f9c..a362bf978a 100644
--- a/libio/iogetdelim.c
+++ b/libio/iogetdelim.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994,1996,1997,1998,2001,2003 Free Software Foundation, Inc.
+/* Copyright (C) 1994,1996-1998,2001,2003,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
@@ -45,7 +45,7 @@ _IO_getdelim (lineptr, n, delimiter, fp)
      int delimiter;
      _IO_FILE *fp;
 {
-  int result;
+  _IO_ssize_t result;
   _IO_ssize_t cur_len = 0;
   _IO_ssize_t len;
 
@@ -91,6 +91,12 @@ _IO_getdelim (lineptr, n, delimiter, fp)
       t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
       if (t != NULL)
 	len = (t - fp->_IO_read_ptr) + 1;
+      if (__builtin_expect (cur_len + len + 1 < 0, 0))
+	{
+	  __set_errno (EOVERFLOW);
+	  result = -1;
+	  goto unlock_return;
+	}
       /* Make enough space for len+1 (for final NUL) bytes.  */
       needed = cur_len + len + 1;
       if (needed > *n)
diff --git a/libio/iogetline.c b/libio/iogetline.c
index eca38cf773..022a444f77 100644
--- a/libio/iogetline.c
+++ b/libio/iogetline.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993,1997,1998,2000,2001,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1997,1998,2000,2001,2002,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
@@ -73,7 +74,8 @@ _IO_getline_info (fp, buf, n, delim, extract_delim, eof)
 	  int c = __uflow (fp);
 	  if (c == EOF)
 	    {
-	      if (eof) *eof = c;
+	      if (eof)
+		*eof = c;
 	      break;
 	    }
 	  if (c == delim)
@@ -89,31 +91,31 @@ _IO_getline_info (fp, buf, n, delim, extract_delim, eof)
 	  *ptr++ = c;
 	  n--;
 	}
-	else
-	  {
-	    char *t;
-	    if ((_IO_size_t) len >= n)
-	      len = n;
-	    t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len);
-	    if (t != NULL)
-	      {
-		_IO_size_t old_len = ptr-buf;
-		len = t - fp->_IO_read_ptr;
-		if (extract_delim >= 0)
-		  {
-		    ++t;
-		    if (extract_delim > 0)
-		      ++len;
-		  }
-		memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
-		fp->_IO_read_ptr = t;
-		return old_len + len;
-	      }
-	    memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
-	    fp->_IO_read_ptr += len;
-	    ptr += len;
-	    n -= len;
-	  }
+      else
+	{
+	  char *t;
+	  if ((_IO_size_t) len >= n)
+	    len = n;
+	  t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len);
+	  if (t != NULL)
+	    {
+	      _IO_size_t old_len = ptr-buf;
+	      len = t - fp->_IO_read_ptr;
+	      if (extract_delim >= 0)
+		{
+		  ++t;
+		  if (extract_delim > 0)
+		    ++len;
+		}
+	      memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
+	      fp->_IO_read_ptr = t;
+	      return old_len + len;
+	    }
+	  memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
+	  fp->_IO_read_ptr += len;
+	  ptr += len;
+	  n -= len;
+	}
     }
   return ptr - buf;
 }
diff --git a/libio/iogetwline.c b/libio/iogetwline.c
index e529b7d832..45db478423 100644
--- a/libio/iogetwline.c
+++ b/libio/iogetwline.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1997,1998,1999,2000,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1997-2000,2002,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
@@ -87,9 +87,9 @@ _IO_getwline_info (fp, buf, n, delim, extract_delim, eof)
 		*ptr++ = wc;
 	      else if (extract_delim < 0)
 		INTUSE(_IO_sputbackc) (fp, wc);
-	      return ptr - buf;
 	      if (extract_delim > 0)
 		++len;
+	      return ptr - buf;
 	    }
 	  *ptr++ = wc;
 	  n--;
diff --git a/libio/ioungetwc.c b/libio/ioungetwc.c
index 00d3e965b5..f7b6866617 100644
--- a/libio/ioungetwc.c
+++ b/libio/ioungetwc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -34,7 +34,7 @@ ungetwc (c, fp)
      wint_t c;
      _IO_FILE *fp;
 {
-  int result;
+  wint_t result;
   CHECK_FILE (fp, WEOF);
   _IO_acquire_lock (fp);
   _IO_fwide (fp, 1);
diff --git a/libio/iovdprintf.c b/libio/iovdprintf.c
index e81d870ca7..edab849a44 100644
--- a/libio/iovdprintf.c
+++ b/libio/iovdprintf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995,1997-2000,2001,2002,2003 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1997-2000, 2001, 2002, 2003, 2006
+   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
@@ -25,7 +26,7 @@
    This exception applies to code released by its copyright holders
    in files containing the exception.  */
 
-#include "libioP.h"
+#include <libioP.h>
 #include <stdio_ext.h>
 
 int
@@ -63,7 +64,4 @@ _IO_vdprintf (d, format, arg)
 
   return done;
 }
-
-#ifdef weak_alias
-weak_alias (_IO_vdprintf, vdprintf)
-#endif
+ldbl_weak_alias (_IO_vdprintf, vdprintf)
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
index b26a99b271..7fcd0a156e 100644
--- a/libio/iovsprintf.c
+++ b/libio/iovsprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997-2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2003, 2006 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
@@ -29,10 +29,7 @@
 #include "strfile.h"
 
 int
-_IO_vsprintf (string, format, args)
-     char *string;
-     const char *format;
-     _IO_va_list args;
+__IO_vsprintf (char *string, const char *format, _IO_va_list args)
 {
   _IO_strfile sf;
   int ret;
@@ -47,8 +44,7 @@ _IO_vsprintf (string, format, args)
   _IO_putc_unlocked ('\0', (_IO_FILE *) &sf._sbf);
   return ret;
 }
-INTDEF(_IO_vsprintf)
+INTDEF2(__IO_vsprintf, _IO_vsprintf)
 
-#ifdef weak_alias
-weak_alias (_IO_vsprintf, vsprintf)
-#endif
+ldbl_strong_alias (__IO_vsprintf, _IO_vsprintf)
+ldbl_weak_alias (__IO_vsprintf, vsprintf)
diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c
index 1a965c2d92..10e4b0a9ac 100644
--- a/libio/iovsscanf.c
+++ b/libio/iovsscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997-2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2003, 2006 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
@@ -45,8 +45,5 @@ _IO_vsscanf (string, format, args)
   ret = INTUSE(_IO_vfscanf) ((_IO_FILE *) &sf._sbf, format, args, NULL);
   return ret;
 }
-
-#ifdef weak_alias
-weak_alias (_IO_vsscanf, __vsscanf)
-weak_alias (_IO_vsscanf, vsscanf)
-#endif
+ldbl_weak_alias (_IO_vsscanf, __vsscanf)
+ldbl_weak_alias (_IO_vsscanf, vsscanf)
diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c
index 1bbddd442f..182d8da410 100644
--- a/libio/iovswscanf.c
+++ b/libio/iovswscanf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2000, 2001, 2002, 2006
+   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
@@ -30,10 +31,7 @@
 #include <wchar.h>
 
 int
-vswscanf (string, format, args)
-     const wchar_t *string;
-     const wchar_t *format;
-     _IO_va_list args;
+__vswscanf (const wchar_t *string, const wchar_t *format, _IO_va_list args)
 {
   int ret;
   _IO_strfile sf;
@@ -47,4 +45,5 @@ vswscanf (string, format, args)
   ret = _IO_vfwscanf ((_IO_FILE *) &sf._sbf, format, args, NULL);
   return ret;
 }
-libc_hidden_def (vswscanf)
+ldbl_hidden_def (__vswscanf, vswscanf)
+ldbl_strong_alias (__vswscanf, vswscanf)
diff --git a/libio/libc_fatal.c b/libio/libc_fatal.c
new file mode 100644
index 0000000000..be23849829
--- /dev/null
+++ b/libio/libc_fatal.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1993, 1995, 1997, 2003 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
+   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 <stdio.h>
+
+/* Abort with an error message.  */
+void
+__libc_fatal (message)
+     const char *message;
+{
+  /* This function should write MESSAGE out in the most reliable way.
+     It is called in situations like internal stdio lossage.  */
+
+  abort ();
+}
+libc_hidden_def (__libc_fatal)
diff --git a/libio/libio.h b/libio/libio.h
index 3b6facdddb..9df08614ee 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1995, 1997-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1995,1997-2005,2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Per Bothner <bothner@cygnus.com>.
 
@@ -142,6 +142,7 @@
 #ifdef _LIBC
 # define _IO_FLAGS2_FORTIFY 4
 #endif
+#define _IO_FLAGS2_USER_WBUF 8
 
 /* These are "formatting flags" matching the iostream fmtflags enum values. */
 #define _IO_SKIPWS 01
@@ -317,13 +318,19 @@ struct _IO_FILE_complete
   /* Wide character stream stuff.  */
   struct _IO_codecvt *_codecvt;
   struct _IO_wide_data *_wide_data;
+  struct _IO_FILE *_freeres_list;
+  void *_freeres_buf;
+  size_t _freeres_size;
 # else
   void *__pad1;
   void *__pad2;
+  void *__pad3;
+  void *__pad4;
+  size_t __pad5;
 # endif
   int _mode;
   /* Make sure we don't get into trouble again.  */
-  char _unused2[15 * sizeof (int) - 2 * sizeof (void *)];
+  char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
 #endif
 };
 
@@ -403,15 +410,15 @@ extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write,
 extern "C" {
 #endif
 
-extern int __underflow (_IO_FILE *) __THROW;
-extern int __uflow (_IO_FILE *) __THROW;
-extern int __overflow (_IO_FILE *, int) __THROW;
-extern _IO_wint_t __wunderflow (_IO_FILE *) __THROW;
-extern _IO_wint_t __wuflow (_IO_FILE *) __THROW;
-extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t) __THROW;
+extern int __underflow (_IO_FILE *);
+extern int __uflow (_IO_FILE *);
+extern int __overflow (_IO_FILE *, int);
+extern _IO_wint_t __wunderflow (_IO_FILE *);
+extern _IO_wint_t __wuflow (_IO_FILE *);
+extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t);
 
 #if  __GNUC__ >= 3
-# define _IO_BE(expr, res) __builtin_expect (expr, res)
+# define _IO_BE(expr, res) __builtin_expect ((expr), res)
 #else
 # define _IO_BE(expr, res) (expr)
 #endif
@@ -441,12 +448,12 @@ extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t) __THROW;
 #define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
 #define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
 
-extern int _IO_getc (_IO_FILE *__fp) __THROW;
-extern int _IO_putc (int __c, _IO_FILE *__fp) __THROW;
+extern int _IO_getc (_IO_FILE *__fp);
+extern int _IO_putc (int __c, _IO_FILE *__fp);
 extern int _IO_feof (_IO_FILE *__fp) __THROW;
 extern int _IO_ferror (_IO_FILE *__fp) __THROW;
 
-extern int _IO_peekc_locked (_IO_FILE *__fp) __THROW;
+extern int _IO_peekc_locked (_IO_FILE *__fp);
 
 /* This one is for Emacs. */
 #define _IO_PENDING_OUTPUT_COUNT(_fp)	\
@@ -472,20 +479,20 @@ extern int _IO_ftrylockfile (_IO_FILE *) __THROW;
 #endif /* !_IO_MTSAFE_IO */
 
 extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,
-			_IO_va_list, int *__restrict) __THROW;
+			_IO_va_list, int *__restrict);
 extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,
-			 _IO_va_list) __THROW;
-extern _IO_ssize_t _IO_padn (_IO_FILE *, int, _IO_ssize_t) __THROW;
-extern _IO_size_t _IO_sgetn (_IO_FILE *, void *, _IO_size_t) __THROW;
+			 _IO_va_list);
+extern _IO_ssize_t _IO_padn (_IO_FILE *, int, _IO_ssize_t);
+extern _IO_size_t _IO_sgetn (_IO_FILE *, void *, _IO_size_t);
 
-extern _IO_off64_t _IO_seekoff (_IO_FILE *, _IO_off64_t, int, int) __THROW;
-extern _IO_off64_t _IO_seekpos (_IO_FILE *, _IO_off64_t, int) __THROW;
+extern _IO_off64_t _IO_seekoff (_IO_FILE *, _IO_off64_t, int, int);
+extern _IO_off64_t _IO_seekpos (_IO_FILE *, _IO_off64_t, int);
 
 extern void _IO_free_backup_area (_IO_FILE *) __THROW;
 
 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-extern _IO_wint_t _IO_getwc (_IO_FILE *__fp) __THROW;
-extern _IO_wint_t _IO_putwc (wchar_t __wc, _IO_FILE *__fp) __THROW;
+extern _IO_wint_t _IO_getwc (_IO_FILE *__fp);
+extern _IO_wint_t _IO_putwc (wchar_t __wc, _IO_FILE *__fp);
 extern int _IO_fwide (_IO_FILE *__fp, int __mode) __THROW;
 # if __GNUC__ >= 2
 /* While compiling glibc we have to handle compatibility with very old
@@ -521,13 +528,17 @@ weak_extern (_IO_stdin_used);
 # endif
 
 extern int _IO_vfwscanf (_IO_FILE * __restrict, const wchar_t * __restrict,
-			 _IO_va_list, int *__restrict) __THROW;
+			 _IO_va_list, int *__restrict);
 extern int _IO_vfwprintf (_IO_FILE *__restrict, const wchar_t *__restrict,
-			  _IO_va_list) __THROW;
-extern _IO_ssize_t _IO_wpadn (_IO_FILE *, wint_t, _IO_ssize_t) __THROW;
+			  _IO_va_list);
+extern _IO_ssize_t _IO_wpadn (_IO_FILE *, wint_t, _IO_ssize_t);
 extern void _IO_free_wbackup_area (_IO_FILE *) __THROW;
 #endif
 
+#ifdef __LDBL_COMPAT
+# include <bits/libio-ldbl.h>
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libio/libioP.h b/libio/libioP.h
index 319b0fd5f3..a574b40f77 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1997-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2003,2004,2005,2006,2007
+	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
@@ -35,6 +36,8 @@
 /*# include <comthread.h>*/
 #endif
 
+#include <math_ldbl_opt.h>
+
 #include "iolibio.h"
 
 /* Control of exported symbols.  Used in glibc.  By default we don't
@@ -377,7 +380,7 @@ typedef struct _IO_FILE *_IO_ITER;
 
 extern void _IO_switch_to_main_get_area (_IO_FILE *) __THROW;
 extern void _IO_switch_to_backup_area (_IO_FILE *) __THROW;
-extern int _IO_switch_to_get_mode (_IO_FILE *) __THROW;
+extern int _IO_switch_to_get_mode (_IO_FILE *);
 extern void _IO_init (_IO_FILE *, int) __THROW;
 extern int _IO_sputbackc (_IO_FILE *, int) __THROW;
 extern int _IO_sungetc (_IO_FILE *) __THROW;
@@ -391,7 +394,7 @@ extern unsigned _IO_adjust_column (unsigned, const char *, int) __THROW;
 
 extern void _IO_switch_to_main_wget_area (_IO_FILE *) __THROW;
 extern void _IO_switch_to_wbackup_area (_IO_FILE *) __THROW;
-extern int _IO_switch_to_wget_mode (_IO_FILE *) __THROW;
+extern int _IO_switch_to_wget_mode (_IO_FILE *);
 extern void _IO_wsetb (_IO_FILE *, wchar_t *, wchar_t *, int) __THROW;
 extern wint_t _IO_sputbackwc (_IO_FILE *, wint_t) __THROW;
 extern wint_t _IO_sungetwc (_IO_FILE *) __THROW;
@@ -401,8 +404,8 @@ extern unsigned _IO_adjust_wcolumn (unsigned, const wchar_t *, int) __THROW;
 
 /* Marker-related function. */
 
-extern void _IO_init_marker (struct _IO_marker *, _IO_FILE *) __THROW;
-extern void _IO_init_wmarker (struct _IO_marker *, _IO_FILE *) __THROW;
+extern void _IO_init_marker (struct _IO_marker *, _IO_FILE *);
+extern void _IO_init_wmarker (struct _IO_marker *, _IO_FILE *);
 extern void _IO_remove_marker (struct _IO_marker *) __THROW;
 extern int _IO_marker_difference (struct _IO_marker *, struct _IO_marker *)
      __THROW;
@@ -431,22 +434,22 @@ libc_hidden_proto (_IO_list_resetlock)
 /* Default jumptable functions. */
 
 extern int _IO_default_underflow (_IO_FILE *) __THROW;
-extern int _IO_default_uflow (_IO_FILE *) __THROW;
-extern wint_t _IO_wdefault_uflow (_IO_FILE *) __THROW;
+extern int _IO_default_uflow (_IO_FILE *);
+extern wint_t _IO_wdefault_uflow (_IO_FILE *);
 extern int _IO_default_doallocate (_IO_FILE *) __THROW;
 extern int _IO_wdefault_doallocate (_IO_FILE *) __THROW;
 extern void _IO_default_finish (_IO_FILE *, int) __THROW;
 extern void _IO_wdefault_finish (_IO_FILE *, int) __THROW;
 extern int _IO_default_pbackfail (_IO_FILE *, int) __THROW;
 extern wint_t _IO_wdefault_pbackfail (_IO_FILE *, wint_t) __THROW;
-extern _IO_FILE* _IO_default_setbuf (_IO_FILE *, char *, _IO_ssize_t) __THROW;
+extern _IO_FILE* _IO_default_setbuf (_IO_FILE *, char *, _IO_ssize_t);
 extern _IO_size_t _IO_default_xsputn (_IO_FILE *, const void *, _IO_size_t);
 extern _IO_size_t _IO_wdefault_xsputn (_IO_FILE *, const void *, _IO_size_t);
 extern _IO_size_t _IO_default_xsgetn (_IO_FILE *, void *, _IO_size_t);
 extern _IO_size_t _IO_wdefault_xsgetn (_IO_FILE *, void *, _IO_size_t);
 extern _IO_off64_t _IO_default_seekoff (_IO_FILE *, _IO_off64_t, int, int)
      __THROW;
-extern _IO_off64_t _IO_default_seekpos (_IO_FILE *, _IO_off64_t, int) __THROW;
+extern _IO_off64_t _IO_default_seekpos (_IO_FILE *, _IO_off64_t, int);
 extern _IO_ssize_t _IO_default_write (_IO_FILE *, const void *, _IO_ssize_t);
 extern _IO_ssize_t _IO_default_read (_IO_FILE *, void *, _IO_ssize_t);
 extern int _IO_default_stat (_IO_FILE *, void *) __THROW;
@@ -469,23 +472,23 @@ extern const struct _IO_jump_t _IO_streambuf_jumps;
 extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden;
 extern const struct _IO_jump_t _IO_str_jumps attribute_hidden;
 extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden;
-extern struct _IO_codecvt __libio_codecvt attribute_hidden;
-extern int _IO_do_write (_IO_FILE *, const char *, _IO_size_t) __THROW;
-extern int _IO_new_do_write (_IO_FILE *, const char *, _IO_size_t) __THROW;
-extern int _IO_old_do_write (_IO_FILE *, const char *, _IO_size_t) __THROW;
-extern int _IO_wdo_write (_IO_FILE *, const wchar_t *, _IO_size_t) __THROW;
-extern int _IO_flush_all_lockp (int) __THROW;
-extern int _IO_flush_all (void) __THROW;
-extern int _IO_cleanup (void) __THROW;
-extern void _IO_flush_all_linebuffered (void) __THROW;
-extern int _IO_new_fgetpos (_IO_FILE *, _IO_fpos_t *) __THROW;
-extern int _IO_old_fgetpos (_IO_FILE *, _IO_fpos_t *) __THROW;
-extern int _IO_new_fsetpos (_IO_FILE *, const _IO_fpos_t *) __THROW;
-extern int _IO_old_fsetpos (_IO_FILE *, const _IO_fpos_t *) __THROW;
-extern int _IO_new_fgetpos64 (_IO_FILE *, _IO_fpos64_t *) __THROW;
-extern int _IO_old_fgetpos64 (_IO_FILE *, _IO_fpos64_t *) __THROW;
-extern int _IO_new_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *) __THROW;
-extern int _IO_old_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *) __THROW;
+extern const struct _IO_codecvt __libio_codecvt attribute_hidden;
+extern int _IO_do_write (_IO_FILE *, const char *, _IO_size_t);
+extern int _IO_new_do_write (_IO_FILE *, const char *, _IO_size_t);
+extern int _IO_old_do_write (_IO_FILE *, const char *, _IO_size_t);
+extern int _IO_wdo_write (_IO_FILE *, const wchar_t *, _IO_size_t);
+extern int _IO_flush_all_lockp (int);
+extern int _IO_flush_all (void);
+extern int _IO_cleanup (void);
+extern void _IO_flush_all_linebuffered (void);
+extern int _IO_new_fgetpos (_IO_FILE *, _IO_fpos_t *);
+extern int _IO_old_fgetpos (_IO_FILE *, _IO_fpos_t *);
+extern int _IO_new_fsetpos (_IO_FILE *, const _IO_fpos_t *);
+extern int _IO_old_fsetpos (_IO_FILE *, const _IO_fpos_t *);
+extern int _IO_new_fgetpos64 (_IO_FILE *, _IO_fpos64_t *);
+extern int _IO_old_fgetpos64 (_IO_FILE *, _IO_fpos64_t *);
+extern int _IO_new_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *);
+extern int _IO_old_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *);
 extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW;
 
 
@@ -531,95 +534,79 @@ extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW;
 /* Jumptable functions for files. */
 
 extern int _IO_file_doallocate (_IO_FILE *) __THROW;
-extern _IO_FILE* _IO_file_setbuf (_IO_FILE *, char *, _IO_ssize_t) __THROW;
-extern _IO_off64_t _IO_file_seekoff (_IO_FILE *, _IO_off64_t, int, int)
-     __THROW;
+extern _IO_FILE* _IO_file_setbuf (_IO_FILE *, char *, _IO_ssize_t);
+extern _IO_off64_t _IO_file_seekoff (_IO_FILE *, _IO_off64_t, int, int);
 extern _IO_off64_t _IO_file_seekoff_mmap (_IO_FILE *, _IO_off64_t, int, int)
      __THROW;
-extern _IO_size_t _IO_file_xsputn (_IO_FILE *, const void *, _IO_size_t)
-     __THROW;
-extern _IO_size_t _IO_file_xsgetn (_IO_FILE *, void *, _IO_size_t) __THROW;
+extern _IO_size_t _IO_file_xsputn (_IO_FILE *, const void *, _IO_size_t);
+extern _IO_size_t _IO_file_xsgetn (_IO_FILE *, void *, _IO_size_t);
 extern int _IO_file_stat (_IO_FILE *, void *) __THROW;
 extern int _IO_file_close (_IO_FILE *) __THROW;
 extern int _IO_file_close_mmap (_IO_FILE *) __THROW;
-extern int _IO_file_underflow (_IO_FILE *) __THROW;
-extern int _IO_file_underflow_mmap (_IO_FILE *) __THROW;
-extern int _IO_file_underflow_maybe_mmap (_IO_FILE *) __THROW;
-extern int _IO_file_overflow (_IO_FILE *, int) __THROW;
+extern int _IO_file_underflow (_IO_FILE *);
+extern int _IO_file_underflow_mmap (_IO_FILE *);
+extern int _IO_file_underflow_maybe_mmap (_IO_FILE *);
+extern int _IO_file_overflow (_IO_FILE *, int);
 #define _IO_file_is_open(__fp) ((__fp)->_fileno != -1)
 extern void _IO_file_init (struct _IO_FILE_plus *) __THROW;
-extern _IO_FILE* _IO_file_attach (_IO_FILE *, int) __THROW;
-extern _IO_FILE* _IO_file_open (_IO_FILE *, const char *, int, int, int, int)
-     __THROW;
+extern _IO_FILE* _IO_file_attach (_IO_FILE *, int);
+extern _IO_FILE* _IO_file_open (_IO_FILE *, const char *, int, int, int, int);
 libc_hidden_proto (_IO_file_open)
-extern _IO_FILE* _IO_file_fopen (_IO_FILE *, const char *, const char *, int)
-     __THROW;
-extern _IO_ssize_t _IO_file_write (_IO_FILE *, const void *, _IO_ssize_t)
-     __THROW;
-extern _IO_ssize_t _IO_file_read (_IO_FILE *, void *, _IO_ssize_t) __THROW;
-extern int _IO_file_sync (_IO_FILE *) __THROW;
-extern int _IO_file_close_it (_IO_FILE *) __THROW;
+extern _IO_FILE* _IO_file_fopen (_IO_FILE *, const char *, const char *, int);
+extern _IO_ssize_t _IO_file_write (_IO_FILE *, const void *, _IO_ssize_t);
+extern _IO_ssize_t _IO_file_read (_IO_FILE *, void *, _IO_ssize_t);
+extern int _IO_file_sync (_IO_FILE *);
+extern int _IO_file_close_it (_IO_FILE *);
 extern _IO_off64_t _IO_file_seek (_IO_FILE *, _IO_off64_t, int) __THROW;
-extern void _IO_file_finish (_IO_FILE *, int) __THROW;
+extern void _IO_file_finish (_IO_FILE *, int);
 
-extern _IO_FILE* _IO_new_file_attach (_IO_FILE *, int) __THROW;
-extern int _IO_new_file_close_it (_IO_FILE *) __THROW;
-extern void _IO_new_file_finish (_IO_FILE *, int) __THROW;
+extern _IO_FILE* _IO_new_file_attach (_IO_FILE *, int);
+extern int _IO_new_file_close_it (_IO_FILE *);
+extern void _IO_new_file_finish (_IO_FILE *, int);
 extern _IO_FILE* _IO_new_file_fopen (_IO_FILE *, const char *, const char *,
-				     int) __THROW;
+				     int);
 extern void _IO_no_init (_IO_FILE *, int, int, struct _IO_wide_data *,
 			 const struct _IO_jump_t *) __THROW;
 extern void _IO_new_file_init (struct _IO_FILE_plus *) __THROW;
-extern _IO_FILE* _IO_new_file_setbuf (_IO_FILE *, char *, _IO_ssize_t) __THROW;
-extern _IO_FILE* _IO_file_setbuf_mmap (_IO_FILE *, char *, _IO_ssize_t)
-     __THROW;
-extern int _IO_new_file_sync (_IO_FILE *) __THROW;
-extern int _IO_new_file_underflow (_IO_FILE *) __THROW;
-extern int _IO_new_file_overflow (_IO_FILE *, int) __THROW;
-extern _IO_off64_t _IO_new_file_seekoff (_IO_FILE *, _IO_off64_t, int, int)
-     __THROW;
-extern _IO_ssize_t _IO_new_file_write (_IO_FILE *, const void *, _IO_ssize_t)
-     __THROW;
-extern _IO_size_t _IO_new_file_xsputn (_IO_FILE *, const void *, _IO_size_t)
-     __THROW;
-
-extern _IO_FILE* _IO_old_file_setbuf (_IO_FILE *, char *, _IO_ssize_t) __THROW;
-extern _IO_off64_t _IO_old_file_seekoff (_IO_FILE *, _IO_off64_t, int, int)
-     __THROW;
-extern _IO_size_t _IO_old_file_xsputn (_IO_FILE *, const void *, _IO_size_t)
-     __THROW;
-extern int _IO_old_file_underflow (_IO_FILE *) __THROW;
-extern int _IO_old_file_overflow (_IO_FILE *, int) __THROW;
+extern _IO_FILE* _IO_new_file_setbuf (_IO_FILE *, char *, _IO_ssize_t);
+extern _IO_FILE* _IO_file_setbuf_mmap (_IO_FILE *, char *, _IO_ssize_t);
+extern int _IO_new_file_sync (_IO_FILE *);
+extern int _IO_new_file_underflow (_IO_FILE *);
+extern int _IO_new_file_overflow (_IO_FILE *, int);
+extern _IO_off64_t _IO_new_file_seekoff (_IO_FILE *, _IO_off64_t, int, int);
+extern _IO_ssize_t _IO_new_file_write (_IO_FILE *, const void *, _IO_ssize_t);
+extern _IO_size_t _IO_new_file_xsputn (_IO_FILE *, const void *, _IO_size_t);
+
+extern _IO_FILE* _IO_old_file_setbuf (_IO_FILE *, char *, _IO_ssize_t);
+extern _IO_off64_t _IO_old_file_seekoff (_IO_FILE *, _IO_off64_t, int, int);
+extern _IO_size_t _IO_old_file_xsputn (_IO_FILE *, const void *, _IO_size_t);
+extern int _IO_old_file_underflow (_IO_FILE *);
+extern int _IO_old_file_overflow (_IO_FILE *, int);
 extern void _IO_old_file_init (struct _IO_FILE_plus *) __THROW;
-extern _IO_FILE* _IO_old_file_attach (_IO_FILE *, int) __THROW;
-extern _IO_FILE* _IO_old_file_fopen (_IO_FILE *, const char *, const char *)
-     __THROW;
-extern _IO_ssize_t _IO_old_file_write (_IO_FILE *, const void *, _IO_ssize_t)
-     __THROW;
-extern int _IO_old_file_sync (_IO_FILE *) __THROW;
-extern int _IO_old_file_close_it (_IO_FILE *) __THROW;
-extern void _IO_old_file_finish (_IO_FILE *, int) __THROW;
+extern _IO_FILE* _IO_old_file_attach (_IO_FILE *, int);
+extern _IO_FILE* _IO_old_file_fopen (_IO_FILE *, const char *, const char *);
+extern _IO_ssize_t _IO_old_file_write (_IO_FILE *, const void *, _IO_ssize_t);
+extern int _IO_old_file_sync (_IO_FILE *);
+extern int _IO_old_file_close_it (_IO_FILE *);
+extern void _IO_old_file_finish (_IO_FILE *, int);
 
 extern int _IO_wfile_doallocate (_IO_FILE *) __THROW;
-extern _IO_size_t _IO_wfile_xsputn (_IO_FILE *, const void *, _IO_size_t)
-     __THROW;
-extern _IO_FILE* _IO_wfile_setbuf (_IO_FILE *, wchar_t *, _IO_ssize_t) __THROW;
-extern wint_t _IO_wfile_sync (_IO_FILE *) __THROW;
-extern wint_t _IO_wfile_underflow (_IO_FILE *) __THROW;
-extern wint_t _IO_wfile_overflow (_IO_FILE *, wint_t) __THROW;
-extern _IO_off64_t _IO_wfile_seekoff (_IO_FILE *, _IO_off64_t, int, int)
-     __THROW;
+extern _IO_size_t _IO_wfile_xsputn (_IO_FILE *, const void *, _IO_size_t);
+extern _IO_FILE* _IO_wfile_setbuf (_IO_FILE *, wchar_t *, _IO_ssize_t);
+extern wint_t _IO_wfile_sync (_IO_FILE *);
+extern wint_t _IO_wfile_underflow (_IO_FILE *);
+extern wint_t _IO_wfile_overflow (_IO_FILE *, wint_t);
+extern _IO_off64_t _IO_wfile_seekoff (_IO_FILE *, _IO_off64_t, int, int);
 
 /* Jumptable functions for proc_files. */
 extern _IO_FILE* _IO_proc_open (_IO_FILE *, const char *, const char *)
      __THROW;
 extern _IO_FILE* _IO_new_proc_open (_IO_FILE *, const char *, const char *)
      __THROW;
-extern _IO_FILE* _IO_old_proc_open (_IO_FILE *, const char *, const char *)
-     __THROW;
+extern _IO_FILE* _IO_old_proc_open (_IO_FILE *, const char *, const char *);
 extern int _IO_proc_close (_IO_FILE *) __THROW;
 extern int _IO_new_proc_close (_IO_FILE *) __THROW;
-extern int _IO_old_proc_close (_IO_FILE *) __THROW;
+extern int _IO_old_proc_close (_IO_FILE *);
 
 /* Jumptable functions for strfiles. */
 extern int _IO_str_underflow (_IO_FILE *) __THROW;
@@ -649,7 +636,7 @@ extern void _IO_wstr_finish (_IO_FILE *, int) __THROW;
 
 extern int _IO_vasprintf (char **result_ptr, __const char *format,
 			  _IO_va_list args) __THROW;
-extern int _IO_vdprintf (int d, __const char *format, _IO_va_list arg) __THROW;
+extern int _IO_vdprintf (int d, __const char *format, _IO_va_list arg);
 extern int _IO_vsnprintf (char *string, _IO_size_t maxlen,
 			  __const char *format, _IO_va_list args) __THROW;
 
@@ -657,73 +644,62 @@ extern int _IO_vsnprintf (char *string, _IO_size_t maxlen,
 extern _IO_size_t _IO_getline (_IO_FILE *,char *, _IO_size_t, int, int);
 extern _IO_size_t _IO_getline_info (_IO_FILE *,char *, _IO_size_t,
 				    int, int, int *);
-extern _IO_ssize_t _IO_getdelim (char **, _IO_size_t *, int, _IO_FILE *)
-     __THROW;
+extern _IO_ssize_t _IO_getdelim (char **, _IO_size_t *, int, _IO_FILE *);
 extern _IO_size_t _IO_getwline (_IO_FILE *,wchar_t *, _IO_size_t, wint_t, int);
 extern _IO_size_t _IO_getwline_info (_IO_FILE *,wchar_t *, _IO_size_t,
 				     wint_t, int, wint_t *);
-extern double _IO_strtod (const char *, char **) __THROW;
-extern char *_IO_dtoa (double __d, int __mode, int __ndigits,
-		       int *__decpt, int *__sign, char **__rve) __THROW;
-extern int _IO_outfloat (double __value, _IO_FILE *__sb, int __type,
-			 int __width, int __precision, int __flags,
-			 int __sign_mode, int __fill) __THROW;
 
 extern struct _IO_FILE_plus *_IO_list_all;
 extern void (*_IO_cleanup_registration_needed) (void);
 
 /* Prototype for functions with alternative entry point.  */
-extern int _IO_flush_all_internal (void) __THROW;
-extern unsigned _IO_adjust_column_internal (unsigned, const char *, int)
-     __THROW;
+extern int _IO_flush_all_internal (void);
+extern unsigned _IO_adjust_column_internal (unsigned, const char *, int);
 
-extern int _IO_default_uflow_internal (_IO_FILE *) __THROW;
+extern int _IO_default_uflow_internal (_IO_FILE *);
 extern void _IO_default_finish_internal (_IO_FILE *, int) __THROW;
 extern int _IO_default_pbackfail_internal (_IO_FILE *, int) __THROW;
 extern _IO_size_t _IO_default_xsputn_internal (_IO_FILE *, const void *,
-					       _IO_size_t) __THROW;
-extern _IO_size_t _IO_default_xsgetn_internal (_IO_FILE *, void *, _IO_size_t)
-     __THROW;
+					       _IO_size_t);
+extern _IO_size_t _IO_default_xsgetn_internal (_IO_FILE *, void *, _IO_size_t);
 extern int _IO_default_doallocate_internal (_IO_FILE *) __THROW;
 extern void _IO_wdefault_finish_internal (_IO_FILE *, int) __THROW;
 extern wint_t _IO_wdefault_pbackfail_internal (_IO_FILE *, wint_t) __THROW;
 extern _IO_size_t _IO_wdefault_xsputn_internal (_IO_FILE *, const void *,
-						_IO_size_t) __THROW;
+						_IO_size_t);
 extern _IO_size_t _IO_wdefault_xsgetn_internal (_IO_FILE *, void *,
-						_IO_size_t) __THROW;
+						_IO_size_t);
 extern int _IO_wdefault_doallocate_internal (_IO_FILE *) __THROW;
-extern wint_t _IO_wdefault_uflow_internal (_IO_FILE *) __THROW;
+extern wint_t _IO_wdefault_uflow_internal (_IO_FILE *);
 
 extern int _IO_file_doallocate_internal (_IO_FILE *) __THROW;
-extern _IO_FILE* _IO_file_setbuf_internal (_IO_FILE *, char *, _IO_ssize_t)
-     __THROW;
+extern _IO_FILE* _IO_file_setbuf_internal (_IO_FILE *, char *, _IO_ssize_t);
 extern _IO_off64_t _IO_file_seekoff_internal (_IO_FILE *, _IO_off64_t,
-					      int, int) __THROW;
+					      int, int);
 extern _IO_size_t _IO_file_xsputn_internal (_IO_FILE *, const void *,
-					    _IO_size_t) __THROW;
-extern _IO_size_t _IO_file_xsgetn_internal (_IO_FILE *, void *, _IO_size_t)
-     __THROW;
+					    _IO_size_t);
+extern _IO_size_t _IO_file_xsgetn_internal (_IO_FILE *, void *, _IO_size_t);
 extern int _IO_file_stat_internal (_IO_FILE *, void *) __THROW;
 extern int _IO_file_close_internal (_IO_FILE *) __THROW;
-extern int _IO_file_close_it_internal (_IO_FILE *) __THROW;
-extern int _IO_file_underflow_internal (_IO_FILE *) __THROW;
-extern int _IO_file_overflow_internal (_IO_FILE *, int) __THROW;
+extern int _IO_file_close_it_internal (_IO_FILE *);
+extern int _IO_file_underflow_internal (_IO_FILE *);
+extern int _IO_file_overflow_internal (_IO_FILE *, int);
 extern void _IO_file_init_internal (struct _IO_FILE_plus *) __THROW;
-extern _IO_FILE* _IO_file_attach_internal (_IO_FILE *, int) __THROW;
+extern _IO_FILE* _IO_file_attach_internal (_IO_FILE *, int);
 extern _IO_FILE* _IO_file_fopen_internal (_IO_FILE *, const char *,
-					  const char *, int) __THROW;
+					  const char *, int);
 extern _IO_ssize_t _IO_file_read_internal (_IO_FILE *, void *,
 					   _IO_ssize_t);
-extern int _IO_file_sync_internal (_IO_FILE *) __THROW;
+extern int _IO_file_sync_internal (_IO_FILE *);
 extern _IO_off64_t _IO_file_seek_internal (_IO_FILE *, _IO_off64_t, int)
      __THROW;
-extern void _IO_file_finish_internal (_IO_FILE *, int) __THROW;
+extern void _IO_file_finish_internal (_IO_FILE *, int);
 
 extern _IO_size_t _IO_wfile_xsputn_internal (_IO_FILE *, const void *,
-					     _IO_size_t) __THROW;
+					     _IO_size_t);
 extern _IO_off64_t _IO_wfile_seekoff_internal (_IO_FILE *, _IO_off64_t,
-					       int, int) __THROW;
-extern wint_t _IO_wfile_sync_internal (_IO_FILE *) __THROW;
+					       int, int);
+extern wint_t _IO_wfile_sync_internal (_IO_FILE *);
 
 extern int _IO_str_underflow_internal (_IO_FILE *) __THROW;
 extern int _IO_str_overflow_internal (_IO_FILE *, int) __THROW;
@@ -744,12 +720,12 @@ extern void _IO_wdoallocbuf_internal (_IO_FILE *) __THROW;
 
 extern _IO_size_t _IO_sgetn_internal (_IO_FILE *, void *, _IO_size_t);
 extern void _IO_flush_all_linebuffered_internal (void) __THROW;
-extern int _IO_switch_to_wget_mode_internal (_IO_FILE *) __THROW;
+extern int _IO_switch_to_wget_mode_internal (_IO_FILE *);
 extern void _IO_unsave_markers_internal (_IO_FILE *) __THROW;
 extern void _IO_switch_to_main_wget_area_internal (_IO_FILE *) __THROW;
 extern int _IO_wdo_write_internal (_IO_FILE *, const wchar_t *, _IO_size_t);
 extern int _IO_do_write_internal (_IO_FILE *, const char *, _IO_size_t);
-extern _IO_ssize_t _IO_padn_internal (_IO_FILE *, int, _IO_ssize_t) __THROW;
+extern _IO_ssize_t _IO_padn_internal (_IO_FILE *, int, _IO_ssize_t);
 extern _IO_size_t _IO_getline_info_internal (_IO_FILE *,char *, _IO_size_t,
 					     int, int, int *);
 extern _IO_size_t _IO_getline_internal (_IO_FILE *, char *, _IO_size_t, int,
@@ -759,7 +735,7 @@ extern void _IO_free_backup_area_internal (_IO_FILE *) __THROW;
 extern void _IO_switch_to_wbackup_area_internal (_IO_FILE *) __THROW;
 extern void _IO_setb_internal (_IO_FILE *, char *, char *, int) __THROW;
 extern wint_t _IO_sputbackwc_internal (_IO_FILE *, wint_t) __THROW;
-extern int _IO_switch_to_get_mode_internal (_IO_FILE *) __THROW;
+extern int _IO_switch_to_get_mode_internal (_IO_FILE *);
 extern int _IO_vfscanf_internal (_IO_FILE * __restrict,
 				 const char * __restrict,
 				 _IO_va_list, int *__restrict);
@@ -769,9 +745,9 @@ extern void _IO_doallocbuf_internal (_IO_FILE *) __THROW;
 extern void _IO_wsetb_internal (_IO_FILE *, wchar_t *, wchar_t *, int)
      __THROW;
 extern _IO_off64_t _IO_seekoff_unlocked (_IO_FILE *, _IO_off64_t, int, int)
-     attribute_hidden __THROW;
+     attribute_hidden;
 extern _IO_off64_t _IO_seekpos_unlocked (_IO_FILE *, _IO_off64_t, int)
-     attribute_hidden __THROW;
+     attribute_hidden;
 extern int _IO_putc_internal (int __c, _IO_FILE *__fp);
 extern void _IO_init_internal (_IO_FILE *, int) __THROW;
 extern void _IO_un_link_internal (struct _IO_FILE_plus *) __THROW;
@@ -863,12 +839,6 @@ extern void _IO_un_link_internal (struct _IO_FILE_plus *) __THROW;
 #ifndef OS_FSTAT
 # define OS_FSTAT fstat
 #endif
-struct stat;
-extern _IO_ssize_t _IO_read (int, void *, _IO_size_t);
-extern _IO_ssize_t _IO_write (int, const void *, _IO_size_t);
-extern _IO_off64_t _IO_lseek (int, _IO_off64_t, int) __THROW;
-extern int _IO_close (int);
-extern int _IO_fstat (int, struct stat *) __THROW;
 extern int _IO_vscanf (const char *, _IO_va_list) __THROW;
 
 /* _IO_pos_BAD is an _IO_off64_t value indicating error, unknown, or EOF. */
diff --git a/libio/memstream.c b/libio/memstream.c
index 4cc9ab2dfc..877383f3a8 100644
--- a/libio/memstream.c
+++ b/libio/memstream.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-97,99,2000,2002,2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1995-97,99,2000,2002-2004,2006 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
@@ -83,7 +83,7 @@ open_memstream (bufloc, sizeloc)
   new_f->fp._sf._sbf._f._lock = &new_f->lock;
 #endif
 
-  buf = malloc (_IO_BUFSIZ);
+  buf = calloc (1, _IO_BUFSIZ);
   if (buf == NULL)
     return NULL;
   INTUSE(_IO_init) (&new_f->fp._sf._sbf._f, 0);
@@ -106,11 +106,6 @@ _IO_mem_sync (fp)
      _IO_FILE* fp;
 {
   struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
-  int res;
-
-  res = _IO_default_sync (fp);
-  if (res < 0)
-    return res;
 
   if (fp->_IO_write_ptr == fp->_IO_write_end)
     {
@@ -140,9 +135,9 @@ _IO_mem_finish (fp, dummy)
     {
       (*mp->bufloc)[fp->_IO_write_ptr - fp->_IO_write_base] = '\0';
       *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base;
-    }
 
-  fp->_IO_buf_base = NULL;
+      fp->_IO_buf_base = NULL;
+    }
 
-  INTUSE(_IO_default_finish) (fp, 0);
+  _IO_str_finish (fp, 0);
 }
diff --git a/libio/obprintf.c b/libio/obprintf.c
index 19300e80a3..0a50c8e0fc 100644
--- a/libio/obprintf.c
+++ b/libio/obprintf.c
@@ -1,5 +1,6 @@
 /* Print output of stream to given obstack.
-   Copyright (C) 1996,1997,1999-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996,1997,1999,2000,2001,2002,2003,2004,2005,2006
+	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -23,6 +24,7 @@
 #include <stdlib.h>
 #endif
 #include "libioP.h"
+#include "strfile.h"
 #include <assert.h>
 #include <string.h>
 #include <errno.h>
@@ -174,9 +176,7 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
 
   return result;
 }
-#ifdef weak_alias
-weak_alias (_IO_obstack_vprintf, obstack_vprintf)
-#endif
+ldbl_weak_alias (_IO_obstack_vprintf, obstack_vprintf)
 
 
 int
@@ -189,6 +189,4 @@ _IO_obstack_printf (struct obstack *obstack, const char *format, ...)
   va_end (ap);
   return result;
 }
-#ifdef weak_alias
-weak_alias (_IO_obstack_printf, obstack_printf)
-#endif
+ldbl_weak_alias (_IO_obstack_printf, obstack_printf)
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index b9efca7aa8..3bd0aa175b 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995, 1997-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997-2004, 2005, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Per Bothner <bothner@cygnus.com>.
 
@@ -271,7 +272,7 @@ _IO_old_file_setbuf (fp, p, len)
     return fp;
 }
 
-static int old_do_write (_IO_FILE *, const char *, _IO_size_t) __THROW;
+static int old_do_write (_IO_FILE *, const char *, _IO_size_t);
 
 /* Write TO_DO bytes from DATA to FP.
    Then mark FP as having empty buffers. */
@@ -695,7 +696,7 @@ _IO_old_file_xsputn (f, data, n)
   register const char *s = (char *) data;
   _IO_size_t to_do = n;
   int must_flush = 0;
-  _IO_size_t count;
+  _IO_size_t count = 0;
 
   if (n <= 0)
     return 0;
@@ -704,7 +705,6 @@ _IO_old_file_xsputn (f, data, n)
      (or the filebuf is unbuffered), use sys_write directly. */
 
   /* First figure out how much space is available in the buffer. */
-  count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
   if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
     {
       count = f->_IO_buf_end - f->_IO_write_ptr;
@@ -722,6 +722,9 @@ _IO_old_file_xsputn (f, data, n)
 	    }
 	}
     }
+  else if (f->_IO_write_end > f->_IO_write_ptr)
+    count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
+
   /* Then fill the buffer. */
   if (count > 0)
     {
@@ -752,7 +755,7 @@ _IO_old_file_xsputn (f, data, n)
       _IO_size_t block_size, do_write;
       /* Next flush the (full) buffer. */
       if (__overflow (f, EOF) == EOF)
-	return n - to_do;
+	return to_do == 0 ? EOF : n - to_do;
 
       /* Try to maintain alignment: write a whole number of blocks.
 	 dont_write is what gets left over. */
diff --git a/libio/oldiofclose.c b/libio/oldiofclose.c
index 8dd321b054..62c3154118 100644
--- a/libio/oldiofclose.c
+++ b/libio/oldiofclose.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997-2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995,1997-2002,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
@@ -58,8 +58,8 @@ _IO_old_fclose (fp)
     status = _IO_old_file_close_it (fp);
   else
     status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
-  _IO_FINISH (fp);
   _IO_release_lock (fp);
+  _IO_FINISH (fp);
   if (_IO_have_backup (fp))
     INTUSE(_IO_free_backup_area) (fp);
   if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
diff --git a/libio/stdio.h b/libio/stdio.h
index e1081c9039..c8fe52cf31 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -1,5 +1,5 @@
 /* Define ISO C stdio on top of C++ iostreams.
-   Copyright (C) 1991,1994-2002,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1991,1994-2004,2005,2006 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
@@ -142,10 +142,12 @@ typedef _G_fpos64_t fpos64_t;
 extern struct _IO_FILE *stdin;		/* Standard input stream.  */
 extern struct _IO_FILE *stdout;		/* Standard output stream.  */
 extern struct _IO_FILE *stderr;		/* Standard error output stream.  */
+#ifdef __STDC__
 /* C89/C99 say they're macros.  Make them happy.  */
 #define stdin stdin
 #define stdout stdout
 #define stderr stderr
+#endif
 
 __BEGIN_NAMESPACE_STD
 /* Remove file FILENAME.  */
@@ -154,6 +156,11 @@ extern int remove (__const char *__filename) __THROW;
 extern int rename (__const char *__old, __const char *__new) __THROW;
 __END_NAMESPACE_STD
 
+#ifdef __USE_ATFILE
+/* Rename file OLD relative to OLDFD to NEW relative to NEWFD.  */
+extern int renameat (int __oldfd, __const char *__old, int __newfd,
+		     __const char *__new) __THROW;
+#endif
 
 __BEGIN_NAMESPACE_STD
 /* Create a temporary file and open it read/write.
@@ -286,8 +293,7 @@ extern FILE *fmemopen (void *__s, size_t __len, __const char *__modes) __THROW;
 /* Open a stream that writes into a malloc'd buffer that is expanded as
    necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
    and the number of characters written on fflush or fclose.  */
-extern FILE *open_memstream (char **__restrict __bufloc,
-			     size_t *__restrict __sizeloc) __THROW;
+extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __THROW;
 #endif
 
 
@@ -391,12 +397,12 @@ __BEGIN_NAMESPACE_STD
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern int fscanf (FILE *__restrict __stream,
-		   __const char *__restrict __format, ...);
+		   __const char *__restrict __format, ...) __wur;
 /* Read formatted input from stdin.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern int scanf (__const char *__restrict __format, ...);
+extern int scanf (__const char *__restrict __format, ...) __wur;
 /* Read formatted input from S.  */
 extern int sscanf (__const char *__restrict __s,
 		   __const char *__restrict __format, ...) __THROW;
@@ -410,14 +416,14 @@ __BEGIN_NAMESPACE_C99
    marked with __THROW.  */
 extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format,
 		    _G_va_list __arg)
-     __attribute__ ((__format__ (__scanf__, 2, 0)));
+     __attribute__ ((__format__ (__scanf__, 2, 0))) __wur;
 
 /* Read formatted input from stdin into argument list ARG.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern int vscanf (__const char *__restrict __format, _G_va_list __arg)
-     __attribute__ ((__format__ (__scanf__, 1, 0)));
+     __attribute__ ((__format__ (__scanf__, 1, 0))) __wur;
 
 /* Read formatted input from S into argument list ARG.  */
 extern int vsscanf (__const char *__restrict __s,
@@ -523,14 +529,15 @@ __BEGIN_NAMESPACE_STD
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream);
+extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
+     __wur;
 
 /* Get a newline-terminated string from stdin, removing the newline.
    DO NOT USE THIS FUNCTION!!  There is no limit on how much it will read.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern char *gets (char *__s);
+extern char *gets (char *__s) __wur;
 __END_NAMESPACE_STD
 
 #ifdef __USE_GNU
@@ -541,7 +548,7 @@ __END_NAMESPACE_STD
    or due to the implementation it is a cancellation point and
    therefore not marked with __THROW.  */
 extern char *fgets_unlocked (char *__restrict __s, int __n,
-			     FILE *__restrict __stream);
+			     FILE *__restrict __stream) __wur;
 #endif
 
 
@@ -558,10 +565,10 @@ extern char *fgets_unlocked (char *__restrict __s, int __n,
    therefore not marked with __THROW.  */
 extern _IO_ssize_t __getdelim (char **__restrict __lineptr,
 			       size_t *__restrict __n, int __delimiter,
-			       FILE *__restrict __stream);
+			       FILE *__restrict __stream) __wur;
 extern _IO_ssize_t getdelim (char **__restrict __lineptr,
 			     size_t *__restrict __n, int __delimiter,
-			     FILE *__restrict __stream);
+			     FILE *__restrict __stream) __wur;
 
 /* Like `getdelim', but reads up to a newline.
 
@@ -571,7 +578,7 @@ extern _IO_ssize_t getdelim (char **__restrict __lineptr,
    therefore not marked with __THROW.  */
 extern _IO_ssize_t getline (char **__restrict __lineptr,
 			    size_t *__restrict __n,
-			    FILE *__restrict __stream);
+			    FILE *__restrict __stream) __wur;
 #endif
 
 
@@ -601,13 +608,13 @@ extern int ungetc (int __c, FILE *__stream);
    This function is a possible cancellation points and therefore not
    marked with __THROW.  */
 extern size_t fread (void *__restrict __ptr, size_t __size,
-		     size_t __n, FILE *__restrict __stream);
+		     size_t __n, FILE *__restrict __stream) __wur;
 /* Write chunks of generic data to STREAM.
 
    This function is a possible cancellation points and therefore not
    marked with __THROW.  */
 extern size_t fwrite (__const void *__restrict __ptr, size_t __size,
-		      size_t __n, FILE *__restrict __s);
+		      size_t __n, FILE *__restrict __s) __wur;
 __END_NAMESPACE_STD
 
 #ifdef __USE_GNU
@@ -629,9 +636,9 @@ extern int fputs_unlocked (__const char *__restrict __s,
    or due to the implementation they are cancellation points and
    therefore not marked with __THROW.  */
 extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
-			      size_t __n, FILE *__restrict __stream);
+			      size_t __n, FILE *__restrict __stream) __wur;
 extern size_t fwrite_unlocked (__const void *__restrict __ptr, size_t __size,
-			       size_t __n, FILE *__restrict __stream);
+			       size_t __n, FILE *__restrict __stream) __wur;
 #endif
 
 
@@ -645,7 +652,7 @@ extern int fseek (FILE *__stream, long int __off, int __whence);
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern long int ftell (FILE *__stream);
+extern long int ftell (FILE *__stream) __wur;
 /* Rewind to the beginning of STREAM.
 
    This function is a possible cancellation point and therefore not
@@ -669,7 +676,7 @@ extern int fseeko (FILE *__stream, __off_t __off, int __whence);
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern __off_t ftello (FILE *__stream);
+extern __off_t ftello (FILE *__stream) __wur;
 # else
 #  ifdef __REDIRECT
 extern int __REDIRECT (fseeko,
@@ -710,7 +717,7 @@ __END_NAMESPACE_STD
 
 #ifdef __USE_LARGEFILE64
 extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence);
-extern __off64_t ftello64 (FILE *__stream);
+extern __off64_t ftello64 (FILE *__stream) __wur;
 extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos);
 extern int fsetpos64 (FILE *__stream, __const fpos64_t *__pos);
 #endif
@@ -719,16 +726,16 @@ __BEGIN_NAMESPACE_STD
 /* Clear the error and EOF indicators for STREAM.  */
 extern void clearerr (FILE *__stream) __THROW;
 /* Return the EOF indicator for STREAM.  */
-extern int feof (FILE *__stream) __THROW;
+extern int feof (FILE *__stream) __THROW __wur;
 /* Return the error indicator for STREAM.  */
-extern int ferror (FILE *__stream) __THROW;
+extern int ferror (FILE *__stream) __THROW __wur;
 __END_NAMESPACE_STD
 
 #ifdef __USE_MISC
 /* Faster versions when locking is not required.  */
 extern void clearerr_unlocked (FILE *__stream) __THROW;
-extern int feof_unlocked (FILE *__stream) __THROW;
-extern int ferror_unlocked (FILE *__stream) __THROW;
+extern int feof_unlocked (FILE *__stream) __THROW __wur;
+extern int ferror_unlocked (FILE *__stream) __THROW __wur;
 #endif
 
 
@@ -749,12 +756,12 @@ __END_NAMESPACE_STD
 
 #ifdef	__USE_POSIX
 /* Return the system file descriptor for STREAM.  */
-extern int fileno (FILE *__stream) __THROW;
+extern int fileno (FILE *__stream) __THROW __wur;
 #endif /* Use POSIX.  */
 
 #ifdef __USE_MISC
 /* Faster version when locking is not required.  */
-extern int fileno_unlocked (FILE *__stream) __THROW;
+extern int fileno_unlocked (FILE *__stream) __THROW __wur;
 #endif
 
 
@@ -764,7 +771,7 @@ extern int fileno_unlocked (FILE *__stream) __THROW;
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern FILE *popen (__const char *__command, __const char *__modes);
+extern FILE *popen (__const char *__command, __const char *__modes) __wur;
 
 /* Close a stream opened by popen and return the status of its child.
 
@@ -808,7 +815,7 @@ extern void flockfile (FILE *__stream) __THROW;
 
 /* Try to acquire ownership of STREAM but do not block if it is not
    possible.  */
-extern int ftrylockfile (FILE *__stream) __THROW;
+extern int ftrylockfile (FILE *__stream) __THROW __wur;
 
 /* Relinquish the ownership granted for STREAM.  */
 extern void funlockfile (FILE *__stream) __THROW;
@@ -830,6 +837,9 @@ extern void funlockfile (FILE *__stream) __THROW;
 #if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
 # include <bits/stdio2.h>
 #endif
+#ifdef __LDBL_COMPAT
+# include <bits/stdio-ldbl.h>
+#endif
 
 __END_DECLS
 
diff --git a/libio/strfile.h b/libio/strfile.h
index b91111a9d6..53a36a3db8 100644
--- a/libio/strfile.h
+++ b/libio/strfile.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999, 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
@@ -73,3 +73,14 @@ typedef struct
 } _IO_strnfile;
 
 extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
+
+
+typedef struct
+{
+  _IO_strfile f;
+  /* This is used for the characters which do not fit in the buffer
+     provided by the user.  */
+  wchar_t overflow_buf[64];
+} _IO_wstrnfile;
+
+extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden;
diff --git a/libio/strops.c b/libio/strops.c
index 2de83403a2..05270ce407 100644
--- a/libio/strops.c
+++ b/libio/strops.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2003, 2004, 2006 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
@@ -25,43 +25,12 @@
    This exception applies to code released by its copyright holders
    in files containing the exception.  */
 
+#include <assert.h>
 #include "strfile.h"
 #include "libioP.h"
 #include <string.h>
 #include <stdio_ext.h>
 
-#if 0
-/* The following definitions are for exposition only.
-   They map the terminology used in the ANSI/ISO C++ draft standard
-   to the implementation. */
-
-/* allocated:  set  when a dynamic array object has been allocated, and
-   hence should be freed by the destructor for the strstreambuf object. */
-#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
-
-/* constant:  set when the array object has const elements,
-   so the output sequence cannot be written. */
-#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
-
-/* alsize:  the suggested minimum size for a dynamic array object. */
-#define ALSIZE(FP) ??? /* not stored */
-
-/* palloc: points to the function to call to allocate a dynamic array object.*/
-#define PALLOC(FP) \
-  ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
-
-/* pfree: points  to  the  function  to call to free a dynamic array object. */
-#define PFREE(FP) \
-  ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
-
-#endif
-
-#ifdef TODO
-/* An "unbounded buffer" is when a buffer is supplied, but with no
-   specified length.  An example is the buffer argument to sprintf.
-   */
-#endif
-
 void
 _IO_str_init_static_internal (sf, ptr, size, pstart)
      _IO_strfile *sf;
@@ -134,7 +103,7 @@ _IO_str_overflow (fp, c)
       fp->_IO_write_ptr = fp->_IO_read_ptr;
       fp->_IO_read_ptr = fp->_IO_read_end;
     }
-  pos =  fp->_IO_write_ptr - fp->_IO_write_base;
+  pos = fp->_IO_write_ptr - fp->_IO_write_base;
   if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
     {
       if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
@@ -143,7 +112,10 @@ _IO_str_overflow (fp, c)
 	{
 	  char *new_buf;
 	  char *old_buf = fp->_IO_buf_base;
-	  _IO_size_t new_size = 2 * _IO_blen (fp) + 100;
+	  size_t old_blen = _IO_blen (fp);
+	  _IO_size_t new_size = 2 * old_blen + 100;
+	  if (new_size < old_blen)
+	    return EOF;
 	  new_buf
 	    = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
 	  if (new_buf == NULL)
@@ -153,15 +125,13 @@ _IO_str_overflow (fp, c)
 	    }
 	  if (old_buf)
 	    {
-	      memcpy (new_buf, old_buf, _IO_blen (fp));
+	      memcpy (new_buf, old_buf, old_blen);
 	      (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
 	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
 	      fp->_IO_buf_base = NULL;
 	    }
-#if 0
-	  if (lenp == &LEN(fp)) /* use '\0'-filling */
-	      memset (new_buf + pos, 0, blen() - pos);
-#endif
+	  memset (new_buf + old_blen, '\0', new_size - old_blen);
+
 	  INTUSE(_IO_setb) (fp, new_buf, new_buf + new_size, 1);
 	  fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
 	  fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
@@ -211,6 +181,71 @@ _IO_str_count (fp)
 	  - fp->_IO_read_base);
 }
 
+
+static int
+enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
+{
+  if ((_IO_ssize_t) offset <= _IO_blen (fp))
+    return 0;
+
+  _IO_ssize_t oldend = fp->_IO_write_end - fp->_IO_write_base;
+
+  /* Try to enlarge the buffer.  */
+  if (fp->_flags & _IO_USER_BUF)
+    /* User-provided buffer.  */
+    return 1;
+
+  _IO_size_t newsize = offset + 100;
+  char *oldbuf = fp->_IO_buf_base;
+  char *newbuf
+    = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize);
+  if (newbuf == NULL)
+    return 1;
+
+  if (oldbuf != NULL)
+    {
+      memcpy (newbuf, oldbuf, _IO_blen (fp));
+      (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
+      /* Make sure _IO_setb won't try to delete
+	 _IO_buf_base. */
+      fp->_IO_buf_base = NULL;
+    }
+
+  INTUSE(_IO_setb) (fp, newbuf, newbuf + newsize, 1);
+
+  if (reading)
+    {
+      fp->_IO_write_base = newbuf + (fp->_IO_write_base - oldbuf);
+      fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf);
+      fp->_IO_write_end = newbuf + (fp->_IO_write_end - oldbuf);
+      fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf);
+
+      fp->_IO_read_base = newbuf;
+      fp->_IO_read_end = fp->_IO_buf_end;
+    }
+  else
+    {
+      fp->_IO_read_base = newbuf + (fp->_IO_read_base - oldbuf);
+      fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf);
+      fp->_IO_read_end = newbuf + (fp->_IO_read_end - oldbuf);
+      fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf);
+
+      fp->_IO_write_base = newbuf;
+      fp->_IO_write_end = fp->_IO_buf_end;
+    }
+
+  /* Clear the area between the last write position and th
+     new position.  */
+  assert (offset >= oldend);
+  if (reading)
+    memset (fp->_IO_read_base + oldend, '\0', offset - oldend);
+  else
+    memset (fp->_IO_write_base + oldend, '\0', offset - oldend);
+
+  return 0;
+}
+
+
 _IO_off64_t
 _IO_str_seekoff (fp, offset, dir, mode)
      _IO_FILE *fp;
@@ -251,7 +286,10 @@ _IO_str_seekoff (fp, offset, dir, mode)
 	    default: /* case _IO_seek_set: */
 	      break;
 	    }
-	  if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+	  if (offset < 0)
+	    return EOF;
+	  if ((_IO_ssize_t) offset > cur_size
+	      && enlarge_userbuf (fp, offset, 1) != 0)
 	    return EOF;
 	  fp->_IO_read_ptr = fp->_IO_read_base + offset;
 	  fp->_IO_read_end = fp->_IO_read_base + cur_size;
@@ -272,7 +310,10 @@ _IO_str_seekoff (fp, offset, dir, mode)
 	    default: /* case _IO_seek_set: */
 	      break;
 	    }
-	  if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+	  if (offset < 0)
+	    return EOF;
+	  if ((_IO_ssize_t) offset > cur_size
+	      && enlarge_userbuf (fp, offset, 0) != 0)
 	    return EOF;
 	  fp->_IO_write_ptr = fp->_IO_write_base + offset;
 	  new_pos = offset;
diff --git a/libio/swprintf.c b/libio/swprintf.c
index 298c1e7537..ea0bdfd33c 100644
--- a/libio/swprintf.c
+++ b/libio/swprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1995,1997,1998,1999,2000,2003
+/* Copyright (C) 1991,1995,1997,1998,1999,2000,2003,2004,2006
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -17,13 +17,14 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <wchar.h>
 
 /* Write formatted output into S, according to the format string FORMAT.  */
 /* VARARGS3 */
 int
-swprintf (wchar_t *s, size_t n, const wchar_t *format, ...)
+__swprintf (wchar_t *s, size_t n, const wchar_t *format, ...)
 {
   va_list arg;
   int done;
@@ -34,3 +35,4 @@ swprintf (wchar_t *s, size_t n, const wchar_t *format, ...)
 
   return done;
 }
+ldbl_strong_alias (__swprintf, swprintf)
diff --git a/libio/swscanf.c b/libio/swscanf.c
index c837ad14f6..f93d207416 100644
--- a/libio/swscanf.c
+++ b/libio/swscanf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1995,1996,1998,1999,2003 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1998, 1999, 2003, 2006
+   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
@@ -16,13 +17,14 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <wchar.h>
 
 /* Read formatted input from S, according to the format string FORMAT.  */
 /* VARARGS2 */
 int
-swscanf (const wchar_t *s, const wchar_t *format, ...)
+__swscanf (const wchar_t *s, const wchar_t *format, ...)
 {
   va_list arg;
   int done;
@@ -33,3 +35,4 @@ swscanf (const wchar_t *s, const wchar_t *format, ...)
 
   return done;
 }
+ldbl_strong_alias (__swscanf, swscanf)
diff --git a/libio/tst-fopenloc2.c b/libio/tst-fopenloc2.c
new file mode 100644
index 0000000000..5ddd63446b
--- /dev/null
+++ b/libio/tst-fopenloc2.c
@@ -0,0 +1,116 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <wchar.h>
+
+
+static const struct
+{
+  const char *enc;
+  const char *data;
+  size_t datalen;
+  const wchar_t *expected;
+  size_t expectedlen;
+} tests[] =
+  {
+    { "UCS-4LE", "a\0\0\0b\0\0\0", 8, L"ab", 2 },
+    { "UCS-4BE", "\0\0\0a\0\0\0b", 8, L"ab", 2 },
+  };
+#define ntests (sizeof (tests) / sizeof (tests[0]))
+
+
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+
+static void prepare (void);
+#define PREPARE(argc, argv) prepare ();
+
+#include "../test-skeleton.c"
+
+
+static int fd;
+static char *tmpname;
+
+
+static void
+prepare (void)
+{
+  fd = create_temp_file ("tst-fopenloc2", &tmpname);
+  if (fd == -1)
+    {
+      puts ("cannot open temp file");
+      exit (1);
+    }
+}
+
+
+static int
+do_test (void)
+{
+  for (int i = 0; i < ntests; ++i)
+    {
+      if (ftruncate (fd, 0) != 0)
+	{
+	  printf ("ftruncate in round %d failed\n", i + 1);
+	  return 1;
+	}
+
+      if (TEMP_FAILURE_RETRY (write (fd, tests[i].data, tests[i].datalen))
+	  != tests[i].datalen)
+	{
+	  printf ("write in round %d failed\n", i + 1);
+	  return 1;
+	}
+
+      if (lseek (fd, 0, SEEK_SET) != 0)
+	{
+	  printf ("lseek in round %d failed\n", i + 1);
+	  return 1;
+	}
+
+      char *ccs;
+      if (asprintf (&ccs, "r,ccs=%s", tests[i].enc) == -1)
+	{
+	  printf ("asprintf in round %d failed\n", i + 1);
+	  return 1;
+	}
+
+      FILE *fp = fopen (tmpname, ccs);
+      if (fp == NULL)
+	{
+	  printf ("fopen in round %d failed\n", i + 1);
+	  return 1;
+	}
+
+#define LINELEN 100
+      wchar_t line[LINELEN];
+      if (fgetws (line, LINELEN, fp) != line)
+	{
+	  printf ("fgetws in round %d failed\n", i + 1);
+	  return 1;
+	}
+
+      if (wcslen (line) != tests[i].expectedlen)
+	{
+	  printf ("round %d: expected length %zu, got length %zu\n",
+		  i + 1, tests[i].expectedlen, wcslen (line));
+	  return 1;
+	}
+
+      if (wcscmp (tests[i].expected, line) != 0)
+	{
+	  printf ("round %d: expected L\"%ls\", got L\"%ls\"\n",
+		  i + 1, tests[i].expected, line);
+	  return 1;
+	}
+
+      fclose (fp);
+
+      free (ccs);
+    }
+
+  close (fd);
+
+  return 0;
+}
diff --git a/libio/tst-memstream1.c b/libio/tst-memstream1.c
new file mode 100644
index 0000000000..d18f5cc22a
--- /dev/null
+++ b/libio/tst-memstream1.c
@@ -0,0 +1,89 @@
+#include <mcheck.h>
+#include <stdio.h>
+
+
+#ifndef CHAR_T
+# define CHAR_T char
+# define W(o) o
+# define OPEN_MEMSTREAM open_memstream
+#endif
+
+#define S(s) S1 (s)
+#define S1(s) #s
+
+
+static void
+mcheck_abort (enum mcheck_status ev)
+{
+  printf ("mecheck failed with status %d\n", (int) ev);
+  exit (1);
+}
+
+
+static int
+do_test (void)
+{
+  mcheck_pedantic (mcheck_abort);
+
+  CHAR_T *buf = (CHAR_T *) 1l;
+  size_t len = 12345;
+  FILE *fp = OPEN_MEMSTREAM (&buf, &len);
+  if (fp == NULL)
+    {
+      printf ("%s failed\n", S(OPEN_MEMSTREAM));
+      return 1;
+    }
+
+  if (fflush (fp) != 0)
+    {
+      puts ("fflush failed");
+      return 1;
+    }
+
+  if (len != 0)
+    {
+      puts ("string after no write not empty");
+      return 1;
+    }
+  if (buf == (CHAR_T *) 1l)
+    {
+      puts ("buf not updated");
+      return 1;
+    }
+  if (buf[0] != W('\0'))
+    {
+      puts ("buf[0] != 0");
+      return 1;
+    }
+
+  buf = (CHAR_T *) 1l;
+  len = 12345;
+  if (fclose (fp) != 0)
+    {
+      puts ("fclose failed");
+      return 1;
+    }
+
+  if (len != 0)
+    {
+      puts ("string after close with no write not empty");
+      return 1;
+    }
+  if (buf == (CHAR_T *) 1l)
+    {
+      puts ("buf not updated");
+      return 1;
+    }
+  if (buf[0] != W('\0'))
+    {
+      puts ("buf[0] != 0");
+      return 1;
+    }
+
+  free (buf);
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libio/tst-memstream2.c b/libio/tst-memstream2.c
new file mode 100644
index 0000000000..9619d7725d
--- /dev/null
+++ b/libio/tst-memstream2.c
@@ -0,0 +1,104 @@
+#include <mcheck.h>
+#include <stdio.h>
+
+
+#ifndef CHAR_T
+# define CHAR_T char
+# define W(o) o
+# define OPEN_MEMSTREAM open_memstream
+#endif
+
+#define S(s) S1 (s)
+#define S1(s) #s
+
+
+static void
+mcheck_abort (enum mcheck_status ev)
+{
+  printf ("mecheck failed with status %d\n", (int) ev);
+  exit (1);
+}
+
+
+static int
+do_test (void)
+{
+  mcheck_pedantic (mcheck_abort);
+
+  CHAR_T *buf = (CHAR_T *) 1l;
+  size_t len = 12345;
+  FILE *fp = OPEN_MEMSTREAM (&buf, &len);
+  if (fp == NULL)
+    {
+      printf ("%s failed\n", S(OPEN_MEMSTREAM));
+      return 1;
+    }
+
+  for (int outer = 0; outer < 800; ++outer)
+    {
+      for (int inner = 0; inner < 100; ++inner)
+	if (fputc (W('a') + (outer * 100 + inner) % 26, fp) == EOF)
+	  {
+	    printf ("fputc at %d:%d failed\n", outer, inner);
+	    return 1;
+	  }
+
+      if (fflush (fp) != 0)
+	{
+	  puts ("fflush failed");
+	  return 1;
+	}
+
+      if (len != (outer + 1) * 100)
+	{
+	  printf ("string in round %d not %d bytest long\n",
+		  outer + 1, (outer + 1) * 100);
+	  return 1;
+	}
+      if (buf == (CHAR_T *) 1l)
+	{
+	  printf ("round %d: buf not updated\n", outer + 1);
+	  return 1;
+	}
+      for (int inner = 0; inner < (outer + 1) * 100; ++inner)
+	if (buf[inner] != W('a') + inner % 26)
+	  {
+	    printf ("round %d: buf[%d] != '%c'\n", outer + 1, inner,
+		    (char) (W('a') + inner % 26));
+	    return 1;
+	  }
+    }
+
+  buf = (CHAR_T *) 1l;
+  len = 12345;
+  if (fclose (fp) != 0)
+    {
+      puts ("fclose failed");
+      return 1;
+    }
+
+  if (len != 800 * 100)
+    {
+      puts ("string after close not 80000 bytes long");
+      return 1;
+    }
+  if (buf == (CHAR_T *) 1l)
+    {
+      puts ("buf not updated");
+      return 1;
+    }
+  for (int inner = 0; inner < 800 * 100; ++inner)
+    if (buf[inner] != W('a') + inner % 26)
+      {
+	printf ("after close: buf[%d] != %c\n", inner,
+		(char) (W('a') + inner % 26));
+	return 1;
+      }
+
+  free (buf);
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libio/tst-setvbuf1.c b/libio/tst-setvbuf1.c
new file mode 100644
index 0000000000..9222d4050d
--- /dev/null
+++ b/libio/tst-setvbuf1.c
@@ -0,0 +1,39 @@
+/* Dereived from the test case in BZ #2337.  */
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <wchar.h>
+
+
+static char buf[512] __attribute__ ((aligned (4096)));
+
+
+static int
+do_test (void)
+{
+  setlocale (LC_ALL, "de_DE.UTF-8");
+
+  FILE *fp = fdopen (dup (STDOUT_FILENO), "a");
+  if (fp == NULL)
+    error (EXIT_FAILURE, errno, "fdopen(,\"a\")");
+
+  setvbuf (fp, buf, _IOFBF, sizeof (buf));
+
+  /* fwprintf to unbuffered stream.   */
+  fwprintf (fp, L"hello.\n");
+
+  fclose (fp);
+
+  /* touch my buffer */
+  buf[45] = 'a';
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/libio/tst-wmemstream1.c b/libio/tst-wmemstream1.c
new file mode 100644
index 0000000000..f8b308bc6c
--- /dev/null
+++ b/libio/tst-wmemstream1.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+#define CHAR_T wchar_t
+#define W(o) L##o
+#define OPEN_MEMSTREAM open_wmemstream
+
+#include "tst-memstream1.c"
diff --git a/libio/tst-wmemstream2.c b/libio/tst-wmemstream2.c
new file mode 100644
index 0000000000..e2442ebfac
--- /dev/null
+++ b/libio/tst-wmemstream2.c
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+#define CHAR_T wchar_t
+#define W(o) L##o
+#define OPEN_MEMSTREAM open_wmemstream
+
+#include "tst-memstream2.c"
diff --git a/libio/vasprintf.c b/libio/vasprintf.c
index e32a488438..2fdb9f6ed2 100644
--- a/libio/vasprintf.c
+++ b/libio/vasprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995,1997,1999-2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1997,1999-2002,2004,2006 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
@@ -46,6 +46,8 @@ _IO_vasprintf (result_ptr, format, args)
   int ret;
   _IO_size_t needed;
   _IO_size_t allocated;
+  /* No need to clear the memory here (unlike for open_memstream) since
+     we know we will never seek on the stream.  */
   string = (char *) malloc (init_string_size);
   if (string == NULL)
     return -1;
@@ -87,7 +89,4 @@ _IO_vasprintf (result_ptr, format, args)
   (*result_ptr)[needed - 1] = '\0';
   return ret;
 }
-
-#ifdef weak_alias
-weak_alias (_IO_vasprintf, vasprintf)
-#endif
+ldbl_weak_alias (_IO_vasprintf, vasprintf)
diff --git a/libio/vscanf.c b/libio/vscanf.c
index 477cbaee84..78c30eefdf 100644
--- a/libio/vscanf.c
+++ b/libio/vscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 2002, 2006 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
@@ -37,7 +37,4 @@ _IO_vscanf (format, args)
 {
   return INTUSE(_IO_vfscanf) (_IO_stdin, format, args, NULL);
 }
-
-#ifdef weak_alias
-weak_alias (_IO_vscanf, vscanf)
-#endif
+ldbl_weak_alias (_IO_vscanf, vscanf)
diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c
index 4250c2d2de..289160e540 100644
--- a/libio/vsnprintf.c
+++ b/libio/vsnprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994,1997,1999-2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1994,1997,1999-2003, 2004, 2006 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
@@ -123,8 +123,5 @@ _IO_vsnprintf (string, maxlen, format, args)
     *sf.f._sbf._f._IO_write_ptr = '\0';
   return ret;
 }
-
-#ifdef weak_alias
-weak_alias (_IO_vsnprintf, __vsnprintf)
-weak_alias (_IO_vsnprintf, vsnprintf)
-#endif
+ldbl_weak_alias (_IO_vsnprintf, __vsnprintf)
+ldbl_weak_alias (_IO_vsnprintf, vsnprintf)
diff --git a/libio/vswprintf.c b/libio/vswprintf.c
index 42168aade4..5bbd20227b 100644
--- a/libio/vswprintf.c
+++ b/libio/vswprintf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1994,1997,1999-2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1997, 1999-2002, 2004, 2005, 2006
+   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
@@ -29,15 +30,6 @@
 #include "strfile.h"
 
 
-typedef struct
-{
-  _IO_strfile f;
-  /* This is used for the characters which do not fit in the buffer
-     provided by the user.  */
-  wchar_t overflow_buf[64];
-} _IO_wstrnfile;
-
-
 static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW;
 
 static wint_t
@@ -75,7 +67,7 @@ _IO_wstrn_overflow (fp, c)
 }
 
 
-static const struct _IO_jump_t _IO_wstrn_jumps =
+const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden =
 {
   JUMP_INIT_DUMMY,
   JUMP_INIT(finish, _IO_wstr_finish),
@@ -135,8 +127,5 @@ _IO_vswprintf (string, maxlen, format, args)
 
   return ret;
 }
-
-#ifdef weak_alias
 weak_alias (_IO_vswprintf, __vswprintf)
-weak_alias (_IO_vswprintf, vswprintf)
-#endif
+ldbl_weak_alias (_IO_vswprintf, vswprintf)
diff --git a/libio/vwprintf.c b/libio/vwprintf.c
index 814fdf32bf..bd9a950c7c 100644
--- a/libio/vwprintf.c
+++ b/libio/vwprintf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1993,1995,1997,1999,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1995, 1997, 1999, 2001, 2006
+   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
@@ -16,6 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <wchar.h>
@@ -23,9 +25,8 @@
 /* Write formatted output to stdout according to the
    format string FORMAT, using the argument list in ARG.  */
 int
-vwprintf (format, arg)
-     const wchar_t *format;
-     __gnuc_va_list arg;
+__vwprintf (const wchar_t *format, __gnuc_va_list arg)
 {
   return __vfwprintf (stdout, format, arg);
 }
+ldbl_strong_alias (__vwprintf, vwprintf)
diff --git a/libio/vwscanf.c b/libio/vwscanf.c
index cd7af9ce5b..f6d04e8e87 100644
--- a/libio/vwscanf.c
+++ b/libio/vwscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1999, 2006 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
@@ -29,9 +29,8 @@
 #include <wchar.h>
 
 int
-vwscanf (format, args)
-     const wchar_t *format;
-     _IO_va_list args;
+__vwscanf (const wchar_t *format, _IO_va_list args)
 {
   return _IO_vfwscanf (_IO_stdin, format, args, NULL);
 }
+ldbl_strong_alias (__vwscanf, vwscanf)
diff --git a/libio/wfiledoalloc.c b/libio/wfiledoalloc.c
index 2f8140b0ac..67a05175b2 100644
--- a/libio/wfiledoalloc.c
+++ b/libio/wfiledoalloc.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1999, 2000, 2002, 2006
+   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
@@ -85,35 +86,20 @@ _IO_wfile_doallocate (fp)
      _IO_FILE *fp;
 {
   _IO_size_t size;
-  int couldbetty;
   wchar_t *p;
-  struct _G_stat64 st;
 
   /* Allocate room for the external buffer.  */
   if (fp->_IO_buf_base == NULL)
     INTUSE(_IO_file_doallocate) (fp);
 
-  if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0)
-    {
-      couldbetty = 0;
-      size = _IO_BUFSIZ;
-#if 0
-      /* do not try to optimise fseek() */
-      fp->_flags |= __SNPT;
-#endif
-    }
-  else
-    {
-      couldbetty = S_ISCHR (st.st_mode);
-#if _IO_HAVE_ST_BLKSIZE
-      size = st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize;
-#else
-      size = _IO_BUFSIZ;
-#endif
-    }
+  /* If narrow buffer is user allocated (set by setvbuf etc.),
+     use that size as the size of the wide buffer, when it is
+     allocated by _IO_file_doallocate, multiply that by size
+     of the wide character.  */
+  size = fp->_IO_buf_end - fp->_IO_buf_base;
+  if ((fp->_flags & _IO_USER_BUF))
+    size = (size + sizeof (wchar_t) - 1) / sizeof (wchar_t);
   ALLOC_WBUF (p, size * sizeof (wchar_t), EOF);
   INTUSE(_IO_wsetb) (fp, p, p + size, 1);
-  if (couldbetty && isatty (fp->_fileno))
-    fp->_flags |= _IO_LINE_BUF;
   return 1;
 }
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 5f9faac223..b930aad067 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1997-2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995,1997-2003,2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@cygnus.com>.
    Based on the single byte version by Per Bothner <bothner@cygnus.com>.
@@ -69,7 +69,7 @@ _IO_wdo_write (fp, data, to_do)
 	{
 	  if (_IO_new_do_write (fp, fp->_IO_write_base,
 				fp->_IO_write_ptr - fp->_IO_write_base) == EOF)
-	    return EOF;
+	    return WEOF;
 	}
 
       do
diff --git a/libio/wgenops.c b/libio/wgenops.c
index a9cc7bf210..760a413dc3 100644
--- a/libio/wgenops.c
+++ b/libio/wgenops.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1995,1997-2001,2002,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1995,1997-2002,2004,2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@cygnus.com>.
    Based on the single byte version by Per Bothner <bothner@cygnus.com>.
@@ -115,14 +115,14 @@ _IO_wsetb (f, b, eb, a)
      wchar_t *eb;
      int a;
 {
-  if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
-    FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f));
+  if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF))
+    FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f) * sizeof (wchar_t));
   f->_wide_data->_IO_buf_base = b;
   f->_wide_data->_IO_buf_end = eb;
   if (a)
-    f->_flags &= ~_IO_USER_BUF;
+    f->_flags2 &= ~_IO_FLAGS2_USER_WBUF;
   else
-    f->_flags |= _IO_USER_BUF;
+    f->_flags2 |= _IO_FLAGS2_USER_WBUF;
 }
 INTDEF(_IO_wsetb)
 
@@ -198,7 +198,7 @@ _IO_wdefault_finish (fp, dummy)
      int dummy;
 {
   struct _IO_marker *mark;
-  if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+  if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
     {
       FREE_BUF (fp->_wide_data->_IO_buf_base,
 		_IO_wblen (fp) * sizeof (wchar_t));
diff --git a/libio/wmemstream.c b/libio/wmemstream.c
new file mode 100644
index 0000000000..7bf6a429ac
--- /dev/null
+++ b/libio/wmemstream.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 1995-97,99,2000,2002-2004,2006 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
+   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 "libioP.h"
+#include "strfile.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+
+struct _IO_FILE_wmemstream
+{
+  _IO_strfile _sf;
+  wchar_t **bufloc;
+  _IO_size_t *sizeloc;
+};
+
+
+static int _IO_wmem_sync (_IO_FILE* fp) __THROW;
+static void _IO_wmem_finish (_IO_FILE* fp, int) __THROW;
+
+
+static const struct _IO_jump_t _IO_wmem_jumps =
+{
+  JUMP_INIT_DUMMY,
+  JUMP_INIT (finish, _IO_wmem_finish),
+  JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
+  JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
+  JUMP_INIT (uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)),
+  JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
+  JUMP_INIT (xsputn, INTUSE(_IO_wdefault_xsputn)),
+  JUMP_INIT (xsgetn, INTUSE(_IO_wdefault_xsgetn)),
+  JUMP_INIT (seekoff, _IO_wstr_seekoff),
+  JUMP_INIT (seekpos, _IO_default_seekpos),
+  JUMP_INIT (setbuf, _IO_default_setbuf),
+  JUMP_INIT (sync, _IO_wmem_sync),
+  JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)),
+  JUMP_INIT (read, _IO_default_read),
+  JUMP_INIT (write, _IO_default_write),
+  JUMP_INIT (seek, _IO_default_seek),
+  JUMP_INIT (close, _IO_default_close),
+  JUMP_INIT (stat, _IO_default_stat),
+  JUMP_INIT (showmanyc, _IO_default_showmanyc),
+  JUMP_INIT (imbue, _IO_default_imbue)
+};
+
+/* Open a stream that writes into a malloc'd buffer that is expanded as
+   necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
+   and the number of characters written on fflush or fclose.  */
+_IO_FILE *
+open_wmemstream (bufloc, sizeloc)
+     wchar_t **bufloc;
+     _IO_size_t *sizeloc;
+{
+  struct locked_FILE
+  {
+    struct _IO_FILE_wmemstream fp;
+#ifdef _IO_MTSAFE_IO
+    _IO_lock_t lock;
+#endif
+    struct _IO_wide_data wd;
+  } *new_f;
+  wchar_t *buf;
+
+  new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
+  if (new_f == NULL)
+    return NULL;
+#ifdef _IO_MTSAFE_IO
+  new_f->fp._sf._sbf._f._lock = &new_f->lock;
+#endif
+
+  buf = calloc (1, _IO_BUFSIZ);
+  if (buf == NULL)
+    return NULL;
+
+  _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps);
+  _IO_fwide (&new_f->fp._sf._sbf._f, 1);
+  _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
+			_IO_BUFSIZ / sizeof (wchar_t), buf);
+  new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF;
+  new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+  new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
+
+  new_f->fp.bufloc = bufloc;
+  new_f->fp.sizeloc = sizeloc;
+
+  return (_IO_FILE *) &new_f->fp._sf._sbf;
+}
+
+
+static int
+_IO_wmem_sync (fp)
+     _IO_FILE* fp;
+{
+  struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
+
+  if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end)
+    {
+      _IO_wstr_overflow (fp, '\0');
+      --fp->_wide_data->_IO_write_ptr;
+    }
+  else
+    *fp->_wide_data->_IO_write_ptr = '\0';
+
+  *mp->bufloc = fp->_wide_data->_IO_write_base;
+  *mp->sizeloc = (fp->_wide_data->_IO_write_ptr
+		  - fp->_wide_data->_IO_write_base);
+
+  return 0;
+}
+
+
+static void
+_IO_wmem_finish (fp, dummy)
+     _IO_FILE* fp;
+     int dummy;
+{
+  struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
+
+  *mp->bufloc = (wchar_t *) realloc (fp->_wide_data->_IO_write_base,
+				     (fp->_wide_data->_IO_write_ptr
+				      - fp->_wide_data->_IO_write_base + 1)
+				     * sizeof (wchar_t));
+  if (*mp->bufloc != NULL)
+    {
+      size_t len = (fp->_wide_data->_IO_write_ptr
+		    - fp->_wide_data->_IO_write_base);
+      (*mp->bufloc)[len] = '\0';
+      *mp->sizeloc = len;
+
+      fp->_wide_data->_IO_buf_base = NULL;
+    }
+
+  _IO_wstr_finish (fp, 0);
+}
diff --git a/libio/wprintf.c b/libio/wprintf.c
index f418cf515d..d06451c15a 100644
--- a/libio/wprintf.c
+++ b/libio/wprintf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1995,1996,1997,1999,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1999, 2001, 2006
+   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
@@ -16,6 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <wchar.h>
@@ -23,7 +25,7 @@
 /* Write formatted output to stdout from the format string FORMAT.  */
 /* VARARGS1 */
 int
-wprintf (const wchar_t *format, ...)
+__wprintf (const wchar_t *format, ...)
 {
   va_list arg;
   int done;
@@ -34,3 +36,4 @@ wprintf (const wchar_t *format, ...)
 
   return done;
 }
+ldbl_strong_alias (__wprintf, wprintf)
diff --git a/libio/wscanf.c b/libio/wscanf.c
index f4b8cd1b83..3eba6207c3 100644
--- a/libio/wscanf.c
+++ b/libio/wscanf.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1999, 2006
+   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
@@ -16,6 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <libioP.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <wchar.h>
@@ -24,7 +26,7 @@
 /* Read formatted input from stdin according to the format string FORMAT.  */
 /* VARARGS1 */
 int
-wscanf (const wchar_t *format, ...)
+__wscanf (const wchar_t *format, ...)
 {
   va_list arg;
   int done;
@@ -35,3 +37,4 @@ wscanf (const wchar_t *format, ...)
 
   return done;
 }
+ldbl_strong_alias (__wscanf, wscanf)
diff --git a/libio/wstrops.c b/libio/wstrops.c
index 32f7ef3cf7..c5aae7bc6a 100644
--- a/libio/wstrops.c
+++ b/libio/wstrops.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1997-1999,2001-2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1997-1999,2001-2004, 2006 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
@@ -25,44 +25,13 @@
    This exception applies to code released by its copyright holders
    in files containing the exception.  */
 
+#include <assert.h>
 #include "strfile.h"
 #include "libioP.h"
 #include <string.h>
 #include <wchar.h>
 #include <stdio_ext.h>
 
-#if 0
-/* The following definitions are for exposition only.
-   They map the terminology used in the ANSI/ISO C++ draft standard
-   to the implementation. */
-
-/* allocated:  set  when a dynamic array object has been allocated, and
-   hence should be freed by the destructor for the strstreambuf object. */
-#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
-
-/* constant:  set when the array object has const elements,
-   so the output sequence cannot be written. */
-#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
-
-/* alsize:  the suggested minimum size for a dynamic array object. */
-#define ALSIZE(FP) ??? /* not stored */
-
-/* palloc: points to the function to call to allocate a dynamic array object.*/
-#define PALLOC(FP) \
-  ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
-
-/* pfree: points  to  the  function  to call to free a dynamic array object. */
-#define PFREE(FP) \
-  ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
-
-#endif
-
-#ifdef TODO
-/* An "unbounded buffer" is when a buffer is supplied, but with no
-   specified length.  An example is the buffer argument to sprintf.
-   */
-#endif
-
 void
 _IO_wstr_init_static (fp, ptr, size, pstart)
      _IO_FILE *fp;
@@ -98,7 +67,7 @@ _IO_wstr_init_static (fp, ptr, size, pstart)
       fp->_wide_data->_IO_read_end = end;
     }
   /* A null _allocate_buffer function flags the strfile as being static. */
-  (((_IO_strfile *) fp)->_s._allocate_buffer) =  (_IO_alloc_type)0;
+  (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
 }
 
 _IO_wint_t
@@ -116,16 +85,19 @@ _IO_wstr_overflow (fp, c)
       fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
       fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
     }
-  pos =  fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base;
+  pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base;
   if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only))
     {
-      if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
+      if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* not allowed to enlarge */
 	return WEOF;
       else
 	{
 	  wchar_t *new_buf;
 	  wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
-	  _IO_size_t new_size = 2 * _IO_wblen (fp) + 100;
+	  size_t old_wblen = _IO_wblen (fp);
+	  _IO_size_t new_size = 2 * old_wblen + 100;
+	  if (new_size < old_wblen)
+	    return EOF;
 	  new_buf
 	    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
 									* sizeof (wchar_t));
@@ -136,11 +108,14 @@ _IO_wstr_overflow (fp, c)
 	    }
 	  if (old_buf)
 	    {
-	      __wmemcpy (new_buf, old_buf, _IO_wblen (fp));
+	      __wmemcpy (new_buf, old_buf, old_wblen);
 	      (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
 	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
 	      fp->_wide_data->_IO_buf_base = NULL;
 	    }
+
+	  wmemset (new_buf + old_wblen, L'\0', new_size - old_wblen);
+
 	  INTUSE(_IO_wsetb) (fp, new_buf, new_buf + new_size, 1);
 	  fp->_wide_data->_IO_read_base =
 	    new_buf + (fp->_wide_data->_IO_read_base - old_buf);
@@ -163,6 +138,7 @@ _IO_wstr_overflow (fp, c)
   return c;
 }
 
+
 _IO_wint_t
 _IO_wstr_underflow (fp)
      _IO_FILE *fp;
@@ -181,17 +157,87 @@ _IO_wstr_underflow (fp)
     return WEOF;
 }
 
-/* The size of the valid part of the buffer.  */
 
+/* The size of the valid part of the buffer.  */
 _IO_ssize_t
 _IO_wstr_count (fp)
      _IO_FILE *fp;
 {
-  return ((fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end
-	   ? fp->_wide_data->_IO_write_ptr : fp->_wide_data->_IO_read_end)
-	  - fp->_wide_data->_IO_read_base);
+  struct _IO_wide_data *wd = fp->_wide_data;
+
+  return ((wd->_IO_write_ptr > wd->_IO_read_end
+	   ? wd->_IO_write_ptr : wd->_IO_read_end)
+	  - wd->_IO_read_base);
 }
 
+
+static int
+enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
+{
+  if ((_IO_ssize_t) offset <= _IO_blen (fp))
+    return 0;
+
+  struct _IO_wide_data *wd = fp->_wide_data;
+
+  _IO_ssize_t oldend = wd->_IO_write_end - wd->_IO_write_base;
+
+  /* Try to enlarge the buffer.  */
+  if (fp->_flags2 & _IO_FLAGS2_USER_WBUF)
+    /* User-provided buffer.  */
+    return 1;
+
+  _IO_size_t newsize = offset + 100;
+  wchar_t *oldbuf = wd->_IO_buf_base;
+  wchar_t *newbuf
+    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
+								* sizeof (wchar_t));
+  if (newbuf == NULL)
+    return 1;
+
+  if (oldbuf != NULL)
+    {
+      __wmemcpy (newbuf, oldbuf, _IO_wblen (fp));
+      (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
+      /* Make sure _IO_setb won't try to delete
+	 _IO_buf_base. */
+      wd->_IO_buf_base = NULL;
+    }
+
+  INTUSE(_IO_wsetb) (fp, newbuf, newbuf + newsize, 1);
+
+  if (reading)
+    {
+      wd->_IO_write_base = newbuf + (wd->_IO_write_base - oldbuf);
+      wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf);
+      wd->_IO_write_end = newbuf + (wd->_IO_write_end - oldbuf);
+      wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf);
+
+      wd->_IO_read_base = newbuf;
+      wd->_IO_read_end = wd->_IO_buf_end;
+    }
+  else
+    {
+      wd->_IO_read_base = newbuf + (wd->_IO_read_base - oldbuf);
+      wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf);
+      wd->_IO_read_end = newbuf + (wd->_IO_read_end - oldbuf);
+      wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf);
+
+      wd->_IO_write_base = newbuf;
+      wd->_IO_write_end = wd->_IO_buf_end;
+    }
+
+  /* Clear the area between the last write position and th
+     new position.  */
+  assert (offset >= oldend);
+  if (reading)
+    wmemset (wd->_IO_read_base + oldend, L'\0', offset - oldend);
+  else
+    wmemset (wd->_IO_write_base + oldend, L'\0', offset - oldend);
+
+  return 0;
+}
+
+
 _IO_off64_t
 _IO_wstr_seekoff (fp, offset, dir, mode)
      _IO_FILE *fp;
@@ -234,7 +280,10 @@ _IO_wstr_seekoff (fp, offset, dir, mode)
 	    default: /* case _IO_seek_set: */
 	      break;
 	    }
-	  if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+	  if (offset < 0)
+	    return EOF;
+	  if ((_IO_ssize_t) offset > cur_size
+	      && enlarge_userbuf (fp, offset, 1) != 0)
 	    return EOF;
 	  fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
 					  + offset);
@@ -258,7 +307,10 @@ _IO_wstr_seekoff (fp, offset, dir, mode)
 	    default: /* case _IO_seek_set: */
 	      break;
 	    }
-	  if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+	  if (offset < 0)
+	    return EOF;
+	  if ((_IO_ssize_t) offset > cur_size
+	      && enlarge_userbuf (fp, offset, 0) != 0)
 	    return EOF;
 	  fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base
 					   + offset);
@@ -283,7 +335,7 @@ _IO_wstr_finish (fp, dummy)
      _IO_FILE *fp;
      int dummy;
 {
-  if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+  if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
     (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base);
   fp->_wide_data->_IO_buf_base = NULL;