public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* A libio patch
@ 1997-08-27 16:44 H.J. Lu
  0 siblings, 0 replies; 3+ messages in thread
From: H.J. Lu @ 1997-08-27 16:44 UTC (permalink / raw)
  To: egcs

Hi,

This patch brings libio to libio in glibc 2.1, aka Ulrich's libio.
It also works with different combinations of vtable thunks supports
in gcc and libc.

Thanks.

-- 
H.J. Lu (hjl@gnu.ai.mit.edu)
---
Mon Aug 25 17:31:49 1997  H.J. Lu  (hjl@gnu.ai.mit.edu)

	* Makefile.in (STDIO_OBJECTS): New. Defined as stdfiles.o.
	(LIBIO_OBJECTS): Add $(STDIO_OBJECTS).
	(empty.c): New target for an empty C file.
	(libio.a): Also depend on empty.o. If $(LIBIO_OBJECTS) is
	empty, create libio.a with empty.o.

	* config.shared (DISTCLEAN): Add target-mkfrag.

	* configure.in (*-linux*): Remove warning. Check vtable thunks
	in libc and compiler. Add mtsafe.mt/libio.mt to frags when
	appropriate.
	(ALL): Remove $(_G_CONFIG_H).
	(EXTRA_DISTCLEAN): New. set to dummy.c.

	* filedoalloc.c, fileops.c, iolibio.h, libio.h, libioP.h,
	strfile.h, strops.c: Update from glibc 2.1.

	* iovasprintf.c: New. Copied from glibc, libio/vasprintf.c.

	* iovsnprintf.c: New. Copied from glibc, libio/vsnprintf.c.

	* genops.c (__dummy): New if _IO_USE_LIBC is defined. Used to
	get the incompatible functions in libio.

	* iofclose.c (fclose): Make it weak alias of _IO_fclose if
	_IO_USE_LIBC is defined.

	* iofdopen.c (fdopen): Make it weak alias of _IO_fdopen if
	_IO_USE_LIBC is defined.

	* iofflush.c (fflush): Make it weak alias of _IO_fflush if
	_IO_USE_LIBC is defined.

	* iofopen.c (fopen): Make it weak alias of _IO_fopen if
	_IO_USE_LIBC is defined.

	* iofputs.c (fputs): Make it weak alias of _IO_fputs if
	_IO_USE_LIBC is defined.

	* iofwrite.c (fwrite): Make it weak alias of _IO_fwrite if
	_IO_USE_LIBC is defined.

	* iopopen.c (popen): Make it alias of _IO_popen if
	_IO_USE_LIBC is defined.

	* ioputs.c (puts): Make it weak alias of _IO_puts if
	_IO_USE_LIBC is defined.

	* iosetbuffer.c (setbuffer): Make it weak alias of _IO_setbuffer
	if _IO_USE_LIBC is defined.

	* iosetvbuf.c (setvbuf): Make it weak alias of _IO_setvbuf if
	_IO_USE_LIBC is defined.

	* iovfprintf.c (__cvt_double): Declared.
	(vfprintf): Make it alias of _IO_vfprintf if _IO_USE_LIBC is
	defined.

	* iovfscanf.c (__vfscanf): New. Defined if _IO_USE_LIBC is
	defined.

	* iovsprintf.c (vsprintf): Make it weak alias of _IO_vsprintf
	if _IO_USE_LIBC is defined.

	* iovsscanf.c (vsscanf, __vsscanf): Make them weak alias of
	_IO_vsscanf if _IO_USE_LIBC is defined.

	* outfloat.c: Define only if _IO_USE_DTOA is defined.

	* iostream.cc (__cvt_double, __printf_fp): Declared when
	appropriate.
	(istream& istream::operator>>(long double& x),
	ostream& ostream::operator<<(long double n)): Use long
	double in libio in glibc when appropriate.
	(ostream& ostream::operator<<(double n)): Use in libio in glibc
	when appropriate.

	* iostream.h (ostream& ostream::operator<<(long double n)):
	Don't inline with the double version for Linux.

	* parsestream.cc: Use malloc instead of ALLOC_BUF to allocate
	buffer.

	* stdstrbufs.cc: Include "_G_config.h".
	(DEF_STDFILE): Initialize lock if _IO_MTSAFE_IO is defined.

	* streambuf.cc (_IO_sb_finish): Add dummy int arg.
	(streambuf::streambuf(int flags)): Allocate a lock if
	_IO_MTSAFE_IO is defined.
	(streambuf::~streambuf()): Delete the lock if _IO_MTSAFE_IO is
	defined.

	* streambuf.h (_G_NEED_STDARG_H): Changed from
	_IO_NEED_STDARG_H.

	* gen-params (sigset_t): Don't generate.
	(_G_ullong): Also check unsigned long long int.
	(_G_llong): Also check long long int.
	(HAVE_FEATURES): Set to 1 if  <features.h> exists.

	* config/linux.mt: Update.

	* config/libio.mt, config/mtsafe.mt: New.

	* dbz/Makefile.in (check): Support make -j.

	* tests/tFile.cc (tempfile): Use the same tmp filename for
	different runs to support make -j.

Index: libio/Makefile.in
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/Makefile.in,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Makefile.in
--- libio/Makefile.in	1997/08/26 00:21:26	1.1.1.1
+++ libio/Makefile.in	1997/08/26 01:42:20
@@ -31,6 +31,8 @@
   ioprintf.o ioseekoff.o ioseekpos.o \
   outfloat.o strops.o iofclose.o iopopen.o ioungetc.o
 
+STDIO_OBJECTS = stdfiles.o
+
 # These emulate stdio functionality, but with a different name (_IO_ungetc
 # instead of ungetc), and using _IO_FILE instead of FILE.
 # They are not needed for C++ iostream, nor stdio, though some stdio
@@ -55,7 +57,8 @@
 OSPRIM_OBJECTS = ioprims.o iostrerror.o cleanup.o
 
 LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(OSPRIM_OBJECTS)
-LIBIO_OBJECTS = $(IO_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS) stdfiles.o
+LIBIO_OBJECTS = $(IO_OBJECTS) $(STDIO_OBJECTS) $(STDIO_WRAP_OBJECTS) \
+		$(OSPRIM_OBJECTS)
 
 LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS)
 LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS)
@@ -65,10 +68,14 @@
 #### package, host, target, and site dependent Makefile fragments come in here.
 ##
 
-libio.a: $(_G_CONFIG_H) $(LIBIO_OBJECTS)
+libio.a: $(_G_CONFIG_H) $(LIBIO_OBJECTS) empty.o
 	-rm -rf libio.a
-	$(AR) $(AR_FLAGS) libio.a $(LIBIO_OBJECTS)
+	$(AR) $(AR_FLAGS) libio.a $(LIBIO_OBJECTS) \
+	  `test x = x"$(LIBIO_OBJECTS)" && echo empty.o`
 	$(RANLIB) libio.a
+
+empty.c: Makefile
+	echo '/* empty file */' > empty.c
 
 libiostream.a: $(_G_CONFIG_H) $(LIBIOSTREAM_DEP)
 	-rm -rf libiostream.a
Index: libio/config.shared
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/config.shared,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 config.shared
--- libio/config.shared	1997/08/26 00:21:26	1.1.1.1
+++ libio/config.shared	1997/08/26 01:42:20
@@ -395,7 +395,7 @@
 
 MOSTLYCLEAN="${MOSTLYCLEAN-*.o pic stamp-picdir core ${EXTRA_MOSTLYCLEAN}} `if test -n "${TOUCH_ON_COMPILE}"; then echo stamp; else true; fi`"
 CLEAN="${CLEAN-${TARGETPROG} ${TARGETLIB}}"
-DISTCLEAN="${DISTCLEAN-config.status Makefile *~ Make.pack multilib.out ${EXTRA_DISTCLEAN-}}"
+DISTCLEAN="${DISTCLEAN-config.status Makefile *~ Make.pack target-mkfrag multilib.out ${EXTRA_DISTCLEAN-}}"
 REALCLEAN="${REALCLEAN-depend *.info*}"
 
 
Index: libio/configure.in
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/configure.in,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 configure.in
--- libio/configure.in	1997/08/26 00:21:26	1.1.1.1
+++ libio/configure.in	1997/08/27 00:29:22
@@ -15,17 +15,111 @@
 frags=
 
 case "${target}" in
-  *-hpux*)       frags=hpux.mt ;;
-  *-linux*)      
-	echo "WARNING:  The I/O implementation in FSF libg++ 2.8.x is not"
-	echo "  compatible with Linux libc through 5.2.x."
-	echo "  See libg++/README for more information."
-	echo "  YOU ARE ON YOUR OWN!"
-		 frags=linux.mt ;;
-  *-sco3.2v[45]*)   frags=sco4.mt ;;
-  *-isc*)        frags=isc.mt ;;
-  *-netware*)    frags=netware.mt ;;
-  *)             frags=${target_cpu}.mt ;;
+  *-hpux*)
+    frags=hpux.mt
+    ;;
+  *-linux*aout*)
+    frags=linux.mt
+    ;;
+  *-linux*)
+    case "${target}" in
+      *-linux*gnulibc1) gnulibc1=yes;;
+    esac
+    frags=linux.mt
+cat > dummy.c <<EOF
+extern int _libio_using_thunks;
+main ()
+{
+  return _libio_using_thunks;
+}
+EOF
+    if ${CC-cc} -o dummy dummy.c > /dev/null 2>&1; then
+      libc_thunks=yes
+    else
+      libc_thunks=no
+    fi
+cat > dummy.cc <<EOF
+class B
+{
+public:
+  virtual ~B () {};
+};
+
+class A : virtual B
+{
+public:
+  A() {}
+  ~A ();
+};
+
+A::~A ()
+{
+}
+
+main ()
+{
+  A os;
+}
+EOF
+    if ${CXX-c++} -c dummy.cc > /dev/null 2>&1; then
+      ${NM-nm} dummy.o | grep thunk > /dev/null 2>&1
+      if [ $? = 0 ]; then
+	cxx_thunks=yes
+      else
+	cxx_thunks=no
+      fi
+    else
+      cxx_thunks=no
+    fi
+    rm -f dummy.o dummy.c dummy.cc dummy
+    if [ $cxx_thunks != $libc_thunks ]; then
+      if [ x$gnulibc1 = xyes ]; then
+	echo "WARNING: The vtable thunks is enabled in your GNU C++"
+	echo "  compiler, which is not 100% compatible with the I/O"
+	echo "  implementation in the Linux C library 5.x.x. The"
+	echo "  resulting libg++ is not binary compatible with other"
+	echo "  libg++ 2.8.x for libc 5.x.x. Please disable vtable"
+	echo "  thunks in your GNU C++ compiler!"
+      fi
+      frags="$frags libio.mt"
+    else
+      if [ x$gnulibc1 != xyes ]; then
+	frags="$frags mtsafe.mt"
+      fi
+    fi
+    if [ x$gnulibc1 != xyes ]; then
+      if [  $cxx_thunks = no  ]; then
+	echo "WARNING: The vtable thunks is disabled in your GNU C++"
+	echo "  compiler, which may not be 100% compatible with the"
+	echo "  I/O implementation in GNU C library 2. The resulting"
+	echo "  libg++ may not thread safe, less efficient and the"
+	echo "  shared libg++ libraries are not binary compatible with"
+	echo "  other libg++ 2.8.x for glibc 2. Please enable vtable"
+	echo "  thunks in your GNU C++ compiler!"
+      fi
+      if [ $libc_thunks = no ]; then
+	echo "WARNING: Your GNU C library 2 does not support vtable"
+	echo "  thunks, which may not be 100% compatible with the"
+	echo "  I/O in this libg++. The resulting libg++ may not be"
+	echo "  thread safe, less efficient and the shared libg++"
+	echo "  libraries are not binary compatible with other libg++"
+	echo "  2.8.x for glibc 2. Please update your GNU C library"
+	echo "  for the vtable thunks support!"
+      fi
+    fi
+    ;;
+  *-sco3.2v[45]*)
+    frags=sco4.mt
+    ;;
+  *-isc*)
+    frags=isc.mt
+    ;;
+  *-netware*)
+    frags=netware.mt
+    ;;
+  *)
+    frags=${target_cpu}.mt
+    ;;
 esac
 
 case "${enable_shared}" in
@@ -57,10 +151,11 @@
 
 LIBDIR=yes
 TO_TOPDIR=../
-ALL='$(_G_CONFIG_H) libio.a iostream.list'
+ALL='libio.a iostream.list'
 XCINCLUDES='-I. -I$(srcdir)'
 XCXXINCLUDES='-I. -I$(srcdir)'
 MOSTLYCLEAN='*.o pic stamp-picdir core iostream.list'
+EXTRA_DISTCLEAN=dummy.c
 DISTCLEAN='config.status Makefile *~ Make.pack target-mkfrag multilib.out'
 CLEAN='_G_config.h *.a'
 INFO_FILES=iostream
Index: libio/filedoalloc.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/filedoalloc.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 filedoalloc.c
--- libio/filedoalloc.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/filedoalloc.c	1997/08/26 01:01:29
@@ -1,26 +1,27 @@
-/* 
-Copyright (C) 1993 Free Software Foundation
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
 
-This file is part of the GNU IO Library.  This library is free
-software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this library; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-As a special exception, if you link this library with files
-compiled with a GNU compiler to produce an executable, this does not cause
-the resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why
-the executable file might be covered by the GNU General Public License. */
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -41,7 +42,9 @@
 
 /* Modified for GNU iostream by Per Bothner 1991, 1992. */
 
-#define _POSIX_SOURCE
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
 #include "libioP.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -50,6 +53,11 @@
 #include <unistd.h>
 #endif
 
+#ifdef _LIBC
+# undef isatty
+# define isatty(Fd) __isatty (Fd)
+#endif
+
 /*
  * Allocate a file buffer, or switch to unbuffered I/O.
  * Per the ANSI C standard, ALL tty devices default to line buffered.
@@ -59,21 +67,23 @@
  */
 
 int
-DEFUN(_IO_file_doallocate, (fp),
-      register _IO_FILE *fp)
+_IO_file_doallocate (fp)
+     _IO_FILE *fp;
 {
-  register _IO_size_t size;
+  _IO_size_t size;
   int couldbetty;
-  register char *p;
+  char *p;
   struct stat st;
 
+#ifndef _LIBC
   /* If _IO_cleanup_registration_needed is non-zero, we should call the
      function it points to.  This is to make sure _IO_cleanup gets called
      on exit.  We call it from _IO_file_doallocate, since that is likely
      to get called by any program that does buffered I/O. */
   if (_IO_cleanup_registration_needed)
-    (*_IO_cleanup_registration_needed)();
-  
+    (*_IO_cleanup_registration_needed) ();
+#endif
+
   if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0)
     {
       couldbetty = 0;
@@ -85,18 +95,16 @@
     }
   else
     {
-      couldbetty = S_ISCHR(st.st_mode);
+      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
     }
-  p = ALLOC_BUF(size);
-  if (p == NULL)
-    return EOF;
-  _IO_setb(fp, p, p+size, 1);
-  if (couldbetty && isatty(fp->_fileno))
+  ALLOC_BUF (p, size, EOF);
+  _IO_setb (fp, p, p + size, 1);
+  if (couldbetty && isatty (fp->_fileno))
     fp->_flags |= _IO_LINE_BUF;
   return 1;
 }
Index: libio/fileops.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/fileops.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 fileops.c
--- libio/fileops.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/fileops.c	1997/08/26 01:02:08
@@ -1,30 +1,33 @@
-/* 
-Copyright (C) 1993, 1995 Free Software Foundation
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
+   Written by Per Bothner <bothner@cygnus.com>.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
 
-This file is part of the GNU IO Library.  This library is free
-software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this library; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-As a special exception, if you link this library with files
-compiled with a GNU compiler to produce an executable, this does not cause
-the resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why
-the executable file might be covered by the GNU General Public License. */
 
-/*  written by Per Bothner (bothner@cygnus.com) */
-
-#define _POSIX_SOURCE
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
 #include "libioP.h"
 #include <fcntl.h>
 #include <sys/types.h>
@@ -35,11 +38,16 @@
 extern int errno;
 #endif
 
+
+#ifdef _LIBC
+# define open(Name, Flags, Prot) __open ((Name), (Flags), (Prot))
+#endif
+
 /* An fstream can be in at most one of put mode, get mode, or putback mode.
    Putback mode is a variant of get mode.
 
    In a filebuf, there is only one current position, instead of two
-   separate get and put pointers.  In get mode, the current posistion
+   separate get and put pointers.  In get mode, the current position
    is that of gptr(); in put mode that of pptr().
 
    The position in the buffer that corresponds to the position
@@ -73,14 +81,14 @@
    (The pointers save_gptr() and save_egptr() are the values
    of gptr() and egptr() at the time putback mode was entered.)
    The OS position corresponds to that of save_egptr().
-   
+
    LINE BUFFERED OUTPUT:
    During line buffered output, _IO_write_base==base() && epptr()==base().
    However, ptr() may be anywhere between base() and ebuf().
    This forces a call to filebuf::overflow(int C) on every put.
    If there is more space in the buffer, and C is not a '\n',
    then C is inserted, and pptr() incremented.
-   
+
    UNBUFFERED STREAMS:
    If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
 */
@@ -90,8 +98,8 @@
 
 
 void
-DEFUN(_IO_file_init, (fp),
-      register _IO_FILE *fp)
+_IO_file_init (fp)
+     _IO_FILE *fp;
 {
   /* POSIX.1 allows another file handle to be used to change the position
      of our file descriptor.  Hence we actually don't know the actual
@@ -104,11 +112,11 @@
 }
 
 int
-DEFUN(_IO_file_close_it, (fp),
-      register _IO_FILE* fp)
+_IO_file_close_it (fp)
+     _IO_FILE *fp;
 {
   int write_status, close_status;
-  if (!_IO_file_is_open(fp))
+  if (!_IO_file_is_open (fp))
     return EOF;
 
   write_status = _IO_do_flush (fp);
@@ -118,11 +126,11 @@
   close_status = _IO_SYSCLOSE (fp);
 
   /* Free buffer. */
-  _IO_setb(fp, NULL, NULL, 0);
-  _IO_setg(fp, NULL, NULL, NULL);
-  _IO_setp(fp, NULL, NULL);
+  _IO_setb (fp, NULL, NULL, 0);
+  _IO_setg (fp, NULL, NULL, NULL);
+  _IO_setp (fp, NULL, NULL);
 
-  _IO_un_link(fp);
+  _IO_un_link (fp);
   fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
   fp->_fileno = EOF;
   fp->_offset = _IO_pos_BAD;
@@ -131,86 +139,99 @@
 }
 
 void
-DEFUN(_IO_file_finish, (fp),
-      register _IO_FILE* fp)
+_IO_file_finish (fp, dummy)
+     _IO_FILE *fp;
+     int dummy;
 {
-  if (_IO_file_is_open(fp))
+  if (_IO_file_is_open (fp))
     {
       _IO_do_flush (fp);
       if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
 	_IO_SYSCLOSE (fp);
     }
-  _IO_default_finish(fp);
+  _IO_default_finish (fp, 0);
 }
 
 _IO_FILE *
-DEFUN(_IO_file_fopen, (fp, filename, mode),
-      register _IO_FILE *fp AND const char *filename AND const char *mode)
+_IO_file_fopen (fp, filename, mode)
+     _IO_FILE *fp;
+     const char *filename;
+     const char *mode;
 {
   int oflags = 0, omode;
   int read_write, fdesc;
   int oprot = 0666;
   if (_IO_file_is_open (fp))
     return 0;
-  switch (*mode++) {
-  case 'r':
-    omode = O_RDONLY;
-    read_write = _IO_NO_WRITES;
-    break;
-  case 'w':
-    omode = O_WRONLY;
-    oflags = O_CREAT|O_TRUNC;
-    read_write = _IO_NO_READS;
-    break;
-  case 'a':
-    omode = O_WRONLY;
-    oflags = O_CREAT|O_APPEND;
-    read_write = _IO_NO_READS|_IO_IS_APPENDING;
-    break;
-  default:
-    errno = EINVAL;
-    return NULL;
-  }
-  if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) {
-    omode = O_RDWR;
-    read_write &= _IO_IS_APPENDING;
-  }
-  fdesc = open(filename, omode|oflags, oprot);
+  switch (*mode++)
+    {
+    case 'r':
+      omode = O_RDONLY;
+      read_write = _IO_NO_WRITES;
+      break;
+    case 'w':
+      omode = O_WRONLY;
+      oflags = O_CREAT|O_TRUNC;
+      read_write = _IO_NO_READS;
+      break;
+    case 'a':
+      omode = O_WRONLY;
+      oflags = O_CREAT|O_APPEND;
+      read_write = _IO_NO_READS|_IO_IS_APPENDING;
+      break;
+    default:
+      __set_errno (EINVAL);
+      return NULL;
+    }
+  if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
+    {
+      omode = O_RDWR;
+      read_write &= _IO_IS_APPENDING;
+    }
+  fdesc = open (filename, omode|oflags, oprot);
   if (fdesc < 0)
     return NULL;
   fp->_fileno = fdesc;
-  _IO_mask_flags(fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+  _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
   if (read_write & _IO_IS_APPENDING)
     if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
-	== _IO_pos_BAD)
+	== _IO_pos_BAD && errno != ESPIPE)
       return NULL;
-  _IO_link_in(fp);
+  _IO_link_in (fp);
   return fp;
 }
 
-_IO_FILE*
-DEFUN(_IO_file_attach, (fp, fd),
-      _IO_FILE *fp AND int fd)
+_IO_FILE *
+_IO_file_attach (fp, fd)
+     _IO_FILE *fp;
+     int fd;
 {
-  if (_IO_file_is_open(fp))
+  if (_IO_file_is_open (fp))
     return NULL;
   fp->_fileno = fd;
   fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
   fp->_flags |= _IO_DELETE_DONT_CLOSE;
+  /* Get the current position of the file. */
+  /* We have to do that since that may be junk. */
   fp->_offset = _IO_pos_BAD;
+  if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
+      == _IO_pos_BAD && errno != ESPIPE)
+    return NULL;
   return fp;
 }
 
-_IO_FILE*
-DEFUN(_IO_file_setbuf, (fp, p, len),
-      register _IO_FILE *fp AND char* p AND _IO_ssize_t len)
+_IO_FILE *
+_IO_file_setbuf (fp, p, len)
+     _IO_FILE *fp;
+     char *p;
+     _IO_ssize_t len;
 {
-    if (_IO_default_setbuf(fp, p, len) == NULL)
-	return NULL;
+    if (_IO_default_setbuf (fp, p, len) == NULL)
+      return NULL;
 
     fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
       = fp->_IO_buf_base;
-    _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+    _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
 
     return fp;
 }
@@ -219,44 +240,42 @@
    Then mark FP as having empty buffers. */
 
 int
-DEFUN(_IO_do_write, (fp, data, to_do),
-      register _IO_FILE *fp AND const char* data AND _IO_size_t to_do)
+_IO_do_write (fp, data, to_do)
+     _IO_FILE *fp;
+     const char *data;
+     _IO_size_t to_do;
 {
   _IO_size_t count;
   if (to_do == 0)
     return 0;
-  else
-    {
-      if (fp->_flags & _IO_IS_APPENDING)
-	/* On a system without a proper O_APPEND implementation,
-	   you would need to sys_seek(0, SEEK_END) here, but is
-	   is not needed nor desirable for Unix- or Posix-like systems.
-	   Instead, just indicate that offset (before and after) is
-	   unpredictable. */
-	fp->_offset = _IO_pos_BAD;
-      else if (fp->_IO_read_end != fp->_IO_write_base)
-	{ 
-	  _IO_pos_t new_pos
-	    = _IO_SYSSEEK(fp, fp->_IO_write_base - fp->_IO_read_end, 1);
-	  if (new_pos == _IO_pos_BAD)
-	    return EOF;
-	  fp->_offset = new_pos;
-	}
-      count = _IO_SYSWRITE (fp, data, to_do);
-      if (fp->_cur_column)
-	fp->_cur_column
-	  = _IO_adjust_column (fp->_cur_column - 1, data, to_do) + 1;
+  if (fp->_flags & _IO_IS_APPENDING)
+    /* On a system without a proper O_APPEND implementation,
+       you would need to sys_seek(0, SEEK_END) here, but is
+       is not needed nor desirable for Unix- or Posix-like systems.
+       Instead, just indicate that offset (before and after) is
+       unpredictable. */
+    fp->_offset = _IO_pos_BAD;
+  else if (fp->_IO_read_end != fp->_IO_write_base)
+    {
+      _IO_pos_t new_pos
+	= _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
+      if (new_pos == _IO_pos_BAD)
+	return EOF;
+      fp->_offset = new_pos;
     }
-  _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+  count = _IO_SYSWRITE (fp, data, to_do);
+  if (fp->_cur_column)
+    fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, to_do) + 1;
+  _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
-  fp->_IO_write_end = (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) ? fp->_IO_buf_base
-    : fp->_IO_buf_end;
+  fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+		       ? fp->_IO_buf_base : fp->_IO_buf_end);
   return count != to_do ? EOF : 0;
 }
 
 int
-DEFUN(_IO_file_underflow, (fp),
-      register _IO_FILE *fp)
+_IO_file_underflow (fp)
+     _IO_FILE *fp;
 {
   _IO_ssize_t count;
 #if 0
@@ -266,19 +285,31 @@
 #endif
 
   if (fp->_flags & _IO_NO_READS)
-    return EOF;
+    {
+      __set_errno (EBADF);
+      return EOF;
+    }
   if (fp->_IO_read_ptr < fp->_IO_read_end)
-    return *(unsigned char*)fp->_IO_read_ptr;
+    return *(unsigned char *) fp->_IO_read_ptr;
 
   if (fp->_IO_buf_base == NULL)
-    _IO_doallocbuf(fp);
+    _IO_doallocbuf (fp);
 
   /* Flush all line buffered files before reading. */
   /* FIXME This can/should be moved to genops ?? */
   if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
-    _IO_flush_all_linebuffered();
+    _IO_flush_all_linebuffered ();
 
-  _IO_switch_to_get_mode(fp);
+  _IO_switch_to_get_mode (fp);
+
+  /* This is very tricky. We have to adjust those
+     pointers before we call _IO_SYSREAD () since
+     we may longjump () out while waiting for
+     input. Those pointers may be screwed up. H.J. */
+  fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
+  fp->_IO_read_end = fp->_IO_buf_base;
+  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+    = fp->_IO_buf_base;
 
   count = _IO_SYSREAD (fp, fp->_IO_buf_base,
 		       fp->_IO_buf_end - fp->_IO_buf_base);
@@ -289,30 +320,32 @@
       else
 	fp->_flags |= _IO_ERR_SEEN, count = 0;
   }
-  fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
-  fp->_IO_read_end = fp->_IO_buf_base + count;
-  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
-    = fp->_IO_buf_base;
+  fp->_IO_read_end += count;
   if (count == 0)
     return EOF;
   if (fp->_offset != _IO_pos_BAD)
-    _IO_pos_adjust(fp->_offset, count);
-  return *(unsigned char*)fp->_IO_read_ptr;
+    _IO_pos_adjust (fp->_offset, count);
+  return *(unsigned char *) fp->_IO_read_ptr;
 }
 
 int
-DEFUN(_IO_file_overflow, (f, ch),
-      register _IO_FILE* f AND int ch)
+_IO_file_overflow (f, ch)
+      _IO_FILE *f;
+      int ch;
 {
   if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
-    return EOF;
+    {
+      f->_flags |= _IO_ERR_SEEN;
+      __set_errno (EBADF);
+      return EOF;
+    }
   /* If currently reading or no buffer allocated. */
   if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
     {
       /* Allocate a buffer if needed. */
       if (f->_IO_write_base == 0)
 	{
-	  _IO_doallocbuf(f);
+	  _IO_doallocbuf (f);
 	  _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
 	}
       /* Otherwise must be currently reading.
@@ -334,35 +367,35 @@
       f->_flags |= _IO_CURRENTLY_PUTTING;
     }
   if (ch == EOF)
-    return _IO_do_flush(f);
+    return _IO_do_flush (f);
   if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
-    if (_IO_do_flush(f) == EOF)
+    if (_IO_do_flush (f) == EOF)
       return EOF;
   *f->_IO_write_ptr++ = ch;
   if ((f->_flags & _IO_UNBUFFERED)
       || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
-    if (_IO_do_flush(f) == EOF)
+    if (_IO_do_flush (f) == EOF)
       return EOF;
-  return (unsigned char)ch;
+  return (unsigned char) ch;
 }
 
 int
-DEFUN(_IO_file_sync, (fp),
-      register _IO_FILE* fp)
+_IO_file_sync (fp)
+     _IO_FILE *fp;
 {
   _IO_size_t delta;
   /*    char* ptr = cur_ptr(); */
   if (fp->_IO_write_ptr > fp->_IO_write_base)
     if (_IO_do_flush(fp)) return EOF;
-  delta = fp->_IO_read_ptr - fp->_IO_read_end; 
+  delta = fp->_IO_read_ptr - fp->_IO_read_end;
   if (delta != 0)
     {
 #ifdef TODO
-      if (_IO_in_backup(fp))
-	delta -= eGptr() - Gbase();
+      if (_IO_in_backup (fp))
+	delta -= eGptr () - Gbase ();
 #endif
       _IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1);
-      if (new_pos != (_IO_off_t)EOF)
+      if (new_pos != (_IO_off_t) EOF)
 	fp->_IO_read_end = fp->_IO_read_ptr;
 #ifdef ESPIPE
       else if (errno == ESPIPE)
@@ -378,12 +411,19 @@
 }
 
 _IO_pos_t
-DEFUN(_IO_file_seekoff, (fp, offset, dir, mode),
-      register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
+_IO_file_seekoff (fp, offset, dir, mode)
+     _IO_FILE *fp;
+     _IO_off_t offset;
+     int dir;
+     int mode;
 {
   _IO_pos_t result;
   _IO_off_t delta, new_offset;
   long count;
+  /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
+     offset of the underlying file must be exact.  */
+  int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
+		       && fp->_IO_write_base == fp->_IO_write_ptr);
 
   if (mode == 0)
     dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
@@ -396,14 +436,15 @@
      end up flushing when we close(), it doesn't make much difference.)
      FIXME: simulate mem-papped files. */
 
-  if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode(fp))
-    if (_IO_switch_to_get_mode(fp)) return EOF;
+  if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
+    if (_IO_switch_to_get_mode (fp))
+      return EOF;
 
   if (fp->_IO_buf_base == NULL)
     {
-      _IO_doallocbuf(fp);
-      _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
-      _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+      _IO_doallocbuf (fp);
+      _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+      _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
     }
 
   switch (dir)
@@ -414,7 +455,7 @@
       if (fp->_offset == _IO_pos_BAD)
 	goto dumb;
       /* Make offset absolute, assuming current pointer is file_ptr(). */
-      offset += _IO_pos_as_off(fp->_offset);
+      offset += _IO_pos_as_off (fp->_offset);
 
       dir = _IO_seek_set;
       break;
@@ -423,7 +464,7 @@
     case _IO_seek_end:
       {
 	struct stat st;
-	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG(st.st_mode))
+	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
 	  {
 	    offset += st.st_size;
 	    dir = _IO_seek_set;
@@ -439,46 +480,46 @@
       && !_IO_in_backup (fp))
     {
       /* Offset relative to start of main get area. */
-      _IO_pos_t rel_offset = offset - fp->_offset
-	+ (fp->_IO_read_end - fp->_IO_read_base);
+      _IO_pos_t rel_offset = (offset - fp->_offset
+			      + (fp->_IO_read_end - fp->_IO_read_base));
       if (rel_offset >= 0)
 	{
 #if 0
-	  if (_IO_in_backup(fp))
-	    _IO_switch_to_main_get_area(fp);
+	  if (_IO_in_backup (fp))
+	    _IO_switch_to_main_get_area (fp);
 #endif
 	  if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
 	    {
-	      _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
-		       fp->_IO_read_end);
-	      _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
+	      _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
+			fp->_IO_read_end);
+	      _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
 	      return offset;
 	    }
 #ifdef TODO
 	    /* If we have streammarkers, seek forward by reading ahead. */
-	    if (_IO_have_markers(fp))
+	    if (_IO_have_markers (fp))
 	      {
 		int to_skip = rel_offset
 		  - (fp->_IO_read_ptr - fp->_IO_read_base);
-		if (ignore(to_skip) != to_skip)
+		if (ignore (to_skip) != to_skip)
 		  goto dumb;
 		return offset;
 	      }
 #endif
 	}
 #ifdef TODO
-      if (rel_offset < 0 && rel_offset >= Bbase() - Bptr())
+      if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
 	{
-	  if (!_IO_in_backup(fp))
-	    _IO_switch_to_backup_area(fp);
-	  gbump(fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
+	  if (!_IO_in_backup (fp))
+	    _IO_switch_to_backup_area (fp);
+	  gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
 	  return offset;
 	}
 #endif
     }
 
 #ifdef TODO
-  _IO_unsave_markers(fp);
+  _IO_unsave_markers (fp);
 #endif
 
   if (fp->_flags & _IO_NO_READS)
@@ -500,7 +541,8 @@
   else
     {
       count = _IO_SYSREAD (fp, fp->_IO_buf_base,
-			   fp->_IO_buf_end - fp->_IO_buf_base);
+			   (must_be_exact
+			    ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
       if (count < delta)
 	{
 	  /* We weren't allowed to read, but try to seek the remainder. */
@@ -509,31 +551,38 @@
 	  goto dumb;
 	}
     }
-  _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base+delta, fp->_IO_buf_base+count);
-  _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
+  _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
+	    fp->_IO_buf_base + count);
+  _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
   fp->_offset = result + count;
-  _IO_mask_flags(fp, 0, _IO_EOF_SEEN);
+  _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
   return offset;
  dumb:
 
-  _IO_unsave_markers(fp);
+  _IO_unsave_markers (fp);
   result = _IO_SYSSEEK (fp, offset, dir);
   if (result != EOF)
-    _IO_mask_flags(fp, 0, _IO_EOF_SEEN);
+    _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
   fp->_offset = result;
-  _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
-  _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
+  _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+  _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
   return result;
 }
 
 _IO_ssize_t
-DEFUN(_IO_file_read, (fp, buf, size),
-      register _IO_FILE* fp AND void* buf AND _IO_ssize_t size)
+_IO_file_read (fp, buf, size)
+     _IO_FILE *fp;
+     void *buf;
+     _IO_ssize_t size;
 {
   for (;;)
     {
-      _IO_ssize_t count = _IO_read(fp->_fileno, buf, size);
-#ifdef EINTR
+      _IO_ssize_t count = _IO_read (fp->_fileno, buf, size);
+#if 0 && defined EINTR
+      /* We must not do this optimization since POSIX.1 explicitly
+	 requests that the stream operations must return with the
+	 error EINTR if this happens.  There must be the possibility
+	 that stream operations time out.  --drepper  */
       if (count == -1 && errno == EINTR)
 	continue;
 #endif
@@ -542,37 +591,46 @@
 }
 
 _IO_pos_t
-DEFUN(_IO_file_seek, (fp, offset, dir),
-      _IO_FILE *fp AND _IO_off_t offset AND int dir)
+_IO_file_seek (fp, offset, dir)
+     _IO_FILE *fp;
+     _IO_off_t offset;
+     int dir;
 {
-  return _IO_lseek(fp->_fileno, offset, dir);
+  return _IO_lseek (fp->_fileno, offset, dir);
 }
 
 int
-DEFUN(_IO_file_stat, (fp, st),
-      _IO_FILE *fp AND void* st)
+_IO_file_stat (fp, st)
+     _IO_FILE *fp;
+     void *st;
 {
-  return _IO_fstat(fp->_fileno, (struct stat*)st);
+  return _IO_fstat (fp->_fileno, (struct stat *) st);
 }
 
 int
-DEFUN(_IO_file_close, (fp),
-      _IO_FILE* fp)
+_IO_file_close (fp)
+     _IO_FILE *fp;
 {
-  return _IO_close(fp->_fileno);
+  return _IO_close (fp->_fileno);
 }
 
 _IO_ssize_t
-DEFUN(_IO_file_write, (f, data, n),
-      register _IO_FILE* f AND const void* data AND _IO_ssize_t n)
+_IO_file_write (f, data, n)
+     _IO_FILE *f;
+     const void *data;
+     _IO_ssize_t n;
 {
   _IO_ssize_t to_do = n;
   while (to_do > 0)
     {
-      _IO_ssize_t count = _IO_write(f->_fileno, data, to_do);
+      _IO_ssize_t count = _IO_write (f->_fileno, data, to_do);
       if (count == EOF)
 	{
-#ifdef EINTR
+#if 0 && defined EINTR
+	  /* We must not do this optimization since POSIX.1 explicitly
+	     requests that the stream operations must return with the
+	     error EINTR if this happens.  There must be the
+	     possibility that stream operations time out.  --drepper  */
 	  if (errno == EINTR)
 	    continue;
 	  else
@@ -583,7 +641,7 @@
             }
         }
       to_do -= count;
-      data = (void*)((char*)data + count);
+      data = (void *) ((char *) data + count);
     }
   n -= to_do;
   if (f->_offset >= 0)
@@ -592,10 +650,12 @@
 }
 
 _IO_size_t
-DEFUN(_IO_file_xsputn, (f, data, n),
-      _IO_FILE *f AND const void *data AND _IO_size_t n)
+_IO_file_xsputn (f, data, n)
+     _IO_FILE *f;
+     const void *data;
+     _IO_size_t n;
 {
-  register const char *s = (char*) data;
+  register const char *s = (char *) data;
   _IO_size_t to_do = n;
   int must_flush = 0;
   _IO_size_t count;
@@ -612,14 +672,16 @@
     {
       count = f->_IO_buf_end - f->_IO_write_ptr;
       if (count >= n)
-	{ register const char *p;
+	{
+	  register const char *p;
 	  for (p = s + n; p > s; )
 	    {
-	      if (*--p == '\n') {
-		count = p - s + 1;
-		must_flush = 1;
-		break;
-	      }
+	      if (*--p == '\n')
+		{
+		  count = p - s + 1;
+		  must_flush = 1;
+		  break;
+		}
 	    }
 	}
     }
@@ -628,23 +690,26 @@
     {
       if (count > to_do)
 	count = to_do;
-      if (count > 20) {
-	memcpy(f->_IO_write_ptr, s, count);
-	s += count;
-      }
+      if (count > 20)
+	{
+	  memcpy (f->_IO_write_ptr, s, count);
+	  s += count;
+	}
       else
 	{
 	  register char *p = f->_IO_write_ptr;
-	  register int i = (int)count;
-	  while (--i >= 0) *p++ = *s++;
+	  register int i = (int) count;
+	  while (--i >= 0)
+	    *p++ = *s++;
 	}
       f->_IO_write_ptr += count;
       to_do -= count;
     }
   if (to_do + must_flush > 0)
-    { _IO_size_t block_size, dont_write;
+    {
+      _IO_size_t block_size, dont_write;
       /* Next flush the (full) buffer. */
-      if (__overflow(f, EOF) == EOF)
+      if (__overflow (f, EOF) == EOF)
 	return n - to_do;
 
       /* Try to maintain alignment: write a whole number of blocks.
@@ -653,15 +718,15 @@
       dont_write = block_size >= 128 ? to_do % block_size : 0;
 
       count = to_do - dont_write;
-      if (_IO_do_write(f, s, count) == EOF)
+      if (_IO_do_write (f, s, count) == EOF)
 	return n - to_do;
       to_do = dont_write;
-      
+
       /* Now write out the remainder.  Normally, this will fit in the
 	 buffer, but it's somewhat messier for line-buffered files,
 	 so we let _IO_default_xsputn handle the general case. */
       if (dont_write)
-	to_do -= _IO_default_xsputn(f, s+count, dont_write);
+	to_do -= _IO_default_xsputn (f, s+count, dont_write);
     }
   return n - to_do;
 }
@@ -669,21 +734,24 @@
 #if 0
 /* Work in progress */
 _IO_size_t
-DEFUN(_IO_file_xsgetn, (fp, data, n),
-      _IO_FILE *fp AND void *data AND _IO_size_t n)
+_IO_file_xsgetn (fp, data, n)
+     _IO_FILE *fp;
+     void *data;
+     _IO_size_t n;
 {
   register _IO_size_t more = n;
   register char *s = data;
   for (;;)
     {
-      _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; /* Data available. */
+      /* Data available. */
+      _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
       if (count > 0)
 	{
 	  if (count > more)
 	    count = more;
 	  if (count > 20)
 	    {
-	      memcpy(s, fp->_IO_read_ptr, count);
+	      memcpy (s, fp->_IO_read_ptr, count);
 	      s += count;
 	      fp->_IO_read_ptr += count;
 	    }
@@ -692,8 +760,9 @@
 	  else
 	    {
 	      register char *p = fp->_IO_read_ptr;
-	      register int i = (int)count;
-	      while (--i >= 0) *s++ = *p++;
+	      register int i = (int) count;
+	      while (--i >= 0)
+		*s++ = *p++;
 	      fp->_IO_read_ptr = p;
             }
             more -= count;
@@ -708,11 +777,11 @@
 	  /* If we're reading a lot of data, don't bother allocating
 	     a buffer.  But if we're only reading a bit, perhaps we should ??*/
 	  if (count <= 512 && fp->_IO_buf_base == NULL)
-	    _IO_doallocbuf(fp);
+	    _IO_doallocbuf (fp);
 	  if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
-	    _IO_flush_all_linebuffered();
+	    _IO_flush_all_linebuffered ();
 
-	  _IO_switch_to_get_mode(fp); ???;
+	  _IO_switch_to_get_mode (fp); ???;
 	  count = _IO_SYSREAD (fp, s, more);
 	  if (count <= 0)
 	     {
@@ -721,19 +790,20 @@
 	       else
 		 fp->_flags |= _IO_ERR_SEEN, count = 0;
 	     }
-	  
+
 	  s += count;
 	  more -= count;
 	}
 #endif
-      if (more == 0 || __underflow(fp) == EOF)
+      if (more == 0 || __underflow (fp) == EOF)
 	break;
     }
   return n - more;
 }
 #endif
 
-struct _IO_jump_t _IO_file_jumps = {
+struct _IO_jump_t _IO_file_jumps =
+{
   JUMP_INIT_DUMMY,
   JUMP_INIT(finish, _IO_file_finish),
   JUMP_INIT(overflow, _IO_file_overflow),
Index: libio/gen-params
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/gen-params,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 gen-params
--- libio/gen-params	1997/08/26 00:21:27	1.1.1.1
+++ libio/gen-params	1997/08/26 01:42:20
@@ -276,7 +276,7 @@
 fi
 tr '	' ' ' <TMP >dummy.out
 
-for TYPE in dev_t clock_t fpos_t gid_t ino_t mode_t nlink_t off_t pid_t ptrdiff_t sigset_t size_t ssize_t time_t uid_t va_list wchar_t wint_t int16_t uint16_t int32_t uint_32_t u_int16_t u_int32_t; do
+for TYPE in dev_t clock_t fpos_t gid_t ino_t mode_t nlink_t off_t pid_t ptrdiff_t size_t ssize_t time_t uid_t va_list wchar_t wint_t int16_t uint16_t int32_t uint_32_t u_int16_t u_int32_t; do
     IMPORTED=`eval 'echo $'"$TYPE"`
     if [ -n "${IMPORTED}" ] ; then
 	eval "$TYPE='$IMPORTED'"
@@ -288,6 +288,8 @@
 	for iteration in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
 	    # Search dummy.out for a typedef for X*$t.
 	    sed_script="
+		s/unsigned long long int/_G_ullong/g
+		s/long long int/_G_llong/g
 		s/unsigned long long/_G_ullong/g
 		s/long long/_G_llong/g
 		/.*typedef  *\\(.*[^ ]\\)  *X*$t *;.*/{s||\1|;p;q;}
@@ -539,6 +541,20 @@
 
 
 # *** Check for presence of certain include files ***
+
+# check for features.h
+
+if test -n "${HAVE_FEATURES}" ; then
+ echo "#define ${macro_prefix}HAVE_FEATURES ${HAVE_FEATURES}"
+else
+  echo '#include <features.h>' >dummy.c
+  echo 'extern int myfunc __P((int, int));' >>dummy.c
+  if ${CC} -c dummy.c >/dev/null 2>&1 ; then
+    echo "#define ${macro_prefix}HAVE_FEATURES 1"
+  else
+    echo "#define ${macro_prefix}HAVE_FEATURES 0"
+  fi
+fi
 
 # check for sys/resource.h
 
Index: libio/genops.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/genops.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 genops.c
--- libio/genops.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/genops.c	1997/08/26 01:42:20
@@ -850,3 +850,115 @@
 #endif
 
 #endif /* TODO */
+
+#ifdef _IO_USE_LIBC
+/* We only include those files which are not compatible with
+   libio in libc. We need to make sure our version is always
+   used during linking. */
+extern int vfprintf ();
+extern _IO_FILE * popen ();
+static const void * const __dummy [] =
+{
+  &_IO_file_doallocate,
+  &_IO_dtoa,
+  &_IO_strtod,
+  &_IO_adjust_column,
+  &_IO_cleanup,
+  &_IO_default_doallocate,
+  &_IO_default_finish,
+  &_IO_default_pbackfail,
+  &_IO_default_read,
+  &_IO_default_seek,
+  &_IO_default_seekoff,
+  &_IO_default_seekpos,
+  &_IO_default_setbuf,
+  &_IO_default_stat,
+  &_IO_default_sync,
+  &_IO_default_uflow,
+  &_IO_default_underflow,
+  &_IO_default_write,
+  &_IO_default_xsgetn,
+  &_IO_default_xsputn,
+  &_IO_doallocbuf,
+  &_IO_flush_all,
+  &_IO_flush_all_linebuffered,
+  &_IO_free_backup_area,
+  &_IO_get_column,
+  &_IO_init,
+  &_IO_init_marker,
+  &_IO_least_marker,
+  &_IO_link_in,
+  &_IO_marker_delta,
+  &_IO_marker_difference,
+  &_IO_nobackup_pbackfail,
+  &_IO_remove_marker,
+  &_IO_seekmark,
+  &_IO_set_column,
+  &_IO_setb,
+  &_IO_sgetn,
+  &_IO_sputbackc,
+  &_IO_sungetc,
+  &_IO_switch_to_backup_area,
+  &_IO_switch_to_get_mode,
+  &_IO_switch_to_main_get_area,
+  &_IO_sync,
+  &_IO_un_link,
+  &_IO_unbuffer_all,
+  &_IO_unsave_markers,
+  &__overflow,
+  &__uflow,
+  &__underflow,
+  &_IO_do_write,
+  &_IO_file_attach,
+  &_IO_file_close,
+  &_IO_file_close_it,
+  &_IO_file_finish,
+  &_IO_file_fopen,
+  &_IO_file_init,
+  &_IO_file_jumps,
+  &_IO_file_overflow,
+  &_IO_file_read,
+  &_IO_file_seek,
+  &_IO_file_seekoff,
+  &_IO_file_setbuf,
+  &_IO_file_stat,
+  &_IO_file_sync,
+  &_IO_file_underflow,
+  &_IO_file_write,
+  &_IO_file_xsputn,
+  &_IO_vfprintf,
+  &vfprintf,
+  &_IO_vfscanf,
+  &_IO_padn,
+  &_IO_seekoff,
+  &_IO_seekpos,
+  &_IO_outfloat,
+  &_IO_str_count,
+  &_IO_str_finish,
+  &_IO_str_init_readonly,
+  &_IO_str_init_static,
+  &_IO_str_jumps,
+  &_IO_str_overflow,
+  &_IO_str_pbackfail,
+  &_IO_str_seekoff,
+  &_IO_str_underflow,
+  &_IO_fclose,
+  &_IO_popen,
+  &popen,
+  &_IO_proc_close,
+  &_IO_proc_jumps,
+  &_IO_proc_open,
+  &_IO_fdopen,
+  &_IO_fflush,
+  &_IO_fopen,
+  &_IO_fputs,
+  &_IO_fwrite,
+  &_IO_puts,
+  &_IO_setbuffer,
+  &_IO_setvbuf,
+  &_IO_vsprintf,
+  &_IO_vsscanf,
+  &_IO_vasprintf,
+  &_IO_vsnprintf
+};
+#endif
Index: libio/iofclose.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iofclose.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iofclose.c
--- libio/iofclose.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iofclose.c	1997/08/26 01:42:20
@@ -45,3 +45,7 @@
     }
   return status;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak fclose = _IO_fclose
+#endif
Index: libio/iofdopen.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iofdopen.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iofdopen.c
--- libio/iofdopen.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iofdopen.c	1997/08/26 01:42:20
@@ -119,3 +119,7 @@
 
   return (_IO_FILE*)fp;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak fdopen = _IO_fdopen
+#endif
Index: libio/iofflush.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iofflush.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iofflush.c
--- libio/iofflush.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iofflush.c	1997/08/26 01:42:20
@@ -36,3 +36,7 @@
       return _IO_SYNC (fp) ? EOF : 0;
     }
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak fflush = _IO_fflush
+#endif
Index: libio/iofopen.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iofopen.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iofopen.c
--- libio/iofopen.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iofopen.c	1997/08/26 01:42:20
@@ -47,3 +47,7 @@
   free (fp);
   return NULL;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak fopen = _IO_fopen
+#endif
Index: libio/iofputs.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iofputs.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iofputs.c
--- libio/iofputs.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iofputs.c	1997/08/26 01:42:20
@@ -35,3 +35,7 @@
     return EOF;
   return 1;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak fputs = _IO_fputs
+#endif
Index: libio/iofwrite.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iofwrite.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iofwrite.c
--- libio/iofwrite.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iofwrite.c	1997/08/26 01:42:20
@@ -42,3 +42,7 @@
   else
     return written/size;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak fwrite = _IO_fwrite
+#endif
Index: libio/iolibio.h
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iolibio.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iolibio.h
--- libio/iolibio.h	1997/08/26 00:21:27	1.1.1.1
+++ libio/iolibio.h	1997/08/26 01:06:51
@@ -32,6 +32,11 @@
 extern int _IO_ungetc __P((int, _IO_FILE*));
 extern int _IO_vsscanf __P((const char *, const char *, _IO_va_list));
 extern int _IO_vsprintf __P((char*, const char*, _IO_va_list));
+
+struct obstack;
+extern int _IO_obstack_vprintf __P ((struct obstack *, const char *,
+				     _IO_va_list));
+extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...));
 #ifndef _IO_pos_BAD
 #define _IO_pos_BAD ((_IO_fpos_t)(-1))
 #endif
@@ -51,3 +56,22 @@
 #ifdef __cplusplus
 }
 #endif
+
+#define _IO_open	__open
+#define _IO_close	__close
+#define	_IO_fork	__fork
+#define	_IO_fcntl	__fcntl
+#define _IO__exit	_exit
+#define _IO_read	__read
+#define _IO_write	__write
+#define _IO_lseek	__lseek
+#define	_IO_getdtablesize	__getdtablesize
+#define _IO_pipe	__pipe
+#define _IO_dup2	__dup2
+#define _IO_execl	execl
+#define _IO_waitpid	__waitpid
+#define _IO_stat        __stat
+#define _IO_getpid      __getpid
+#define _IO_geteuid     __geteuid
+#define _IO_getegid     __getegid
+#define _IO_fstat	__fstat
Index: libio/iopopen.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iopopen.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iopopen.c
--- libio/iopopen.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iopopen.c	1997/08/26 01:42:20
@@ -220,3 +220,7 @@
   JUMP_INIT(close, _IO_proc_close),
   JUMP_INIT(stat, _IO_file_stat)
 };
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC) && defined (__GNUC__)
+__asm__(".globl popen; popen = _IO_popen");
+#endif
Index: libio/ioputs.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/ioputs.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ioputs.c
--- libio/ioputs.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/ioputs.c	1997/08/26 01:42:20
@@ -36,3 +36,7 @@
     return EOF;
   return len+1;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak puts = _IO_puts
+#endif
Index: libio/iosetbuffer.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iosetbuffer.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iosetbuffer.c
--- libio/iosetbuffer.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iosetbuffer.c	1997/08/26 01:42:20
@@ -34,3 +34,7 @@
     size = 0;
   (void) _IO_SETBUF (fp, buf, size);
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak setbuffer = _IO_setbuffer
+#endif
Index: libio/iosetvbuf.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iosetvbuf.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iosetvbuf.c
--- libio/iosetvbuf.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iosetvbuf.c	1997/08/26 01:42:20
@@ -76,3 +76,7 @@
     }
   return _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak setvbuf = _IO_setvbuf
+#endif
Index: libio/iostream.cc
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iostream.cc,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iostream.cc
--- libio/iostream.cc	1997/08/26 00:21:27	1.1.1.1
+++ libio/iostream.cc	1997/08/26 01:42:20
@@ -35,6 +35,15 @@
 #include <string.h>
 #include <limits.h>
 #include "floatio.h"
+#if defined(__linux__) && !defined(_IO_USE_DTOA)
+#include <printf.h>
+extern "C" int __printf_fp __P ((FILE *,
+				const struct printf_info *,
+				const void *const*));
+#else
+extern "C" int __cvt_double (double, int, int, int *, int,
+			     char *, char *);
+#endif
 
 #define	BUF		(MAXEXP+MAXFRACT+1)	/* + decimal point */
 
@@ -321,7 +330,15 @@
 istream& istream::operator>>(long double& x)
 {
     if (ipfx0())
-	scan("%lg", &x);
+      {
+#if defined(__linux__) && !defined(_IO_USE_DTOA)
+	scan("%Lg", &x);
+#else
+	double y;
+	scan("%lg", &y);
+	x = y;
+#endif
+      }
     return *this;
 }
 
@@ -551,6 +568,62 @@
 }
 #endif /*__GNUC__*/
 
+#ifdef __linux__
+#ifdef _IO_USE_DTOA
+ostream& ostream::operator<<(long double n)
+{ return operator<<((double)n); }
+#else
+ostream& ostream::operator<<(long double n)
+{
+    if (opfx()) {
+	int format_char;
+	if ((flags() & ios::floatfield) == ios::fixed)
+	    format_char = 'f';
+	else if ((flags() & ios::floatfield) == ios::scientific)
+	    format_char = flags() & ios::uppercase ? 'E' : 'e';
+	else
+	    format_char = flags() & ios::uppercase ? 'G' : 'g';
+
+	int prec = precision();
+	if (prec <= 0 && !(flags() & ios::fixed))
+	  prec = 6; /* default */
+
+	// Do actual conversion.
+	struct printf_info info;
+
+#if 1
+	// Not all printf_info's have the extra field.
+	memset (&info, 0, sizeof (info));
+#else
+	info.is_short = 0;
+	info.is_long = 0;
+	info.space = 0;
+	info.group = 0;
+	info.extra = 0;
+#endif
+	info.prec = prec;
+	info.width = width (0);
+	info.spec = format_char;
+	info.is_long_double = 1;
+	info.alt = (flags() & ios::showpoint) != 0;
+	info.left = (flags() & ios::left) != 0;
+	info.showsign = (flags() & ios::showpos) != 0;
+	info.pad = fill();
+
+#if 0
+	_IO_va_list p = (_IO_va_list) &n;
+#else
+	const void *p = (const void *) &n;
+#endif
+	if (__printf_fp (rdbuf(), &info, &p) < 0)
+	    set(ios::badbit|ios::failbit); // ??
+	osfx();
+    }
+    return *this;
+}
+#endif
+#endif
+
 ostream& ostream::operator<<(double n)
 {
     if (opfx()) {
@@ -570,6 +643,37 @@
 	  prec = 6; /* default */
 
 	// Do actual conversion.
+#if defined(__linux__) && !defined(_IO_USE_DTOA)
+	struct printf_info info;
+
+#if 1
+	// Not all printf_info's have the extra field.
+	memset (&info, 0, sizeof (info));
+#else
+	info.is_long_double = 0;
+	info.is_short = 0;
+	info.is_long = 0;
+	info.space = 0;
+	info.group = 0;
+	info.extra = 0;
+#endif
+	info.prec = prec;
+	info.width = width (0);
+	info.spec = format_char;
+	info.alt = (flags() & ios::showpoint) != 0;
+	info.left = (flags() & ios::left) != 0;
+	info.showsign = (flags() & ios::showpos) != 0;
+	info.pad = fill();
+
+#if 0
+	_IO_va_list p = (_IO_va_list) &n;
+#else
+	const void *p = (const void *) &n;
+#endif
+
+	if (__printf_fp (rdbuf(), &info, &p) < 0)
+	    set(ios::badbit|ios::failbit); // ??
+#else
 #ifdef _IO_USE_DTOA
 	if (_IO_outfloat(n, rdbuf(), format_char, width(0),
 			 prec, flags(),
@@ -625,6 +729,7 @@
 
 	if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
 	    for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
+#endif
 #endif
 	osfx();
     }
Index: libio/iostream.h
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iostream.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iostream.h
--- libio/iostream.h	1997/08/26 00:21:27	1.1.1.1
+++ libio/iostream.h	1997/08/26 01:42:20
@@ -96,7 +96,11 @@
 #endif
     ostream& operator<<(double n);
     ostream& operator<<(float n) { return operator<<((double)n); }
+#ifdef __linux__
+    ostream& operator<<(long double n);
+#else
     ostream& operator<<(long double n) { return operator<<((double)n); }
+#endif
     ostream& operator<<(__omanip func) { return (*func)(*this); }
     ostream& operator<<(__manip func) {(*func)(*this); return *this;}
     ostream& operator<<(streambuf*);
Index: libio/iovfprintf.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iovfprintf.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iovfprintf.c
--- libio/iovfprintf.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iovfprintf.c	1997/08/26 01:42:20
@@ -72,6 +72,11 @@
 
 /* end of configuration stuff */
 
+#ifdef __STDC__
+int __cvt_double (double, int, int, int *, int, char *, char *);
+#else
+int __cvt_double ();
+#endif
 
 /*
  * Helper "class" for `fprintf to unbuffered': creates a
@@ -883,3 +888,7 @@
 }
 
 #endif /* defined(FLOATING_POINT) && !defined(_IO_USE_DTOA) */
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC) && defined (__GNUC__)
+__asm__(".globl vfprintf; vfprintf  = _IO_vfprintf");
+#endif
Index: libio/iovfscanf.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iovfscanf.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iovfscanf.c
--- libio/iovfscanf.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iovfscanf.c	1997/08/26 01:42:20
@@ -785,3 +785,15 @@
 	}
 	/* NOTREACHED */
 }
+
+#ifdef _IO_USE_LIBC
+int
+__vfscanf (_IO_FILE *s, const char *format, _IO_va_list argptr)
+{
+  return _IO_vfscanf (s, format, argptr, NULL);
+}
+
+#ifdef __ELF__
+#pragma weak vfscanf = __vfscanf
+#endif
+#endif
Index: libio/iovsprintf.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iovsprintf.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iovsprintf.c
--- libio/iovsprintf.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iovsprintf.c	1997/08/26 01:42:20
@@ -38,3 +38,7 @@
   _IO_putc('\0', (_IO_FILE*)&sf);
   return ret;
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak vsprintf = _IO_vsprintf
+#endif
Index: libio/iovsscanf.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/iovsscanf.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 iovsscanf.c
--- libio/iovsscanf.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/iovsscanf.c	1997/08/26 01:42:20
@@ -35,3 +35,8 @@
   _IO_str_init_static ((_IO_FILE*)&sf, (char*)string, 0, NULL);
   return _IO_vfscanf((_IO_FILE*)&sf, format, args, NULL);
 }
+
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak vsscanf = _IO_vsscanf
+#pragma weak __vsscanf = _IO_vsscanf
+#endif
Index: libio/libio.h
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/libio.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 libio.h
--- libio/libio.h	1997/08/26 00:21:27	1.1.1.1
+++ libio/libio.h	1997/08/26 15:06:32
@@ -1,33 +1,37 @@
-/* 
-Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation
-
-This file is part of the GNU IO Library.  This library is free
-software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this library; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-As a special exception, if you link this library with files
-compiled with a GNU compiler to produce an executable, this does not cause
-the resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why
-the executable file might be covered by the GNU General Public License. */
-
-/* This is part of the iostream library.  Written by Per Bothner. */
+/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
+   Written by Per Bothner <bothner@cygnus.com>.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
 
 #ifndef _IO_STDIO_H
 #define _IO_STDIO_H
-
 #include <_G_config.h>
+
+#if _G_HAVE_FEATURES
+#include <features.h>
+#endif
+
 #define _IO_pos_t _G_fpos_t /* obsolete */
 #define _IO_fpos_t _G_fpos_t
 #define _IO_size_t _G_size_t
@@ -42,60 +46,56 @@
 
 #ifdef _G_NEED_STDARG_H
 /* This define avoids name pollution if we're using GNU stdarg.h */
-#define __need___va_list
-#include <stdarg.h>
-#ifdef __GNUC_VA_LIST
-#undef _IO_va_list
-#define _IO_va_list __gnuc_va_list
-#endif /* __GNUC_VA_LIST */
+# define __need___va_list
+# include <stdarg.h>
+# ifdef __GNUC_VA_LIST
+#  undef _IO_va_list
+#  define _IO_va_list __gnuc_va_list
+# endif /* __GNUC_VA_LIST */
 #endif
 
 #ifndef __P
-#if _G_HAVE_SYS_CDEFS
-#include <sys/cdefs.h>
-#else
-#ifdef __STDC__
-#define __P(protos) protos
-#else
-#define __P(protos) ()
-#endif
-#endif
+# if _G_HAVE_SYS_CDEFS
+#  include <sys/cdefs.h>
+# else
+#  ifdef __STDC__
+#   define __P(protos) protos
+#  else
+#   define __P(protos) ()
+#  endif
+# endif
 #endif /*!__P*/
 
 /* For backward compatibility */
 #ifndef _PARAMS
-#define _PARAMS(protos) __P(protos)
+# define _PARAMS(protos) __P(protos)
 #endif /*!_PARAMS*/
 
 #ifndef __STDC__
-#define const
-#endif
-#ifndef _G_NO_USE_DTOA
-#define _IO_USE_DTOA
-#else
-#undef _IO_USE_DTOA
+# define const
 #endif
 #define _IO_UNIFIED_JUMPTABLES 1
 
 #if 0
-#ifdef _IO_NEED_STDARG_H
-#include <stdarg.h>
-#endif
+# ifdef _IO_NEED_STDARG_H
+#  include <stdarg.h>
+# endif
 #endif
 
 #ifndef EOF
-#define EOF (-1)
+# define EOF (-1)
 #endif
 #ifndef NULL
-#ifdef __GNUG__
-#define NULL (__null)
-#else
-#if !defined(__cplusplus)
-#define NULL ((void*)0)
-#else
-#define NULL (0)
-#endif
-#endif
+# if defined __GNUG__ && \
+    (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+#  define NULL (__null)
+# else
+#  if !defined(__cplusplus)
+#   define NULL ((void*)0)
+#  else
+#   define NULL (0)
+#  endif
+# endif
 #endif
 
 #define _IOS_INPUT	1
@@ -109,7 +109,7 @@
 
 /* Magic numbers and bits for the _flags field.
    The magic numbers use the high-order bits of _flags;
-   the remaining bits are abailable for variable flags.
+   the remaining bits are available for variable flags.
    Note: The magic numbers must all be negative if stdio
    emulation is desired. */
 
@@ -130,6 +130,7 @@
 #define _IO_CURRENTLY_PUTTING 0x800
 #define _IO_IS_APPENDING 0x1000
 #define _IO_IS_FILEBUF 0x2000
+#define _IO_BAD_SEEN 0x4000
 
 /* These are "formatting flags" matching the iostream fmtflags enum values. */
 #define _IO_SKIPWS 01
@@ -148,11 +149,35 @@
 #define _IO_UNITBUF 020000
 #define _IO_STDIO 040000
 #define _IO_DONT_CLOSE 0100000
+#define _IO_BOOLALPHA 0200000
 
-/* A streammarker remembers a position in a buffer. */
 
 struct _IO_jump_t;  struct _IO_FILE;
 
+/* Handle lock.  */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#ifdef _IO_MTSAFE_IO
+# if __GLIBC_MINOR__ >= 1
+#  include <bits/stdio-lock.h>
+# else
+#  include <stdio-lock.h>
+# endif
+#else
+typedef void _IO_lock_t;
+#endif
+#else
+#ifdef __linux__
+struct _IO_lock_t {
+  void *ptr;
+  short int field1;
+  short int field2;
+};
+#endif
+#endif
+
+
+/* A streammarker remembers a position in a buffer. */
+
 struct _IO_marker {
   struct _IO_marker *_next;
   struct _IO_FILE *_sbuf;
@@ -173,11 +198,7 @@
 };
 
 struct _IO_FILE {
-#if _G_USE_INT32_FLAGS
-  _G_int32_t _flags;	/* High-order word is _IO_MAGIC; rest is flags. */
-#else
-  int	     _flags;
-#endif
+  int _flags;		/* High-order word is _IO_MAGIC; rest is flags. */
 #define _IO_file_flags _flags
 
   /* The following pointers correspond to the C++ streambuf protocol. */
@@ -196,20 +217,28 @@
   char *_IO_save_end; /* Pointer to end of non-current get area. */
 
   struct _IO_marker *_markers;
-  
+
   struct _IO_FILE *_chain;
-  
+
   int _fileno;
   int _blksize;
   _IO_off_t _offset;
-  
+
 #define __HAVE_COLUMN /* temporary */
   /* 1+column number of pbase(); 0 is unknown. */
   unsigned short _cur_column;
   char _unused;
   char _shortbuf[1];
-  
+
   /*  char* _save_gptr;  char* _save_egptr; */
+
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+  _IO_lock_t *_lock;
+#else
+#ifdef __linux__
+  struct _IO_lock_t _lock;
+#endif
+#endif
 };
 
 #ifndef __cplusplus
@@ -222,43 +251,85 @@
 #define _IO_stdout ((_IO_FILE*)(&_IO_stdout_))
 #define _IO_stderr ((_IO_FILE*)(&_IO_stderr_))
 
+
+/* Define the user-visible type, with user-friendly member names.  */
+typedef struct
+{
+  _IO_ssize_t (*read) __P ((struct _IO_FILE *, void *, _IO_ssize_t));
+  _IO_ssize_t (*write) __P ((struct _IO_FILE *, const void *, _IO_ssize_t));
+  _IO_fpos_t (*seek) __P ((struct _IO_FILE *, _IO_off_t, int));
+  int (*close) __P ((struct _IO_FILE *));
+} _IO_cookie_io_functions_t;
+
+/* Special file type for fopencookie function.  */
+struct _IO_cookie_file
+{
+  struct _IO_FILE file;
+  const void *vtable;
+  void *cookie;
+  _IO_cookie_io_functions_t io_functions;
+};
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern int __underflow __P((_IO_FILE*));
-extern int __uflow __P((_IO_FILE*));
-extern int __overflow __P((_IO_FILE*, int));
-
-#define _IO_getc(_fp) \
-       ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow(_fp) \
-	: *(unsigned char*)(_fp)->_IO_read_ptr++)
-#define _IO_peekc(_fp) \
+extern int __underflow __P ((_IO_FILE *));
+extern int __uflow __P ((_IO_FILE *));
+extern int __overflow __P ((_IO_FILE *, int));
+
+#define _IO_getc_unlocked(_fp) \
+       ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow (_fp) \
+	: *(unsigned char *) (_fp)->_IO_read_ptr++)
+#define _IO_peekc_unlocked(_fp) \
        ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end \
-	  && __underflow(_fp) == EOF ? EOF \
-	: *(unsigned char*)(_fp)->_IO_read_ptr)
+	  && __underflow (_fp) == EOF ? EOF \
+	: *(unsigned char *) (_fp)->_IO_read_ptr)
 
-#define _IO_putc(_ch, _fp) \
+#define _IO_putc_unlocked(_ch, _fp) \
    (((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \
-    ? __overflow(_fp, (unsigned char)(_ch)) \
-    : (unsigned char)(*(_fp)->_IO_write_ptr++ = (_ch)))
+    ? __overflow (_fp, (unsigned char) (_ch)) \
+    : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch)))
+
+#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 __P ((_IO_FILE *__fp));
+extern int _IO_putc __P ((int __c, _IO_FILE *__fp));
+extern int _IO_feof __P ((_IO_FILE *__fp));
+extern int _IO_ferror __P ((_IO_FILE *__fp));
 
-#define _IO_feof(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
-#define _IO_ferror(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
+extern int _IO_peekc_locked __P ((_IO_FILE *__fp));
 
 /* This one is for Emacs. */
 #define _IO_PENDING_OUTPUT_COUNT(_fp)	\
 	((_fp)->_IO_write_ptr - (_fp)->_IO_write_base)
 
-extern int _IO_vfscanf __P((_IO_FILE*, const char*, _IO_va_list, int*));
-extern int _IO_vfprintf __P((_IO_FILE*, const char*, _IO_va_list));
-extern _IO_ssize_t _IO_padn __P((_IO_FILE *, int, _IO_ssize_t));
-extern _IO_size_t _IO_sgetn __P((_IO_FILE *, void*, _IO_size_t));
+extern void _IO_flockfile __P ((_IO_FILE *));
+extern void _IO_funlockfile __P ((_IO_FILE *));
+extern int _IO_ftrylockfile __P ((_IO_FILE *));
+
+#ifdef _IO_MTSAFE_IO
+# define _IO_peekc(_fp) _IO_peekc_locked (_fp)
+#else
+# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp)
+# define _IO_flockfile(_fp) /**/
+# define _IO_funlockfile(_fp) /**/
+# define _IO_ftrylockfile(_fp) /**/
+# define _IO_cleanup_region_start(_fct, _fp) /**/
+# define _IO_cleanup_region_end(_Doit) /**/
+#endif /* !_IO_MTSAFE_IO */
+
+extern int _IO_vfscanf __P ((_IO_FILE *, const char *, _IO_va_list, int *));
+extern int _IO_vfprintf __P ((_IO_FILE *, const char *, _IO_va_list));
+extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t));
+extern _IO_size_t _IO_sgetn __P ((_IO_FILE *, void *, _IO_size_t));
 
-extern _IO_fpos_t _IO_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
-extern _IO_fpos_t _IO_seekpos __P((_IO_FILE*, _IO_fpos_t, int));
+extern _IO_fpos_t _IO_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
 
-extern void _IO_free_backup_area __P((_IO_FILE*));
+extern void _IO_free_backup_area __P ((_IO_FILE *));
 
 #ifdef __cplusplus
 }
Index: libio/libioP.h
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/libioP.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 libioP.h
--- libio/libioP.h	1997/08/26 00:21:27	1.1.1.1
+++ libio/libioP.h	1997/08/27 01:57:30
@@ -1,56 +1,36 @@
-/* 
-Copyright (C) 1993 Free Software Foundation
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
 
-This file is part of the GNU IO Library.  This library is free
-software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this library; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-As a special exception, if you link this library with files
-compiled with a GNU compiler to produce an executable, this does not cause
-the resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why
-the executable file might be covered by the GNU General Public License. */
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
 
 #include <errno.h>
-#ifndef errno
-extern int errno;
+#ifdef _LIBC
+#include <bits/libc-lock.h>
 #endif
 
 #include "iolibio.h"
 
-#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(__cplusplus)
-/* All known AIX compilers implement these things (but don't always
-   define __STDC__).  The RISC/OS MIPS compiler defines these things
-   in SVR4 mode, but does not define __STDC__.  */
-
-#define	AND		,
-#define	DEFUN(name, arglist, args)	name(args)
-#define	DEFUN_VOID(name)		name(void)
-
-#else	/* Not ANSI C.  */
-
-#define	AND		;
-#ifndef const /* some systems define it in header files for non-ansi mode */
-#define	const
-#endif
-#define	DEFUN(name, arglist, args)	name arglist args;
-#define	DEFUN_VOID(name)		name()
-#endif	/* ANSI C.  */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 #define _IO_seek_set 0
 #define _IO_seek_cur 1
@@ -65,11 +45,11 @@
  * a jump table (of pointers to functions).  The pointer is accessed
  * with the _IO_JUMPS macro.  The jump table has a eccentric format,
  * so as to be compatible with the layout of a C++ virtual function table.
- * (as implemented by g++).  When a pointer to a steambuf object is
+ * (as implemented by g++).  When a pointer to a streambuf object is
  * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just
  * happens to point to the virtual function table of the streambuf.
  * Thus the _IO_JUMPS function table used for C stdio/libio does
- * double duty as the virtual functiuon table for C++ streambuf.
+ * double duty as the virtual function table for C++ streambuf.
  *
  * The entries in the _IO_JUMPS function table (and hence also the
  * virtual functions of a streambuf) are described below.
@@ -77,107 +57,108 @@
  * object being acted on (i.e. the 'this' parameter).
  */
 
-#define _IO_JUMPS(THIS) ((struct _IO_FILE_plus*)(THIS))->vtable
+#define _IO_JUMPS(THIS) ((struct _IO_FILE_plus *) (THIS))->vtable
 #ifdef _G_USING_THUNKS
-#define JUMP_FIELD(TYPE, NAME) TYPE NAME
-#define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC(THIS)
-#define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC(THIS, X1)
-#define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC(THIS, X1, X2)
-#define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC(THIS, X1,X2, X3)
-#define JUMP_INIT(NAME, VALUE) VALUE
-#define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT(dummy2, 0)
+# define JUMP_FIELD(TYPE, NAME) TYPE NAME
+# define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC (THIS)
+# define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC (THIS, X1)
+# define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC (THIS, X1, X2)
+# define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC (THIS, X1,X2, X3)
+# define JUMP_INIT(NAME, VALUE) VALUE
+# define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0)
 #else
 /* These macros will change when we re-implement vtables to use "thunks"! */
-#define JUMP_FIELD(TYPE, NAME) struct { short delta1, delta2; TYPE pfn; } NAME
-#define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC.pfn(THIS)
-#define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC.pfn(THIS, X1)
-#define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC.pfn(THIS, X1, X2)
-#define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC.pfn(THIS, X1,X2, X3)
-#define JUMP_INIT(NAME, VALUE) {0, 0, VALUE}
-#define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0)
+# define JUMP_FIELD(TYPE, NAME) struct { short delta1, delta2; TYPE pfn; } NAME
+# define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC.pfn (THIS)
+# define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1)
+# define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1, X2)
+# define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1,X2,X3)
+# define JUMP_INIT(NAME, VALUE) {0, 0, VALUE}
+# define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0)
 #endif
 
 /* The 'finish' function does any final cleaning up of an _IO_FILE object.
    It does not delete (free) it, but does everything else to finalize it/
    It matches the streambuf::~streambuf virtual destructor.  */
-typedef void (*_IO_finish_t) __P((_IO_FILE*)); /* finalize */
-#define _IO_FINISH(FP) JUMP0(__finish, FP)
+typedef void (*_IO_finish_t) __P ((_IO_FILE *, int)); /* finalize */
+#define _IO_FINISH(FP) JUMP1 (__finish, FP, 0)
 
 /* The 'overflow' hook flushes the buffer.
    The second argument is a character, or EOF.
    It matches the streambuf::overflow virtual function. */
-typedef int (*_IO_overflow_t) __P((_IO_FILE*, int));
-#define _IO_OVERFLOW(FP, CH) JUMP1(__overflow, FP, CH)
+typedef int (*_IO_overflow_t) __P ((_IO_FILE *, int));
+#define _IO_OVERFLOW(FP, CH) JUMP1 (__overflow, FP, CH)
 
 /* The 'underflow' hook tries to fills the get buffer.
    It returns the next character (as an unsigned char) or EOF.  The next
-   character remains in the get buffer, and the get postion is not changed.
+   character remains in the get buffer, and the get position is not changed.
    It matches the streambuf::underflow virtual function. */
-typedef int (*_IO_underflow_t) __P((_IO_FILE*));
-#define _IO_UNDERFLOW(FP) JUMP0(__underflow, FP)
+typedef int (*_IO_underflow_t) __P ((_IO_FILE *));
+#define _IO_UNDERFLOW(FP) JUMP0 (__underflow, FP)
 
 /* The 'uflow' hook returns the next character in the input stream
    (cast to unsigned char), and increments the read position;
    EOF is returned on failure.
    It matches the streambuf::uflow virtual function, which is not in the
    cfront implementation, but was added to C++ by the ANSI/ISO committee. */
-#define _IO_UFLOW(FP) JUMP0(__uflow, FP)
+#define _IO_UFLOW(FP) JUMP0 (__uflow, FP)
 
 /* The 'pbackfail' hook handles backing up.
    It matches the streambuf::pbackfail virtual function. */
-typedef int (*_IO_pbackfail_t) __P((_IO_FILE*, int));
-#define _IO_PBACKFAIL(FP, CH) JUMP1(__pbackfail, FP, CH)
+typedef int (*_IO_pbackfail_t) __P ((_IO_FILE *, int));
+#define _IO_PBACKFAIL(FP, CH) JUMP1 (__pbackfail, FP, CH)
 
 /* The 'xsputn' hook writes upto N characters from buffer DATA.
    Returns the number of character actually written.
    It matches the streambuf::xsputn virtual function. */
-typedef _IO_size_t (*_IO_xsputn_t)
-  __P((_IO_FILE *FP, const void *DATA, _IO_size_t N));
-#define _IO_XSPUTN(FP, DATA, N) JUMP2(__xsputn, FP, DATA, N)
+typedef _IO_size_t (*_IO_xsputn_t) __P ((_IO_FILE *FP, const void *DATA,
+					 _IO_size_t N));
+#define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N)
 
 /* The 'xsgetn' hook reads upto N characters into buffer DATA.
    Returns the number of character actually read.
    It matches the streambuf::xsgetn virtual function. */
-typedef _IO_size_t (*_IO_xsgetn_t) __P((_IO_FILE*FP, void*DATA, _IO_size_t N));
-#define _IO_XSGETN(FP, DATA, N) JUMP2(__xsgetn, FP, DATA, N)
+typedef _IO_size_t (*_IO_xsgetn_t) __P ((_IO_FILE *FP, void *DATA,
+					 _IO_size_t N));
+#define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N)
 
 /* The 'seekoff' hook moves the stream position to a new position
    relative to the start of the file (if DIR==0), the current position
    (MODE==1), or the end of the file (MODE==2).
    It matches the streambuf::seekoff virtual function.
    It is also used for the ANSI fseek function. */
-typedef _IO_fpos_t (*_IO_seekoff_t)
-  __P((_IO_FILE* FP, _IO_off_t OFF, int DIR, int MODE));
-#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3(__seekoff, FP, OFF, DIR, MODE)
+typedef _IO_fpos_t (*_IO_seekoff_t) __P ((_IO_FILE *FP, _IO_off_t OFF,
+					  int DIR, int MODE));
+#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE)
 
 /* The 'seekpos' hook also moves the stream position,
    but to an absolute position given by a fpos_t (seekpos).
    It matches the streambuf::seekpos virtual function.
    It is also used for the ANSI fgetpos and fsetpos functions.  */
 /* The _IO_seek_cur and _IO_seek_end options are not allowed. */
-typedef _IO_fpos_t (*_IO_seekpos_t) __P((_IO_FILE*, _IO_fpos_t, int));
-#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2(__seekpos, FP, POS, FLAGS)
+typedef _IO_fpos_t (*_IO_seekpos_t) __P ((_IO_FILE *, _IO_fpos_t, int));
+#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS)
 
 /* The 'setbuf' hook gives a buffer to the file.
    It matches the streambuf::setbuf virtual function. */
-typedef _IO_FILE* (*_IO_setbuf_t) __P((_IO_FILE*, char *, _IO_ssize_t));
-#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2(__setbuf, FP, BUFFER, LENGTH)
+typedef _IO_FILE* (*_IO_setbuf_t) __P ((_IO_FILE *, char *, _IO_ssize_t));
+#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH)
 
 /* The 'sync' hook attempts to synchronize the internal data structures
    of the file with the external state.
    It matches the streambuf::sync virtual function. */
-typedef int (*_IO_sync_t) __P((_IO_FILE*));
-#define _IO_SYNC(FP) JUMP0(__sync, FP)
+typedef int (*_IO_sync_t) __P ((_IO_FILE *));
+#define _IO_SYNC(FP) JUMP0 (__sync, FP)
 
 /* The 'doallocate' hook is used to tell the file to allocate a buffer.
    It matches the streambuf::doallocate virtual function, which is not
    in the ANSI/ISO C++ standard, but is part traditional implementations. */
-typedef int (*_IO_doallocate_t) __P((_IO_FILE*));
-#define _IO_DOALLOCATE(FP) JUMP0(__doallocate, FP)
+typedef int (*_IO_doallocate_t) __P ((_IO_FILE *));
+#define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP)
 
 /* The following four hooks (sysread, syswrite, sysclose, sysseek, and
    sysstat) are low-level hooks specific to this implementation.
-   There is no correspondance in the ANSI/ISO C++ standard library.
+   There is no correspondence in the ANSI/ISO C++ standard library.
    The hooks basically correspond to the Unix system functions
    (read, write, close, lseek, and stat) except that a _IO_FILE*
    parameter is used instead of a integer file descriptor;  the default
@@ -189,43 +170,44 @@
 /* The 'sysread' hook is used to read data from the external file into
    an existing buffer.  It generalizes the Unix read(2) function.
    It matches the streambuf::sys_read virtual function, which is
-   specific to this implementaion. */
-typedef _IO_ssize_t (*_IO_read_t) __P((_IO_FILE*, void*, _IO_ssize_t));
-#define _IO_SYSREAD(FP, DATA, LEN) JUMP2(__read, FP, DATA, LEN)
+   specific to this implementation. */
+typedef _IO_ssize_t (*_IO_read_t) __P ((_IO_FILE *, void *, _IO_ssize_t));
+#define _IO_SYSREAD(FP, DATA, LEN) JUMP2 (__read, FP, DATA, LEN)
 
 /* The 'syswrite' hook is used to write data from an existing buffer
    to an external file.  It generalizes the Unix write(2) function.
    It matches the streambuf::sys_write virtual function, which is
-   specific to this implementaion. */
-typedef _IO_ssize_t (*_IO_write_t) __P((_IO_FILE*,const void*,_IO_ssize_t));
-#define _IO_SYSWRITE(FP, DATA, LEN) JUMP2(__write, FP, DATA, LEN)
+   specific to this implementation. */
+typedef _IO_ssize_t (*_IO_write_t) __P ((_IO_FILE *,const void *,_IO_ssize_t));
+#define _IO_SYSWRITE(FP, DATA, LEN) JUMP2 (__write, FP, DATA, LEN)
 
 /* The 'sysseek' hook is used to re-position an external file.
    It generalizes the Unix lseek(2) function.
    It matches the streambuf::sys_seek virtual function, which is
-   specific to this implementaion. */
-typedef _IO_fpos_t (*_IO_seek_t) __P((_IO_FILE*, _IO_off_t, int));
-#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2(__seek, FP, OFFSET, MODE)
+   specific to this implementation. */
+typedef _IO_fpos_t (*_IO_seek_t) __P ((_IO_FILE *, _IO_off_t, int));
+#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE)
 
 /* The 'sysclose' hook is used to finalize (close, finish up) an
    external file.  It generalizes the Unix close(2) function.
    It matches the streambuf::sys_close virtual function, which is
    specific to this implementation. */
-typedef int (*_IO_close_t) __P((_IO_FILE*)); /* finalize */
-#define _IO_SYSCLOSE(FP) JUMP0(__close, FP)
+typedef int (*_IO_close_t) __P ((_IO_FILE *)); /* finalize */
+#define _IO_SYSCLOSE(FP) JUMP0 (__close, FP)
 
 /* The 'sysstat' hook is used to get information about an external file
    into a struct stat buffer.  It generalizes the Unix fstat(2) call.
    It matches the streambuf::sys_stat virtual function, which is
-   specific to this implementaion. */
-typedef int (*_IO_stat_t) __P((_IO_FILE*, void*));
-#define _IO_SYSSTAT(FP, BUF) JUMP1(__stat, FP, BUF)
+   specific to this implementation. */
+typedef int (*_IO_stat_t) __P ((_IO_FILE *, void *));
+#define _IO_SYSSTAT(FP, BUF) JUMP1 (__stat, FP, BUF)
 
 
 #define _IO_CHAR_TYPE char /* unsigned char ? */
 #define _IO_INT_TYPE int
 
-struct _IO_jump_t {
+struct _IO_jump_t
+{
     JUMP_FIELD(_G_size_t, __dummy);
 #ifdef _G_USING_THUNKS
     JUMP_FIELD(_G_size_t, __dummy2);
@@ -259,60 +241,69 @@
    This is for compatibility with C++ streambuf; the word can
    be used to smash to a pointer to a virtual function table. */
 
-struct _IO_FILE_plus {
+struct _IO_FILE_plus
+{
   _IO_FILE file;
   const struct _IO_jump_t *vtable;
 };
 
 /* Generic functions */
 
-extern int _IO_switch_to_get_mode __P((_IO_FILE*));
-extern void _IO_init __P((_IO_FILE*, int));
-extern int _IO_sputbackc __P((_IO_FILE*, int));
-extern int _IO_sungetc __P((_IO_FILE*));
-extern void _IO_un_link __P((_IO_FILE*));
-extern void _IO_link_in __P((_IO_FILE *));
-extern void _IO_doallocbuf __P((_IO_FILE*));
-extern void _IO_unsave_markers __P((_IO_FILE*));
-extern void _IO_setb __P((_IO_FILE*, char*, char*, int));
-extern unsigned _IO_adjust_column __P((unsigned, const char *, int));
-#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN(__fp, __s, __n)
+extern _IO_fpos_t _IO_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
+
+extern void _IO_switch_to_main_get_area __P ((_IO_FILE *));
+extern void _IO_switch_to_backup_area __P ((_IO_FILE *));
+extern int _IO_switch_to_get_mode __P ((_IO_FILE *));
+extern void _IO_init __P ((_IO_FILE *, int));
+extern int _IO_sputbackc __P ((_IO_FILE *, int));
+extern int _IO_sungetc __P ((_IO_FILE *));
+extern void _IO_un_link __P ((_IO_FILE *));
+extern void _IO_link_in __P ((_IO_FILE *));
+extern void _IO_doallocbuf __P ((_IO_FILE *));
+extern void _IO_unsave_markers __P ((_IO_FILE *));
+extern void _IO_setb __P ((_IO_FILE *, char *, char *, int));
+extern unsigned _IO_adjust_column __P ((unsigned, const char *, int));
+#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n)
 
 /* Marker-related function. */
 
-extern void _IO_init_marker __P((struct _IO_marker *, _IO_FILE *));
-extern void _IO_remove_marker __P((struct _IO_marker*));
-extern int _IO_marker_difference __P((struct _IO_marker *, struct _IO_marker *));
-extern int _IO_marker_delta __P((struct _IO_marker *));
-extern int _IO_seekmark __P((_IO_FILE *, struct _IO_marker *, int));
+extern void _IO_init_marker __P ((struct _IO_marker *, _IO_FILE *));
+extern void _IO_remove_marker __P ((struct _IO_marker *));
+extern int _IO_marker_difference __P ((struct _IO_marker *,
+				       struct _IO_marker *));
+extern int _IO_marker_delta __P ((struct _IO_marker *));
+extern int _IO_seekmark __P ((_IO_FILE *, struct _IO_marker *, int));
 
 /* Default jumptable functions. */
 
-extern int _IO_default_underflow __P((_IO_FILE*));
-extern int _IO_default_uflow __P((_IO_FILE*));
-extern int _IO_default_doallocate __P((_IO_FILE*));
-extern void _IO_default_finish __P((_IO_FILE *));
-extern int _IO_default_pbackfail __P((_IO_FILE*, int));
-extern _IO_FILE* _IO_default_setbuf __P((_IO_FILE *, char*, _IO_ssize_t));
-extern _IO_size_t _IO_default_xsputn __P((_IO_FILE *, const void*, _IO_size_t));
-extern _IO_size_t _IO_default_xsgetn __P((_IO_FILE *, void*, _IO_size_t));
-extern _IO_fpos_t _IO_default_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
-extern _IO_fpos_t _IO_default_seekpos __P((_IO_FILE*, _IO_fpos_t, int));
-extern _IO_ssize_t _IO_default_write __P((_IO_FILE*,const void*,_IO_ssize_t));
-extern _IO_ssize_t _IO_default_read __P((_IO_FILE*, void*, _IO_ssize_t));
-extern int _IO_default_stat __P((_IO_FILE*, void*));
-extern _IO_fpos_t _IO_default_seek __P((_IO_FILE*, _IO_off_t, int));
-extern int _IO_default_sync __P((_IO_FILE*));
-#define _IO_default_close ((_IO_close_t)_IO_default_sync)
+extern int _IO_default_underflow __P ((_IO_FILE *));
+extern int _IO_default_uflow __P ((_IO_FILE *));
+extern int _IO_default_doallocate __P ((_IO_FILE *));
+extern void _IO_default_finish __P ((_IO_FILE *, int));
+extern int _IO_default_pbackfail __P ((_IO_FILE *, int));
+extern _IO_FILE* _IO_default_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
+extern _IO_size_t _IO_default_xsputn __P ((_IO_FILE *, const void *,
+					   _IO_size_t));
+extern _IO_size_t _IO_default_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
+extern _IO_fpos_t _IO_default_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_default_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
+extern _IO_ssize_t _IO_default_write __P ((_IO_FILE *, const void *,
+					   _IO_ssize_t));
+extern _IO_ssize_t _IO_default_read __P ((_IO_FILE *, void *, _IO_ssize_t));
+extern int _IO_default_stat __P ((_IO_FILE *, void *));
+extern _IO_fpos_t _IO_default_seek __P ((_IO_FILE *, _IO_off_t, int));
+extern int _IO_default_sync __P ((_IO_FILE *));
+#define _IO_default_close ((_IO_close_t) _IO_default_sync)
 
 extern struct _IO_jump_t _IO_file_jumps;
 extern struct _IO_jump_t _IO_streambuf_jumps;
 extern struct _IO_jump_t _IO_proc_jumps;
 extern struct _IO_jump_t _IO_str_jumps;
-extern int _IO_do_write __P((_IO_FILE*, const char*, _IO_size_t));
-extern int _IO_flush_all __P((void));
-extern void _IO_cleanup __P((void));
-extern void _IO_flush_all_linebuffered __P((void));
+extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
+extern int _IO_flush_all __P ((void));
+extern void _IO_cleanup __P ((void));
+extern void _IO_flush_all_linebuffered __P ((void));
 
 #define _IO_do_flush(_f) \
   _IO_do_write(_f, (_f)->_IO_write_base, \
@@ -331,81 +322,140 @@
 
 /* Jumptable functions for files. */
 
-extern int _IO_file_doallocate __P((_IO_FILE*));
-extern _IO_FILE* _IO_file_setbuf __P((_IO_FILE *, char*, _IO_ssize_t));
-extern _IO_fpos_t _IO_file_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
-extern _IO_size_t _IO_file_xsputn __P((_IO_FILE*,const void*,_IO_size_t));
-extern int _IO_file_stat __P((_IO_FILE*, void*));
-extern int _IO_file_close __P((_IO_FILE*));
-extern int _IO_file_underflow __P((_IO_FILE *));
-extern int _IO_file_overflow __P((_IO_FILE *, int));
+extern int _IO_file_doallocate __P ((_IO_FILE *));
+extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
+extern _IO_fpos_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t));
+extern int _IO_file_stat __P ((_IO_FILE *, void *));
+extern int _IO_file_close __P ((_IO_FILE *));
+extern int _IO_file_underflow __P ((_IO_FILE *));
+extern int _IO_file_overflow __P ((_IO_FILE *, int));
 #define _IO_file_is_open(__fp) ((__fp)->_fileno >= 0)
-extern void _IO_file_init __P((_IO_FILE*));
-extern _IO_FILE* _IO_file_fopen __P((_IO_FILE*, const char*, const char*));
-extern _IO_ssize_t _IO_file_write __P((_IO_FILE*,const void*,_IO_ssize_t));
-extern _IO_ssize_t _IO_file_read __P((_IO_FILE*, void*, _IO_ssize_t));
-extern int _IO_file_sync __P((_IO_FILE*));
-extern int _IO_file_close_it __P((_IO_FILE*));
-extern _IO_fpos_t _IO_file_seek __P((_IO_FILE *, _IO_off_t, int));
-extern void _IO_file_finish __P((_IO_FILE*));
-
-/* Other file functions. */
-extern _IO_FILE* _IO_file_attach __P((_IO_FILE *, int));
+extern void _IO_file_init __P ((_IO_FILE *));
+extern _IO_FILE* _IO_file_attach __P ((_IO_FILE *, int));
+extern _IO_FILE* _IO_file_fopen __P ((_IO_FILE *, const char *, const char *));
+extern _IO_ssize_t _IO_file_write __P ((_IO_FILE *, const void *,
+					_IO_ssize_t));
+extern _IO_ssize_t _IO_file_read __P ((_IO_FILE *, void *, _IO_ssize_t));
+extern int _IO_file_sync __P ((_IO_FILE *));
+extern int _IO_file_close_it __P ((_IO_FILE *));
+extern _IO_fpos_t _IO_file_seek __P ((_IO_FILE *, _IO_off_t, int));
+extern void _IO_file_finish __P ((_IO_FILE *, int));
 
 /* Jumptable functions for proc_files. */
-extern _IO_FILE* _IO_proc_open __P((_IO_FILE*, const char*, const char *));
-extern int _IO_proc_close __P((_IO_FILE*));
+extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *));
+extern int _IO_proc_close __P ((_IO_FILE *));
 
 /* Jumptable functions for strfiles. */
-extern int _IO_str_underflow __P((_IO_FILE*));
-extern int _IO_str_overflow __P((_IO_FILE *, int));
-extern int _IO_str_pbackfail __P((_IO_FILE*, int));
-extern _IO_fpos_t _IO_str_seekoff __P((_IO_FILE*,_IO_off_t,int,int));
+extern int _IO_str_underflow __P ((_IO_FILE *));
+extern int _IO_str_overflow __P ((_IO_FILE *, int));
+extern int _IO_str_pbackfail __P ((_IO_FILE *, int));
+extern _IO_fpos_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
+extern void _IO_str_finish __P ((_IO_FILE *, int));
 
 /* Other strfile functions */
-extern void _IO_str_init_static __P((_IO_FILE *, char*, int, char*));
-extern void _IO_str_init_readonly __P((_IO_FILE *, const char*, int));
-extern _IO_ssize_t _IO_str_count __P ((_IO_FILE*));
-
-extern _IO_size_t _IO_getline __P((_IO_FILE*,char*,_IO_size_t,int,int));
-extern _IO_ssize_t _IO_getdelim __P((char**, _IO_size_t*, int, _IO_FILE*));
-extern double _IO_strtod __P((const char *, char **));
-extern char * _IO_dtoa __P((double __d, int __mode, int __ndigits,
-				int *__decpt, int *__sign, char **__rve));
-extern int _IO_outfloat __P((double __value, _IO_FILE *__sb, int __type,
-				 int __width, int __precision, int __flags,
-				 int __sign_mode, int __fill));
+extern void _IO_str_init_static __P ((_IO_FILE *, char *, int, char *));
+extern void _IO_str_init_readonly __P ((_IO_FILE *, const char *, int));
+extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *));
+
+extern int _IO_vasprintf __P ((char **result_ptr, __const char *format,
+			       _IO_va_list args));
+extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg));
+extern int _IO_vsnprintf __P ((char *string, _IO_size_t maxlen,
+			       __const char *format, _IO_va_list args));
+
+
+extern _IO_size_t _IO_getline __P ((_IO_FILE *,char *, _IO_size_t, int, int));
+extern _IO_ssize_t _IO_getdelim __P ((char **, _IO_size_t *, int, _IO_FILE *));
+extern double _IO_strtod __P ((const char *, char **));
+extern char *_IO_dtoa __P ((double __d, int __mode, int __ndigits,
+			    int *__decpt, int *__sign, char **__rve));
+extern int _IO_outfloat __P ((double __value, _IO_FILE *__sb, int __type,
+			      int __width, int __precision, int __flags,
+			      int __sign_mode, int __fill));
 
 extern _IO_FILE *_IO_list_all;
 extern void (*_IO_cleanup_registration_needed) __P ((void));
 
 #ifndef EOF
-#define EOF (-1)
+# define EOF (-1)
 #endif
 #ifndef NULL
-#ifdef __GNUG__
-#define NULL (__null)
-#else
-#if !defined(__cplusplus)
-#define NULL ((void*)0)
-#else
-#define NULL (0)
-#endif
-#endif
-#endif
+# if defined __GNUG__ && \
+    (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
+#  define NULL (__null)
+# else
+#  if !defined(__cplusplus)
+#   define NULL ((void*)0)
+#  else
+#   define NULL (0)
+#  endif
+# endif
+#endif
+
+#if _G_HAVE_MMAP
+
+# include <unistd.h>
+# include <fcntl.h>
+# include <sys/mman.h>
+# include <sys/param.h>
+
+# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#  define MAP_ANONYMOUS MAP_ANON
+# endif
+
+# if !defined(MAP_ANONYMOUS) || !defined(EXEC_PAGESIZE)
+#  undef _G_HAVE_MMAP
+#  define _G_HAVE_MMAP 0
+# endif
+
+#endif /* _G_HAVE_MMAP */
+
+#if _G_HAVE_MMAP
+
+# ifdef _LIBC
+/* When using this code in the GNU libc we must not pollute the name space.  */
+#  define mmap __mmap
+#  define munmap __munmap
+# endif
+
+# define ROUND_TO_PAGE(_S) \
+       (((_S) + EXEC_PAGESIZE - 1) & ~(EXEC_PAGESIZE - 1))
+
+# define FREE_BUF(_B, _S) \
+       munmap ((_B), ROUND_TO_PAGE (_S))
+# define ALLOC_BUF(_B, _S, _R) \
+       do {								      \
+	  (_B) = (char *) mmap (0, ROUND_TO_PAGE (_S),			      \
+				PROT_READ | PROT_WRITE,			      \
+				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);	      \
+	  if ((_B) == (char *) -1)					      \
+	    return (_R);						      \
+       } while (0)
+
+#else /* _G_HAVE_MMAP */
+
+# define FREE_BUF(_B, _S) \
+       free(_B)
+# define ALLOC_BUF(_B, _S, _R) \
+       do {								      \
+	  (_B) = (char*)malloc(_S);					      \
+	  if ((_B) == NULL)						      \
+	    return (_R);						      \
+       } while (0)
 
-#define FREE_BUF(_B) free(_B)
-#define ALLOC_BUF(_S) (char*)malloc(_S)
+#endif /* _G_HAVE_MMAP */
 
 #ifndef OS_FSTAT
-#define OS_FSTAT fstat
+# define OS_FSTAT fstat
 #endif
 struct stat;
-extern _IO_ssize_t _IO_read __P((int, void*, _IO_size_t));
-extern _IO_ssize_t _IO_write __P((int, const void*, _IO_size_t));
-extern _IO_off_t _IO_lseek __P((int, _IO_off_t, int));
-extern int _IO_close __P((int));
-extern int _IO_fstat __P((int, struct stat *));
+extern _IO_ssize_t _IO_read __P ((int, void *, _IO_size_t));
+extern _IO_ssize_t _IO_write __P ((int, const void *, _IO_size_t));
+extern _IO_off_t _IO_lseek __P ((int, _IO_off_t, int));
+extern int _IO_close __P ((int));
+extern int _IO_fstat __P ((int, struct stat *));
+extern int _IO_vscanf __P ((const char *, _IO_va_list));
 
 /* Operations on _IO_fpos_t.
    Normally, these are trivial, but we provide hooks for configurations
@@ -414,84 +464,93 @@
 
 /* _IO_pos_BAD is an _IO_fpos_t value indicating error, unknown, or EOF. */
 #ifndef _IO_pos_BAD
-#define _IO_pos_BAD ((_IO_fpos_t)(-1))
+# define _IO_pos_BAD ((_IO_fpos_t) -1)
 #endif
 /* _IO_pos_as_off converts an _IO_fpos_t value to an _IO_off_t value. */
 #ifndef _IO_pos_as_off
-#define _IO_pos_as_off(__pos) ((_IO_off_t)(__pos))
+# define _IO_pos_as_off(__pos) ((_IO_off_t) (__pos))
 #endif
 /* _IO_pos_adjust adjust an _IO_fpos_t by some number of bytes. */
 #ifndef _IO_pos_adjust
-#define _IO_pos_adjust(__pos, __delta) ((__pos) += (__delta))
+# define _IO_pos_adjust(__pos, __delta) ((__pos) += (__delta))
 #endif
 /* _IO_pos_0 is an _IO_fpos_t value indicating beginning of file. */
 #ifndef _IO_pos_0
-#define _IO_pos_0 ((_IO_fpos_t)0)
+# define _IO_pos_0 ((_IO_fpos_t) 0)
 #endif
 
-#ifdef __cplusplus
-}
-#endif
+__END_DECLS
 
+#ifdef _IO_MTSAFE_IO
+/* check following! */
+# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
+       { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
+         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \
+	   0, 0, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock }
+#else
 /* check following! */
-#define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
+# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
        { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
-         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD}
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD }
+#endif
 
 /* VTABLE_LABEL defines NAME as of the CLASS class.
    CNLENGTH is strlen(#CLASS).  */
 #ifdef __GNUC__
-#if _G_VTABLE_LABEL_HAS_LENGTH
-#define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
+# if _G_VTABLE_LABEL_HAS_LENGTH
+#  define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
   extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CNLENGTH #CLASS);
-#else
-#define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
+# else
+#  define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
   extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CLASS);
-#endif
+# endif
 #endif /* __GNUC__ */
 
 #if !defined(builtinbuf_vtable) && defined(__cplusplus)
-#ifdef __GNUC__
+# ifdef __GNUC__
 VTABLE_LABEL(builtinbuf_vtable, builtinbuf, 10)
-#else
-#if _G_VTABLE_LABEL_HAS_LENGTH
-#define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##10builtinbuf
-#else
-#define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##builtinbuf
-#endif
-#endif
+# else
+#  if _G_VTABLE_LABEL_HAS_LENGTH
+#   define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##10builtinbuf
+#  else
+#   define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##builtinbuf
+#  endif
+# endif
 #endif /* !defined(builtinbuf_vtable) && defined(__cplusplus) */
 
 #if defined(__STDC__) || defined(__cplusplus)
-#define _IO_va_start(args, last) va_start(args, last)
+# define _IO_va_start(args, last) va_start(args, last)
 #else
-#define _IO_va_start(args, last) va_start(args)
+# define _IO_va_start(args, last) va_start(args)
 #endif
 
 extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf;
 
 #if 1
-#define COERCE_FILE(FILE) /* Nothing */
+# define COERCE_FILE(FILE) /* Nothing */
 #else
 /* This is part of the kludge for binary compatibility with old stdio. */
-#define COERCE_FILE(FILE) \
+# define COERCE_FILE(FILE) \
   (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \
     && (FILE) = *(FILE**)&((int*)fp)[1])
 #endif
 
 #ifdef EINVAL
-#define MAYBE_SET_EINVAL errno = EINVAL
+# if defined(__GLIBC__) && __GLIBC__ >= 2 
+#  define MAYBE_SET_EINVAL __set_errno (EINVAL)
+# else
+#  define MAYBE_SET_EINVAL errno = EINVAL
+# endif
 #else
-#define MAYBE_SET_EINVAL /* nothing */
+# define MAYBE_SET_EINVAL /* nothing */
 #endif
 
-#ifdef DEBUG
-#define CHECK_FILE(FILE,RET) \
+#ifdef IO_DEBUG
+# define CHECK_FILE(FILE, RET) \
 	if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \
 	else { COERCE_FILE(FILE); \
 	       if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \
-	  { errno = EINVAL; return RET; }}
+	  { MAYBE_SET_EINVAL; return RET; }}
 #else
-#define CHECK_FILE(FILE,RET) \
-	COERCE_FILE(FILE)
+# define CHECK_FILE(FILE, RET) COERCE_FILE (FILE)
 #endif
Index: libio/outfloat.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/outfloat.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 outfloat.c
--- libio/outfloat.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/outfloat.c	1997/08/26 01:42:20
@@ -24,6 +24,7 @@
 
 #include "libioP.h"
 
+#ifdef _IO_USE_DTOA
 /* Format floating-point number and print them.
    Return number of chars printed, or EOF on error.
 
@@ -202,3 +203,4 @@
  error:
   return EOF;
 }
+#endif
Index: libio/parsestream.cc
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/parsestream.cc,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 parsestream.cc
--- libio/parsestream.cc	1997/08/26 00:21:27	1.1.1.1
+++ libio/parsestream.cc	1997/08/26 01:42:20
@@ -137,7 +137,7 @@
     delete_buf = delete_arg_buf;
     sbuf = buf;
     int buf_size = 128;
-    char* buffer = ALLOC_BUF(buf_size);
+    char* buffer = malloc (buf_size);
     setb(buffer, buffer+buf_size, 1);
 //    setg(buffer, buffer, buffer);
 }
Index: libio/stdstrbufs.cc
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/stdstrbufs.cc,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 stdstrbufs.cc
--- libio/stdstrbufs.cc	1997/08/26 00:21:27	1.1.1.1
+++ libio/stdstrbufs.cc	1997/08/26 01:42:20
@@ -29,6 +29,7 @@
    point to builtinbuf's vtable, so the objects are effectively
    of class builtinbuf.) */
 
+#include "_G_config.h"
 #include "libioP.h"
 #include <stdio.h>
 
@@ -54,8 +55,15 @@
 #define STD_VTABLE (const struct _IO_jump_t *)filebuf_vtable
 #endif
 
+#ifdef _IO_MTSAFE_IO
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+  static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
+  struct _IO_FILE_plus NAME \
+    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps}
+#else
 #define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
   struct _IO_FILE_plus NAME = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), STD_VTABLE}
+#endif
 
 DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
 DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_.file, _IO_NO_READS);
Index: libio/streambuf.cc
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/streambuf.cc,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 streambuf.cc
--- libio/streambuf.cc	1997/08/26 00:21:27	1.1.1.1
+++ libio/streambuf.cc	1997/08/26 01:42:20
@@ -162,7 +162,7 @@
 
 static int _IO_sb_pbackfail(_IO_FILE *fp, int ch)
 { return ((streambuf*)fp)->pbackfail(ch); }
-static void _IO_sb_finish(_IO_FILE *fp)
+static void _IO_sb_finish(_IO_FILE *fp, int)
 { ((streambuf*)fp)->~streambuf(); }
 static _IO_ssize_t _IO_sb_read(_IO_FILE *fp, void *buf, _IO_ssize_t n)
 { return ((streambuf*)fp)->sys_read((char*)buf, n); }
@@ -207,13 +207,22 @@
 
 streambuf::streambuf(int flags)
 {
+#ifdef _IO_MTSAFE_IO
+  _lock = new _IO_lock_t;
+#endif
   _IO_init(this, flags);
 #if !_IO_UNIFIED_JUMPTABLES
   _jumps = &_IO_streambuf_jumps;
 #endif
 }
 
-streambuf::~streambuf() { _IO_default_finish(this); }
+streambuf::~streambuf()
+{
+  _IO_default_finish(this, 0);
+#ifdef _IO_MTSAFE_IO
+  delete _lock;
+#endif
+}
 
 streampos
 streambuf::seekoff(streamoff, _seek_dir, int /*=ios::in|ios::out*/)
Index: libio/streambuf.h
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/streambuf.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 streambuf.h
--- libio/streambuf.h	1997/08/26 00:21:27	1.1.1.1
+++ libio/streambuf.h	1997/08/26 01:42:20
@@ -36,7 +36,7 @@
 #include <libio.h>
 }
 //#include <_G_config.h>
-#ifdef _IO_NEED_STDARG_H
+#ifdef _G_NEED_STDARG_H
 #include <stdarg.h>
 #endif
 #ifndef _IO_va_list
Index: libio/strfile.h
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/strfile.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 strfile.h
--- libio/strfile.h	1997/08/26 00:21:27	1.1.1.1
+++ libio/strfile.h	1997/08/26 01:38:39
@@ -1,34 +1,35 @@
-/* 
-Copyright (C) 1993 Free Software Foundation
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
 
-This file is part of the GNU IO Library.  This library is free
-software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this library; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-As a special exception, if you link this library with files
-compiled with a GNU compiler to produce an executable, this does not cause
-the resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why
-the executable file might be covered by the GNU General Public License. */
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
 
 #include <libio.h>
 #ifdef TODO
 Merge into  libio.h ?
 #endif
 
-typedef void *(*_IO_alloc_type) __P((_IO_size_t));
-typedef void (*_IO_free_type) __P((void*));
+typedef void *(*_IO_alloc_type) __P ((_IO_size_t));
+typedef void (*_IO_free_type) __P ((void*));
 
 struct _IO_str_fields
 {
Index: libio/strops.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/strops.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 strops.c
--- libio/strops.c	1997/08/26 00:21:27	1.1.1.1
+++ libio/strops.c	1997/08/26 01:38:18
@@ -1,26 +1,27 @@
-/* 
-Copyright (C) 1993 Free Software Foundation
+/* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
 
-This file is part of the GNU IO Library.  This library is free
-software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this library; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-As a special exception, if you link this library with files
-compiled with a GNU compiler to produce an executable, this does not cause
-the resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why
-the executable file might be covered by the GNU General Public License. */
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
 
 #include "strfile.h"
 #include "libioP.h"
@@ -28,7 +29,7 @@
 
 #if 0
 /* The following definitions are for exposition only.
-   They map the terminlogy used in the ANSI/ISO C++ draft standard
+   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
@@ -59,16 +60,19 @@
 #endif
 
 void
-DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
-      _IO_FILE *fp AND char *ptr AND int size AND char *pstart)
+_IO_str_init_static (fp, ptr, size, pstart)
+     _IO_FILE *fp;
+     char *ptr;
+     int size;
+     char *pstart;
 {
   if (size == 0)
-    size = strlen(ptr);
+    size = strlen (ptr);
   else if (size < 0)
     {
       /* If size is negative 'the characters are assumed to
 	 continue indefinitely.'  This is kind of messy ... */
-      _G_int32_t s;
+      int s;
       size = 512;
       /* Try increasing powers of 2, as long as we don't wrap around. */
       for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
@@ -80,7 +84,7 @@
 	    size += s;
 	}
     }
-  _IO_setb(fp, ptr, ptr+size, 0);
+  _IO_setb (fp, ptr, ptr + size, 0);
 
   fp->_IO_write_base = ptr;
   fp->_IO_read_base = ptr;
@@ -88,7 +92,7 @@
   if (pstart)
     {
       fp->_IO_write_ptr = pstart;
-      fp->_IO_write_end = ptr+size;
+      fp->_IO_write_end = ptr + size;
       fp->_IO_read_end = pstart;
     }
   else
@@ -98,20 +102,23 @@
       fp->_IO_read_end = ptr+size;
     }
   /* 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;
 }
 
 void
-DEFUN(_IO_str_init_readonly, (fp, ptr, size),
-      _IO_FILE *fp AND const char *ptr AND int size)
+_IO_str_init_readonly (fp, ptr, size)
+     _IO_FILE *fp;
+     const char *ptr;
+     int size;
 {
-  _IO_str_init_static (fp, (char*)ptr, size, NULL);
+  _IO_str_init_static (fp, (char *) ptr, size, NULL);
   fp->_IO_file_flags |= _IO_NO_WRITES;
 }
 
 int
-DEFUN(_IO_str_overflow, (fp, c),
-      register _IO_FILE* fp AND int c)
+_IO_str_overflow (fp, c)
+     _IO_FILE *fp;
+     int c;
 {
   int flush_only = c == EOF;
   _IO_size_t pos;
@@ -124,7 +131,7 @@
       fp->_IO_read_ptr = fp->_IO_read_end;
     }
   pos =  fp->_IO_write_ptr - fp->_IO_write_base;
-  if (pos >= _IO_blen(fp) + flush_only)
+  if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
     {
       if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
 	return EOF;
@@ -132,9 +139,9 @@
 	{
 	  char *new_buf;
 	  char *old_buf = fp->_IO_buf_base;
-	  _IO_size_t new_size = 2 * _IO_blen(fp) + 100;
+	  _IO_size_t new_size = 2 * _IO_blen (fp) + 100;
 	  new_buf
-	    = (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
+	    = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
 	  if (new_buf == NULL)
 	    {
 	      /*	  __ferror(fp) = 1; */
@@ -142,16 +149,16 @@
 	    }
 	  if (fp->_IO_buf_base)
 	    {
-	      memcpy(new_buf, old_buf, _IO_blen(fp));
-	      (*((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
+	      memcpy (new_buf, old_buf, _IO_blen (fp));
+	      (*((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
 	      /* 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);
+	      memset (new_buf + pos, 0, blen() - pos);
 #endif
-	  _IO_setb(fp, new_buf, new_buf + new_size, 1);
+	  _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);
 	  fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
@@ -170,8 +177,8 @@
 }
 
 int
-DEFUN(_IO_str_underflow, (fp),
-      register _IO_FILE* fp)
+_IO_str_underflow (fp)
+     _IO_FILE *fp;
 {
   if (fp->_IO_write_ptr > fp->_IO_read_end)
     fp->_IO_read_end = fp->_IO_write_ptr;
@@ -190,19 +197,22 @@
 /* The size of the valid part of the buffer.  */
 
 _IO_ssize_t
-DEFUN(_IO_str_count, (fp),
-      register _IO_FILE *fp)
+_IO_str_count (fp)
+     _IO_FILE *fp;
 {
-  return (fp->_IO_write_ptr > fp->_IO_read_end ? fp->_IO_write_ptr
-	  : fp->_IO_read_end)
-    - fp->_IO_read_base;
-}     
+  return ((fp->_IO_write_end > fp->_IO_read_end
+	   ? fp->_IO_write_end : fp->_IO_read_end)
+	  - fp->_IO_read_base);
+}
 
 _IO_pos_t
-DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
-      register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
+_IO_str_seekoff (fp, offset, dir, mode)
+     _IO_FILE *fp;
+     _IO_off_t offset;
+     int dir;
+     int mode;
 {
-  _IO_ssize_t cur_size = _IO_str_count(fp);
+  _IO_ssize_t cur_size = _IO_str_count (fp);
   _IO_pos_t new_pos = EOF;
 
   /* Move the get pointer, if requested. */
@@ -219,7 +229,7 @@
 	default: /* case _IO_seek_set: */
 	  break;
 	}
-      if (offset < 0 || (_IO_size_t)offset > cur_size)
+      if (offset < 0 || (_IO_ssize_t) offset > cur_size)
 	return EOF;
       fp->_IO_read_ptr = fp->_IO_read_base + offset;
       fp->_IO_read_end = fp->_IO_read_base + cur_size;
@@ -240,7 +250,7 @@
 	default: /* case _IO_seek_set: */
 	  break;
 	}
-      if (offset < 0 || (_IO_size_t)offset > cur_size)
+      if (offset < 0 || (_IO_ssize_t) offset > cur_size)
 	return EOF;
       fp->_IO_write_ptr = fp->_IO_write_base + offset;
       new_pos = offset;
@@ -249,26 +259,29 @@
 }
 
 int
-DEFUN(_IO_str_pbackfail, (fp, c),
-      register _IO_FILE *fp AND int c)
+_IO_str_pbackfail (fp, c)
+     _IO_FILE *fp;
+     int c;
 {
   if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
     return EOF;
-  return _IO_default_pbackfail(fp, c);
+  return _IO_default_pbackfail (fp, c);
 }
 
 void
-DEFUN (_IO_str_finish, (fp),
-      register _IO_FILE* fp)
+_IO_str_finish (fp, dummy)
+     _IO_FILE *fp;
+     int dummy;
 {
   if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
-    (((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
+    (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
   fp->_IO_buf_base = NULL;
 
-  _IO_default_finish(fp);
+  _IO_default_finish (fp, 0);
 }
 
-struct _IO_jump_t _IO_str_jumps = {
+struct _IO_jump_t _IO_str_jumps =
+{
   JUMP_INIT_DUMMY,
   JUMP_INIT(finish, _IO_str_finish),
   JUMP_INIT(overflow, _IO_str_overflow),
Index: libio/config/linux.mt
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/config/linux.mt,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 linux.mt
--- libio/config/linux.mt	1997/08/26 00:21:27	1.1.1.1
+++ libio/config/linux.mt	1997/08/26 01:42:20
@@ -1,26 +1,30 @@
 # Since the Linux C library has libio, we have to be very careful.
 
+# That is where we keep the g++ header files.
+gxx_includedir =$(prefix)/include/g++
+
 # By default, we build libio and use it.  If someone wants to not
 # build it, let them go to extra work.  The reason is that the user
 # may want a newer, bug fixed libio, also on a linux 1.0.8 system
 # things just won't build with the bottom section uncommented.
 
 # Comment this out to avoid including the stdio functions in libiostream.a:
-LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS)
-LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS) stdio.list
-LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS) `cat stdio.list`
+# LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS)
+# LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS) stdio.list
+# LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS) `cat stdio.list`
 
 # Comment the above and uncomment the below to use the code in the Linux libc:
 # We have _G_config.h in /usr/include.
-# _G_CONFIG_H=
+_G_CONFIG_H=
 
 # We have those in libc.a.
-# IO_OBJECTS=
-# STDIO_WRAP_OBJECTS=
-# OSPRIM_OBJECTS=
+IO_OBJECTS=
+STDIO_OBJECTS=
+STDIO_WRAP_OBJECTS=
+OSPRIM_OBJECTS=
 
 # We have the rest in /usr/include.
-# USER_INCLUDES=PlotFile.h SFile.h builtinbuf.h editbuf.h fstream.h \
-# 	indstream.h iomanip.h iostream.h istream.h ostream.h \
-# 	parsestream.h pfstream.h procbuf.h stdiostream.h stream.h \
-# 	streambuf.h strfile.h strstream.h
+USER_INCLUDES=PlotFile.h SFile.h builtinbuf.h editbuf.h fstream.h \
+	indstream.h iomanip.h iostream.h istream.h ostream.h \
+	parsestream.h pfstream.h procbuf.h stdiostream.h stream.h \
+	streambuf.h strfile.h strstream.h
Index: libio/dbz/Makefile.in
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/dbz/Makefile.in,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Makefile.in
--- libio/dbz/Makefile.in	1997/08/26 00:21:27	1.1.1.1
+++ libio/dbz/Makefile.in	1997/08/26 01:42:20
@@ -37,7 +37,8 @@
 install-info:
 info:
 
-check: r rclean
+check: r
+	$(MAKE) rclean
 
 bininstall:	dbz
 	cp dbz $(NEWSBIN)
Index: libio/tests/tFile.cc
===================================================================
RCS file: /home/work/cvs/gnu/egcs/libio/tests/tFile.cc,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 tFile.cc
--- libio/tests/tFile.cc	1997/08/26 00:21:28	1.1.1.1
+++ libio/tests/tFile.cc	1997/08/26 01:42:20
@@ -43,6 +43,8 @@
 #include <string.h>
 #include <assert.h>
 
+const char *tempfile;
+
 class record
 {
 public:
@@ -160,9 +162,9 @@
 
   cout << "\nMaking File tf ... "; 
 #ifdef _OLD_STREAMS
-  File tf("tempfile", io_readwrite, a_create);
+  File tf(tempfile, io_readwrite, a_create);
 #else
-  fstream tf("tempfile", ios::in|ios::out|ios::trunc);
+  fstream tf(tempfile, ios::in|ios::out|ios::trunc);
 #endif
   assert(tf.good());
   assert(tf.is_open());
@@ -190,7 +192,7 @@
   tf.open(tf.name(), io_appendonly, a_use);
 #else
   tf.close();
-  tf.open("tempfile", ios::app);
+  tf.open(tempfile, ios::app);
 #endif
   assert(tf.good());
   assert(tf.is_open());
@@ -204,7 +206,7 @@
   tf << s;
   assert(tf.good());
   tf.close();
-  tf.open("tempfile", ios::in);
+  tf.open(tempfile, ios::in);
 #endif
   tf.raw();
   assert(tf.good());
@@ -223,7 +225,7 @@
   tf.remove();
 #else
   tf.close();
-  unlink("tempfile");
+  unlink(tempfile);
 #endif
   assert(!tf.is_open());
 }
@@ -512,6 +514,8 @@
 
 main(int argc, char **argv)
 {
+ char temp [1024] = "tempfile";
+
  if (argc > 1 && strncmp(argv[1], "-b", 2) == 0) {
      streambuf *sb = cout.rdbuf();
      streambuf *ret;
@@ -522,7 +526,11 @@
 	 ret = sb->setbuf(new char[buffer_size], buffer_size);
      if (ret != sb)
 	 cerr << "Warning: cout.rdbuf()->setbuf failed!\n";
+     
+      strncpy (&temp [8], &argv[1][2], 1000);
+      temp [1008] = '\0';
   }
+  tempfile = temp;
   t1();
   t2();
   t3();
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ libio/iovasprintf.c	Mon Aug 25 18:12:32 1997
@@ -0,0 +1,76 @@
+/* Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include <malloc.h>
+#include "libioP.h"
+#include "stdio.h"
+#include "strfile.h"
+
+int
+_IO_vasprintf (result_ptr, format, args)
+     char **result_ptr;
+     const char *format;
+     _IO_va_list args;
+{
+  /* Initial size of the buffer to be used.  Will be doubled each time an
+     overflow occurs.  */
+  const _IO_size_t init_string_size = 100;
+  char *string;
+  _IO_strfile sf;
+#ifdef _IO_MTSAFE_IO
+  _IO_lock_t lock;
+#endif
+  int ret;
+  string = (char *) malloc (init_string_size);
+  if (string == NULL)
+    return -1;
+#ifdef _IO_MTSAFE_IO
+  sf._sbf._f._lock = &lock;
+#endif
+  _IO_init ((_IO_FILE *) &sf, 0);
+  _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_str_jumps;
+  _IO_str_init_static ((_IO_FILE *) &sf, string, init_string_size, string);
+  sf._sbf._f._flags &= ~_IO_USER_BUF;
+  sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+  sf._s._free_buffer = (_IO_free_type) free;
+  ret = _IO_vfprintf ((_IO_FILE *) &sf, format, args);
+  if (ret < 0)
+    return ret;
+  *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base,
+				  (sf._sbf._f._IO_write_ptr
+				   - sf._sbf._f._IO_write_base) +1);
+  if (*result_ptr == NULL)
+    *result_ptr = sf._sbf._f._IO_buf_base;
+  (*result_ptr)[sf._sbf._f._IO_write_ptr-sf._sbf._f._IO_write_base] = '\0';
+  return ret;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vasprintf, vasprintf)
+#else
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak vasprintf = _IO_vasprintf
+#endif
+#endif
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ libio/iovsnprintf.c	Mon Aug 25 18:15:43 1997
@@ -0,0 +1,140 @@
+/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libioP.h"
+#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.  */
+  char overflow_buf[64];
+} _IO_strnfile;
+
+
+static int _IO_strn_overflow __P ((_IO_FILE *fp, int c));
+
+static int
+_IO_strn_overflow (fp, c)
+     _IO_FILE *fp;
+     int c;
+{
+  /* When we come to here this means the user supplied buffer is
+     filled.  But since we must return the number of characters which
+     would have been written in total we must provide a buffer for
+     further use.  We can do this by writing on and on in the overflow
+     buffer in the _IO_strnfile structure.  */
+  _IO_strnfile *snf = (_IO_strnfile *) fp;
+
+  if (fp->_IO_buf_base != snf->overflow_buf)
+    {
+      /* Terminate the string.  We know that there is room for at
+	 least one more character since we initialized the stream with
+	 a size to make this possible.  */
+      *fp->_IO_write_ptr = '\0';
+
+      _IO_setb (fp, snf->overflow_buf,
+		snf->overflow_buf + sizeof (snf->overflow_buf), 0);
+
+      fp->_IO_write_base = snf->overflow_buf;
+      fp->_IO_read_base = snf->overflow_buf;
+      fp->_IO_read_ptr = snf->overflow_buf;
+      fp->_IO_read_end = snf->overflow_buf + sizeof (snf->overflow_buf);
+    }
+
+  fp->_IO_write_ptr = snf->overflow_buf;
+  fp->_IO_write_end = snf->overflow_buf;
+
+  /* Since we are not really interested in storing the characters
+     which do not fit in the buffer we simply ignore it.  */
+  return c;
+}
+
+
+static struct _IO_jump_t _IO_strn_jumps =
+{
+  JUMP_INIT_DUMMY,
+  JUMP_INIT(finish, _IO_str_finish),
+  JUMP_INIT(overflow, _IO_strn_overflow),
+  JUMP_INIT(underflow, _IO_str_underflow),
+  JUMP_INIT(uflow, _IO_default_uflow),
+  JUMP_INIT(pbackfail, _IO_str_pbackfail),
+  JUMP_INIT(xsputn, _IO_default_xsputn),
+  JUMP_INIT(xsgetn, _IO_default_xsgetn),
+  JUMP_INIT(seekoff, _IO_str_seekoff),
+  JUMP_INIT(seekpos, _IO_default_seekpos),
+  JUMP_INIT(setbuf, _IO_default_setbuf),
+  JUMP_INIT(sync, _IO_default_sync),
+  JUMP_INIT(doallocate, _IO_default_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)
+};
+
+
+int
+_IO_vsnprintf (string, maxlen, format, args)
+     char *string;
+     _IO_size_t maxlen;
+     const char *format;
+     _IO_va_list args;
+{
+  _IO_strnfile sf;
+  int ret;
+#ifdef _IO_MTSAFE_IO
+  _IO_lock_t lock;
+  sf.f._sbf._f._lock = &lock;
+#endif
+
+  /* We need to handle the special case where MAXLEN is 0.  Use the
+     overflow buffer right from the start.  */
+  if (maxlen == 0)
+    {
+      string = sf.overflow_buf;
+      maxlen = sizeof (sf.overflow_buf);
+    }
+
+  _IO_init ((_IO_FILE *) &sf, 0);
+  _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_strn_jumps;
+  _IO_str_init_static ((_IO_FILE *) &sf, string, maxlen - 1, string);
+  ret = _IO_vfprintf ((_IO_FILE *) &sf, format, args);
+
+  if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
+    *sf.f._sbf._f._IO_write_ptr = '\0';
+  return ret;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vsnprintf, __vsnprintf)
+weak_alias (_IO_vsnprintf, vsnprintf)
+#if defined(__ELF__) && defined(_IO_USE_LIBC)
+#pragma weak vsnprintf = _IO_vsnprintf
+#pragma weak __vsnprintf = _IO_vsnprintf
+#endif
+#endif

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: A libio patch
@ 1997-08-28 14:34 H.J. Lu
  0 siblings, 0 replies; 3+ messages in thread
From: H.J. Lu @ 1997-08-28 14:34 UTC (permalink / raw)
  To: egcs

> 
> I've skimmed the patch.  (I *really* hate jumbo patches!)

Sorry. I am trying to keep it small. But they depend on each other.

> 
> Three comments:  I don't understand the point of the must_be_exact
> hack in _IO_file_seekoff.  The comment suggests it is needed for fflush,
> which according to Posix should be caseful to not make the external
> and internal file positions differ.  And fflush is implemented using
> _IO_file_sync, which calls _IO_SYSSEEK when the read position is
> not in sync.  This this is only called when
> fp->_IO_read_ptr != fp->_IO_read_end.
> 
> On the other hand, must_be_true is true if fp->_IO_read_base ==
> fp->_IO_read_end - which implies fp->_IO_read_ptr == fp->_IO_read_end,
> which implies that _IO_file_sync would not call _IO_SYSSEEK in this case.
> 
> Another issue:  In _IO_file_read and _IO_file_write the patch comments out
> code that checks for EINTR, because Posix recommends against it.
> Fine - just remove that code then, which would simplify it.
> I wrote the code to check for EINTR because I got the impression that
> was what you were supposed to do - it was not an optimization.
> If there is no need to check for EINTR, just remove the code that does.

I will leave those to Ulrich. I just copied them from libio in
glibc 2.1.

> 
> I see various places where it checks for __linux__.  This looks
> suspicious.  Wouldn't it be the same for any other OS that uses glibc
> native, such as the Hurd?

There are 2 stdio in glibc. Using glibc doesn't really mean much unless
I can tell libio is used. Ulrich, is there a way to tell that in
iostream.h? As for __linux__ is libio.h, that is a special compatibility
kludge for the Linux libc 5.


-- 
H.J. Lu (hjl@gnu.ai.mit.edu)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: A libio patch
@ 1997-08-28  6:35 Per Bothner
  0 siblings, 0 replies; 3+ messages in thread
From: Per Bothner @ 1997-08-28  6:35 UTC (permalink / raw)
  To: egcs

I've skimmed the patch.  (I *really* hate jumbo patches!)

Three comments:  I don't understand the point of the must_be_exact
hack in _IO_file_seekoff.  The comment suggests it is needed for fflush,
which according to Posix should be caseful to not make the external
and internal file positions differ.  And fflush is implemented using
_IO_file_sync, which calls _IO_SYSSEEK when the read position is
not in sync.  This this is only called when
fp->_IO_read_ptr != fp->_IO_read_end.

On the other hand, must_be_true is true if fp->_IO_read_base ==
fp->_IO_read_end - which implies fp->_IO_read_ptr == fp->_IO_read_end,
which implies that _IO_file_sync would not call _IO_SYSSEEK in this case.

Another issue:  In _IO_file_read and _IO_file_write the patch comments out
code that checks for EINTR, because Posix recommends against it.
Fine - just remove that code then, which would simplify it.
I wrote the code to check for EINTR because I got the impression that
was what you were supposed to do - it was not an optimization.
If there is no need to check for EINTR, just remove the code that does.

I see various places where it checks for __linux__.  This looks
suspicious.  Wouldn't it be the same for any other OS that uses glibc
native, such as the Hurd?

	--Per Bothner
Cygnus Solutions     bothner@cygnus.com     http://www.cygnus.com/~bothner

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1997-08-28 14:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-08-27 16:44 A libio patch H.J. Lu
1997-08-28  6:35 Per Bothner
1997-08-28 14:34 H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).