summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-11-20 03:48:11 +0000
committerRoland McGrath <roland@gnu.org>1995-11-20 03:48:11 +0000
commit96aa2d94a2355cdc55c96e808d14a0e7f2ebe77d (patch)
treef7c87e6742af0707b858a1387ca85b679aa8d13e
parenta5a81fecc7194d050066265a15b1ba8bc3abc627 (diff)
downloadglibc-96aa2d94a2355cdc55c96e808d14a0e7f2ebe77d.tar.gz
glibc-96aa2d94a2355cdc55c96e808d14a0e7f2ebe77d.tar.xz
glibc-96aa2d94a2355cdc55c96e808d14a0e7f2ebe77d.zip
Sat Nov 18 16:46:01 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
	* libio/Makefile, libio/cleanup.c, libio/clearerr.c, libio/feof.c,
	libio/ferror.c, libio/fgetc.c, libio/filedoalloc.c, libio/fileno.c,
	libio/fileops.c, libio/fputc.c, libio/freopen.c, libio/fseek.c,
	libio/genops.c, libio/getc.c, libio/getchar.c, libio/iofclose.c,
	libio/iofdopen.c, libio/iofflush.c, libio/iofgetpos.c, libio/iofgets.c,
	libio/iofopen.c, libio/iofprintf.c, libio/iofputs.c, libio/iofread.c,
	libio/iofscanf.c, libio/iofsetpos.c, libio/ioftell.c, libio/iofwrite.c,
	libio/iogetdelim.c, libio/iogetline.c, libio/iogets.c, libio/iolibio.h,
	libio/iopadn.c, libio/ioprims.c, libio/ioputs.c, libio/ioseekoff.c,
	libio/ioseekpos.c, libio/iosetbuffer.c, libio/iosetvbuf.c,
	libio/iosprintf.c, libio/ioungetc.c, libio/iovsprintf.c,
	libio/iovsscanf.c, libio/libio.h, libio/libioP.h, libio/putc.c,
	libio/putchar.c, libio/rewind.c, libio/setbuf.c, libio/setlinebuf.c,
	libio/stdfiles.c, libio/stdio.c, libio/stdio.h, libio/strfile.h,
	libio/strops.c, libio/vasprintf.c, libio/vscanf.c, libio/vsnprintf.c:
	New files.  Slightly modified version from Linux libc.

	* libio/memstream.c, libio/vdprintf.c: New files for functions not
	(yet) part of GNU libio.

	* libio/iofopncook.c: Implementation of `fopencookie', mainly written
	by Per Bothner.

	* stdio-common/getline.c: Adapted to libio.
	* stdio-common/snprintf.c: Adapted to libio.
	* stdio-common/vfprintf.c: Adapted to libio.
	* stdio-common/vfscanf.c: Adapted to libio.
	* sysdeps/posix/tempname.c: Adapted to libio.
-rw-r--r--ChangeLog31
-rw-r--r--Makeconfig5
-rw-r--r--configure.in17
-rw-r--r--hurd/hurdfault.c3
-rw-r--r--libio/Makefile44
-rw-r--r--libio/cleanup.c15
-rw-r--r--libio/clearerr.c10
-rw-r--r--libio/feof.c34
-rw-r--r--libio/ferror.c34
-rw-r--r--libio/fgetc.c34
-rw-r--r--libio/filedoalloc.c103
-rw-r--r--libio/fileno.c38
-rw-r--r--libio/fileops.c738
-rw-r--r--libio/fputc.c35
-rw-r--r--libio/freopen.c38
-rw-r--r--libio/fseek.c36
-rw-r--r--libio/genops.c837
-rw-r--r--libio/getc.c35
-rw-r--r--libio/getchar.c34
-rw-r--r--libio/iofclose.c51
-rw-r--r--libio/iofdopen.c124
-rw-r--r--libio/iofflush.c40
-rw-r--r--libio/iofgetpos.c49
-rw-r--r--libio/iofgets.c44
-rw-r--r--libio/iofopen.c52
-rw-r--r--libio/iofopncook.c163
-rw-r--r--libio/iofprintf.c48
-rw-r--r--libio/iofputs.c40
-rw-r--r--libio/iofread.c42
-rw-r--r--libio/iofscanf.c50
-rw-r--r--libio/iofsetpos.c46
-rw-r--r--libio/ioftell.c47
-rw-r--r--libio/iofwrite.c48
-rw-r--r--libio/iogetdelim.c105
-rw-r--r--libio/iogetline.c74
-rw-r--r--libio/iogets.c49
-rw-r--r--libio/iolibio.h53
-rw-r--r--libio/iopadn.c65
-rw-r--r--libio/ioprims.c73
-rw-r--r--libio/ioputs.c38
-rw-r--r--libio/ioseekoff.c43
-rw-r--r--libio/ioseekpos.c39
-rw-r--r--libio/iosetbuffer.c38
-rw-r--r--libio/iosetvbuf.c80
-rw-r--r--libio/iosprintf.c47
-rw-r--r--libio/ioungetc.c38
-rw-r--r--libio/iovsprintf.c44
-rw-r--r--libio/iovsscanf.c38
-rw-r--r--libio/libio.h272
-rw-r--r--libio/libioP.h397
-rw-r--r--libio/memstream.c129
-rw-r--r--libio/putc.c30
-rw-r--r--libio/putchar.c29
-rw-r--r--libio/rewind.c33
-rw-r--r--libio/setbuf.c33
-rw-r--r--libio/setlinebuf.c35
-rw-r--r--libio/stdfiles.c44
-rw-r--r--libio/stdio.c12
-rw-r--r--libio/stdio.h196
-rw-r--r--libio/strfile.h46
-rw-r--r--libio/strops.c285
-rw-r--r--libio/vasprintf.c61
-rw-r--r--libio/vdprintf.c60
-rw-r--r--libio/vscanf.c37
-rw-r--r--libio/vsnprintf.c44
-rw-r--r--stdio-common/getline.c5
-rw-r--r--stdio-common/printf_fp.c14
-rw-r--r--stdio-common/snprintf.c1
-rw-r--r--stdio-common/vfprintf.c51
-rw-r--r--stdio-common/vfscanf.c224
-rw-r--r--stdlib/strtod.c16
-rw-r--r--stdlib/strtol.c8
-rw-r--r--sysdeps/posix/tempname.c41
-rw-r--r--sysdeps/unix/sysv/linux/configure3
74 files changed, 5783 insertions, 112 deletions
diff --git a/ChangeLog b/ChangeLog
index 207253f998..dd731fce4b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+Sat Nov 18 16:46:01 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>
+
+	* libio/Makefile, libio/cleanup.c, libio/clearerr.c, libio/feof.c,
+	libio/ferror.c, libio/fgetc.c, libio/filedoalloc.c, libio/fileno.c,
+	libio/fileops.c, libio/fputc.c, libio/freopen.c, libio/fseek.c,
+	libio/genops.c, libio/getc.c, libio/getchar.c, libio/iofclose.c,
+	libio/iofdopen.c, libio/iofflush.c, libio/iofgetpos.c, libio/iofgets.c,
+	libio/iofopen.c, libio/iofprintf.c, libio/iofputs.c, libio/iofread.c,
+	libio/iofscanf.c, libio/iofsetpos.c, libio/ioftell.c, libio/iofwrite.c,
+	libio/iogetdelim.c, libio/iogetline.c, libio/iogets.c, libio/iolibio.h,
+	libio/iopadn.c, libio/ioprims.c, libio/ioputs.c, libio/ioseekoff.c,
+	libio/ioseekpos.c, libio/iosetbuffer.c, libio/iosetvbuf.c,
+	libio/iosprintf.c, libio/ioungetc.c, libio/iovsprintf.c,
+	libio/iovsscanf.c, libio/libio.h, libio/libioP.h, libio/putc.c,
+	libio/putchar.c, libio/rewind.c, libio/setbuf.c, libio/setlinebuf.c,
+	libio/stdfiles.c, libio/stdio.c, libio/stdio.h, libio/strfile.h,
+	libio/strops.c, libio/vasprintf.c, libio/vscanf.c, libio/vsnprintf.c:
+	New files.  Slightly modified version from Linux libc.
+
+	* libio/memstream.c, libio/vdprintf.c: New files for functions not
+	(yet) part of GNU libio.
+
+	* libio/iofopncook.c: Implementation of `fopencookie', mainly written
+	by Per Bothner.
+
+	* stdio-common/getline.c: Adapted to libio.
+	* stdio-common/snprintf.c: Adapted to libio.
+	* stdio-common/vfprintf.c: Adapted to libio.
+	* stdio-common/vfscanf.c: Adapted to libio.
+	* sysdeps/posix/tempname.c: Adapted to libio.
+
 Fri Nov 17 17:57:00 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
 	* sysdeps/generic/Makefile (make_siglist): Add missing backslash.
diff --git a/Makeconfig b/Makeconfig
index a610d057f5..6b403a1694 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -411,9 +411,12 @@ endif	# gcc
 # files (including ones given in angle brackets) in the current directory
 # and in the parent library source directory.
 # `+sysdep-includes' will be defined by Makerules.
-+includes = -I. $(filter-out -I,-I$(patsubst %/,%,$(..))) \
++includes = -I. $(filter-out -I,-I$(patsubst %/,%,$(..))) $($(stdio)-include) \
 	    $(includes) $(+sysdep-includes) $(last-includes)
 
+# Since libio has several internal header files, we use a -I instead
+# of many little headers in the top level source directory.
+libio-include = -I$(..)libio
 
 # These are the variables that the implicit compilation rules use.
 CPPFLAGS = $(+includes) $(defines) -include $(..)libc-symbols.h \
diff --git a/configure.in b/configure.in
index 6b2624e254..e35769afb2 100644
--- a/configure.in
+++ b/configure.in
@@ -55,7 +55,7 @@ AC_ARG_WITH(weak-symbols, dnl
 
 AC_ARG_ENABLE(libio, dnl
 [  --enable-libio          build in GNU libio instead of GNU stdio],
- 	      stdio=libio, stdio=stdio)
+ 	      stdio=libio, stdio=default)
 
 dnl Arguments to enable or disable building the shared, profiled, and
 dnl -fomit-frame-pointer libraries.
@@ -69,13 +69,6 @@ AC_ARG_ENABLE(omitfp, dnl
 [  --enable-omitfp       build undebuggable optimized library [default=no]],
 	    omitfp=$enableval, omitfp=no)
 
-AC_MSG_CHECKING(stdio selection)
-AC_SUBST(stdio)
-if test $stdio = libio; then
-  AC_DEFINE(USE_IN_LIBIO)
-fi
-AC_MSG_RESULT($stdio)
-
 AC_CANONICAL_HOST
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
@@ -486,6 +479,14 @@ else
   config_uname=
 fi
 
+AC_MSG_CHECKING(stdio selection)
+AC_SUBST(stdio)
+case $stdio in
+libio) AC_DEFINE(USE_IN_LIBIO) ;;
+default) stdio=stdio ;;
+esac
+AC_MSG_RESULT($stdio)
+
 AC_SUBST(gnu_ld) AC_SUBST(gnu_as) AC_SUBST(elf) AC_SUBST(weak)
 if test $gnu_ld = yes; then
   AC_DEFINE(HAVE_GNU_LD)
diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c
index e1f8c19acc..5aedc582ce 100644
--- a/hurd/hurdfault.c
+++ b/hurd/hurdfault.c
@@ -26,6 +26,7 @@ Cambridge, MA 02139, USA.  */
 #include <stdio.h>
 #include "thread_state.h"
 #include "faultexc.h"		/* mig-generated header for our exc server.  */
+#include <assert.h>
 
 jmp_buf _hurdsig_fault_env;
 
@@ -121,7 +122,7 @@ _hurdsig_fault_init (void)
 			      MACH_PORT_RIGHT_RECEIVE, &forward_sigexc);
   assert_perror (err);
 
-  err = __mach_port_insert_right (__mach_task_self (),
+  err = __mach_port_insert_right (__mach_task_self (), sigexc,
 				  sigexc, MACH_MSG_TYPE_MAKE_SEND);
   assert_perror (err);
   err = __thread_set_special_port (_hurd_msgport_thread,
diff --git a/libio/Makefile b/libio/Makefile
new file mode 100644
index 0000000000..8d09a5ecce
--- /dev/null
+++ b/libio/Makefile
@@ -0,0 +1,44 @@
+# Copyright (C) 1995 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB.  If
+# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+# Cambridge, MA 02139, USA.
+
+#
+#	Specific makefile for libio.
+#
+subdir	:= libio
+
+headers	:= stdio.h libio.h
+
+routines	:=							      \
+	filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
+	iofopncook iofprintf iofputs iofread iofscanf iofsetpos ioftell	      \
+	iofwrite iogetdelim iogetline iogets iopadn ioprims ioputs	      \
+	ioseekoff ioseekpos iosetbuffer iosetvbuf iosprintf ioungetc	      \
+	iovsprintf iovsscanf						      \
+									      \
+	clearerr feof ferror fgetc fileno fputc freopen fseek getc getchar    \
+	memstream putc putchar rewind setbuf setlinebuf vasprintf vdprintf    \
+	vscanf vsnprintf						      \
+									      \
+	libc_fatal
+
+aux	:=								      \
+	cleanup fileops genops stdfiles stdio strops
+
+distribute := iolibio.h libioP.h strfile.h
+
+include ../Rules
diff --git a/libio/cleanup.c b/libio/cleanup.c
new file mode 100644
index 0000000000..b4c8be927f
--- /dev/null
+++ b/libio/cleanup.c
@@ -0,0 +1,15 @@
+#include "libioP.h"
+#if _G_HAVE_ATEXIT
+#include <stdlib.h>
+
+typedef void (*voidfunc) __P((void));
+
+static void
+DEFUN_VOID(_IO_register_cleanup)
+{
+  atexit ((voidfunc)_IO_cleanup);
+  _IO_cleanup_registration_needed = 0;
+}
+
+void (*_IO_cleanup_registration_needed)() = _IO_register_cleanup;
+#endif /* _G_HAVE_ATEXIT */
diff --git a/libio/clearerr.c b/libio/clearerr.c
new file mode 100644
index 0000000000..ee9780bdaf
--- /dev/null
+++ b/libio/clearerr.c
@@ -0,0 +1,10 @@
+#include "libioP.h"
+#include "stdio.h"
+
+void
+clearerr(fp)
+     FILE* fp;
+{
+  CHECK_FILE(fp, /*nothing*/);
+  _IO_clearerr(fp);
+}
diff --git a/libio/feof.c b/libio/feof.c
new file mode 100644
index 0000000000..bd30c175f3
--- /dev/null
+++ b/libio/feof.c
@@ -0,0 +1,34 @@
+/* 
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+feof(fp)
+     _IO_FILE* fp;
+{
+  CHECK_FILE(fp, EOF);
+  return _IO_feof(fp);
+}
diff --git a/libio/ferror.c b/libio/ferror.c
new file mode 100644
index 0000000000..d0159818e8
--- /dev/null
+++ b/libio/ferror.c
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+ferror (fp)
+     _IO_FILE* fp;
+{
+  CHECK_FILE (fp, EOF);
+  return _IO_ferror (fp);
+}
diff --git a/libio/fgetc.c b/libio/fgetc.c
new file mode 100644
index 0000000000..19c0a589d9
--- /dev/null
+++ b/libio/fgetc.c
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fgetc (fp)
+     FILE *fp;
+{
+  CHECK_FILE (fp, EOF);
+  return _IO_getc (fp);
+}
diff --git a/libio/filedoalloc.c b/libio/filedoalloc.c
new file mode 100644
index 0000000000..8ab1738a7c
--- /dev/null
+++ b/libio/filedoalloc.c
@@ -0,0 +1,103 @@
+/* 
+Copyright (C) 1993 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. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Modified for GNU iostream by Per Bothner 1991, 1992. */
+
+#define _POSIX_SOURCE
+#include "libioP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+/* If this function pointer is non-zero, we should call it.
+   It's supposed 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. */
+void (*_IO_cleanup_registration_needed)();
+
+/*
+ * Allocate a file buffer, or switch to unbuffered I/O.
+ * Per the ANSI C standard, ALL tty devices default to line buffered.
+ *
+ * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
+ * optimisation) right after the _fstat() that finds the buffer size.
+ */
+
+int
+DEFUN(_IO_file_doallocate, (fp),
+      register _IO_FILE *fp)
+{
+  register _IO_size_t size;
+  int couldbetty;
+  register char *p;
+  struct stat st;
+
+  if (_IO_cleanup_registration_needed)
+    (*_IO_cleanup_registration_needed)();
+  
+  if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0)
+    {
+      couldbetty = 0;
+      size = _IO_BUFSIZ;
+#if 0
+      /* do not try to optimise fseek() */
+      fp->_flags |= __SNPT;
+#endif
+    }
+  else
+    {
+      couldbetty = S_ISCHR(st.st_mode);
+#if _IO_HAVE_ST_BLKSIZE
+      size = st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize;
+#else
+      size = _IO_BUFSIZ;
+#endif
+    }
+  p = ALLOC_BUF(size);
+  if (p == NULL)
+    return EOF;
+  _IO_setb(fp, p, p+size, 1);
+  if (couldbetty && isatty(fp->_fileno))
+    fp->_flags |= _IO_LINE_BUF;
+  return 1;
+}
diff --git a/libio/fileno.c b/libio/fileno.c
new file mode 100644
index 0000000000..fbea4d4995
--- /dev/null
+++ b/libio/fileno.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fileno (fp)
+     _IO_FILE* fp;
+{
+  CHECK_FILE (fp, EOF);
+
+  if (!(fp->_flags & _IO_IS_FILEBUF))
+    return EOF;
+
+  return _IO_fileno (fp);
+}
diff --git a/libio/fileops.c b/libio/fileops.c
new file mode 100644
index 0000000000..89381ec699
--- /dev/null
+++ b/libio/fileops.c
@@ -0,0 +1,738 @@
+/* 
+Copyright (C) 1993, 1995 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. */
+
+/*  written by Per Bothner (bothner@cygnus.com) */
+
+#define _POSIX_SOURCE
+#include "libioP.h"
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#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
+   is that of gptr(); in put mode that of pptr().
+
+   The position in the buffer that corresponds to the position
+   in external file system is file_ptr().
+   This is normally _IO_read_end, except in putback mode,
+   when it is _IO_save_end.
+   If the field _fb._offset is >= 0, it gives the offset in
+   the file as a whole corresponding to eGptr(). (?)
+
+   PUT MODE:
+   If a filebuf is in put mode, pbase() is non-NULL and equal to base().
+   Also, epptr() == ebuf().
+   Also, eback() == gptr() && gptr() == egptr().
+   The un-flushed character are those between pbase() and pptr().
+   GET MODE:
+   If a filebuf is in get or putback mode, eback() != egptr().
+   In get mode, the unread characters are between gptr() and egptr().
+   The OS file position corresponds to that of egptr().
+   PUTBACK MODE:
+   Putback mode is used to remember "excess" characters that have
+   been sputbackc'd in a separate putback buffer.
+   In putback mode, the get buffer points to the special putback buffer.
+   The unread characters are the characters between gptr() and egptr()
+   in the putback buffer, as well as the area between save_gptr()
+   and save_egptr(), which point into the original reserve buffer.
+   (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, pbase()==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.
+*/
+
+#define CLOSED_FILEBUF_FLAGS \
+  (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
+
+
+void
+DEFUN(_IO_file_init, (fp),
+      register _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
+     position before we do the first fseek (and until a following fflush). */
+  fp->_offset = _IO_pos_BAD;
+  fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
+
+  _IO_link_in(fp);
+  fp->_fileno = -1;
+}
+
+int
+DEFUN(_IO_file_close_it, (fp),
+      register _IO_FILE* fp)
+{
+  int sync_status, close_status;
+  if (!_IO_file_is_open(fp))
+    return EOF;
+
+  sync_status = _IO_file_sync (fp);
+
+  _IO_unsave_markers(fp);
+
+  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_un_link(fp);
+  fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
+  fp->_fileno = EOF;
+  fp->_offset = _IO_pos_BAD;
+
+  return close_status ? close_status : sync_status;
+}
+
+void
+DEFUN(_IO_file_finish, (fp),
+      register _IO_FILE* 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_FILE *
+DEFUN(_IO_file_fopen, (fp, filename, mode),
+      register _IO_FILE *fp AND const char *filename AND 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);
+  if (fdesc < 0)
+    return NULL;
+  fp->_fileno = fdesc;
+  _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)
+      return NULL;
+  _IO_link_in(fp);
+  return fp;
+}
+
+_IO_FILE*
+DEFUN(_IO_file_attach, (fp, fd),
+      _IO_FILE *fp AND int fd)
+{
+  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;
+  fp->_offset = _IO_pos_BAD;
+  return fp;
+}
+
+_IO_FILE*
+DEFUN(_IO_file_setbuf, (fp, p, len),
+      register _IO_FILE *fp AND char* p AND _IO_ssize_t len)
+{
+    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);
+
+    return fp;
+}
+
+/* Write TO_DO bytes from DATA to FP.
+   Then mark FP has 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_size_t count;
+  if (to_do == 0)
+    return 0;
+  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;
+  _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;
+  return count != to_do ? EOF : 0;
+}
+
+int
+DEFUN(_IO_file_underflow, (fp),
+      register _IO_FILE *fp)
+{
+  _IO_ssize_t count;
+#if 0
+  /* SysV does not make this test; take it out for compatibility */
+  if (fp->_flags & _IO_EOF_SEEN)
+    return (EOF);
+#endif
+
+  if (fp->_flags & _IO_NO_READS)
+    return EOF;
+  if (fp->_IO_read_ptr < fp->_IO_read_end)
+    return *(unsigned char*)fp->_IO_read_ptr;
+
+  if (fp->_IO_buf_base == NULL)
+    _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_switch_to_get_mode(fp);
+
+  count = _IO_SYSREAD (fp, fp->_IO_buf_base,
+		       fp->_IO_buf_end - fp->_IO_buf_base);
+  if (count <= 0)
+    {
+      if (count == 0)
+	fp->_flags |= _IO_EOF_SEEN;
+      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;
+  if (count == 0)
+    return EOF;
+  if (fp->_offset != _IO_pos_BAD)
+    _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)
+{
+  if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
+    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_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
+	}
+      /* Otherwise must be currently reading. */
+      f->_IO_write_ptr = f->_IO_read_ptr;
+      f->_IO_write_base = f->_IO_write_ptr;
+      f->_IO_write_end = f->_IO_buf_end;
+      f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
+
+      if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+	f->_IO_write_end = f->_IO_write_ptr;
+      f->_flags |= _IO_CURRENTLY_PUTTING;
+    }
+  if (ch == EOF)
+    return _IO_do_flush(f);
+  if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
+    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)
+      return EOF;
+  return (unsigned char)ch;
+}
+
+int
+DEFUN(_IO_file_sync, (fp),
+      register _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; 
+  if (delta != 0)
+    {
+#ifdef TODO
+      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)
+	fp->_IO_read_end = fp->_IO_read_ptr;
+#ifdef ESPIPE
+      else if (errno == ESPIPE)
+	; /* Ignore error from unseekable devices. */
+#endif
+      else
+	return EOF;
+    }
+  fp->_offset = _IO_pos_BAD;
+  /* FIXME: Cleanup - can this be shared? */
+  /*    setg(base(), ptr, ptr); */
+  return 0;
+}
+
+_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_pos_t result;
+  _IO_off_t delta, new_offset;
+  long count;
+
+  if (mode == 0)
+    dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+
+  /* Flush unwritten characters.
+     (This may do an unneeded write if we seek within the buffer.
+     But to be able to switch to reading, we would need to set
+     egptr to ptr.  That can't be done in the current design,
+     which assumes file_ptr() is eGptr.  Anyway, since we probably
+     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_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);
+    }
+
+  switch (dir)
+    {
+    case _IO_seek_cur:
+      /* Adjust for read-ahead (bytes is buffer). */
+      offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+      if (fp->_offset == _IO_pos_BAD)
+	goto dumb;
+      /* Make offset absolute, assuming current pointer is file_ptr(). */
+      offset += _IO_pos_as_off(fp->_offset);
+
+      dir = _IO_seek_set;
+      break;
+    case _IO_seek_set:
+      break;
+    case _IO_seek_end:
+      {
+	struct stat st;
+	if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG(st.st_mode))
+	  {
+	    offset += st.st_size;
+	    dir = _IO_seek_set;
+	  }
+	else
+	  goto dumb;
+      }
+    }
+  /* At this point, dir==_IO_seek_set. */
+
+  /* If destination is within current buffer, optimize: */
+  if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
+      && !_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);
+      if (rel_offset >= 0)
+	{
+#if 0
+	  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);
+	      return offset;
+	    }
+#ifdef TODO
+	    /* If we have streammarkers, seek forward by reading ahead. */
+	    if (_IO_have_markers(fp))
+	      {
+		int to_skip = rel_offset
+		  - (fp->_IO_read_ptr - fp->_IO_read_base);
+		if (ignore(to_skip) != to_skip)
+		  goto dumb;
+		return offset;
+	      }
+#endif
+	}
+#ifdef TODO
+      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);
+	  return offset;
+	}
+#endif
+    }
+
+#ifdef TODO
+  _IO_unsave_markers(fp);
+#endif
+
+  if (fp->_flags & _IO_NO_READS)
+    goto dumb;
+
+  /* Try to seek to a block boundary, to improve kernel page management. */
+  new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
+  delta = offset - new_offset;
+  if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
+    {
+      new_offset = offset;
+      delta = 0;
+    }
+  result = _IO_SYSSEEK (fp, new_offset, 0);
+  if (result < 0)
+    return EOF;
+  if (delta == 0)
+    count = 0;
+  else
+    {
+      count = _IO_SYSREAD (fp, fp->_IO_buf_base,
+			   fp->_IO_buf_end - fp->_IO_buf_base);
+      if (count < delta)
+	{
+	  /* We weren't allowed to read, but try to seek the remainder. */
+	  offset = count == EOF ? delta : delta-count;
+	  dir = _IO_seek_cur;
+	  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);
+  fp->_offset = result + count;
+  _IO_mask_flags(fp, 0, _IO_EOF_SEEN);
+  return offset;
+ dumb:
+
+  _IO_unsave_markers(fp);
+  result = _IO_SYSSEEK (fp, offset, dir);
+  if (result != EOF)
+    _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);
+  return result;
+}
+
+_IO_ssize_t
+DEFUN(_IO_file_read, (fp, buf, size),
+      register _IO_FILE* fp AND void* buf AND _IO_ssize_t size)
+{
+  for (;;)
+    {
+      _IO_ssize_t count = _IO_read(fp->_fileno, buf, size);
+#ifdef EINTR
+      if (count == -1 && errno == EINTR)
+	continue;
+#endif
+      return count;
+    }
+}
+
+_IO_pos_t
+DEFUN(_IO_file_seek, (fp, offset, dir),
+      _IO_FILE *fp AND _IO_off_t offset AND int dir)
+{
+  return _IO_lseek(fp->_fileno, offset, dir);
+}
+
+int
+DEFUN(_IO_file_stat, (fp, st),
+      _IO_FILE *fp AND void* st)
+{
+  return _IO_fstat(fp->_fileno, (struct stat*)st);
+}
+
+int
+DEFUN(_IO_file_close, (fp),
+      _IO_FILE* fp)
+{
+  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_ssize_t to_do = n;
+  while (to_do > 0)
+    {
+      _IO_ssize_t count = _IO_write(f->_fileno, data, to_do);
+      if (count == EOF)
+	{
+#ifdef EINTR
+	  if (errno == EINTR)
+	    continue;
+	  else
+#endif
+	    {
+	      f->_flags |= _IO_ERR_SEEN;
+	      break;
+            }
+        }
+      to_do -= count;
+      data = (void*)((char*)data + count);
+    }
+  n -= to_do;
+  if (f->_offset >= 0)
+    f->_offset += n;
+  return n;
+}
+
+_IO_size_t
+DEFUN(_IO_file_xsputn, (f, data, n),
+      _IO_FILE *f AND const void *data AND _IO_size_t n)
+{
+  register const char *s = (char*) data;
+  _IO_size_t to_do = n;
+  int must_flush = 0;
+  _IO_size_t count;
+
+  if (n <= 0)
+    return 0;
+  /* This is an optimized implementation.
+     If the amount to be written straddles a block boundary
+     (or the filebuf is unbuffered), use sys_write directly. */
+
+  /* First figure out how much space is available in the buffer. */
+  count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
+  if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
+    {
+      count = f->_IO_buf_end - f->_IO_write_ptr;
+      if (count >= n)
+	{ register const char *p;
+	  for (p = s + n; p > s; )
+	    {
+	      if (*--p == '\n') {
+		count = p - s + 1;
+		must_flush = 1;
+		break;
+	      }
+	    }
+	}
+    }
+  /* Then fill the buffer. */
+  if (count > 0)
+    {
+      if (count > to_do)
+	count = to_do;
+      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++;
+	}
+      f->_IO_write_ptr += count;
+      to_do -= count;
+    }
+  if (to_do + must_flush > 0)
+    { _IO_size_t block_size, dont_write;
+      /* Next flush the (full) buffer. */
+      if (__overflow(f, EOF) == EOF)
+	return n - to_do;
+
+      /* Try to maintain alignment: write a whole number of blocks.
+	 dont_write is what gets left over. */
+      block_size = f->_IO_buf_end - f->_IO_buf_base;
+      dont_write = block_size >= 128 ? to_do % block_size : 0;
+
+      count = to_do - dont_write;
+      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);
+    }
+  return n - to_do;
+}
+
+#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)
+{
+  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. */
+      if (count > 0)
+	{
+	  if (count > more)
+	    count = more;
+	  if (count > 20)
+	    {
+	      memcpy(s, fp->_IO_read_ptr, count);
+	      s += count;
+	      fp->_IO_read_ptr += count;
+	    }
+	  else if (count <= 0)
+	    count = 0;
+	  else
+	    {
+	      register char *p = fp->_IO_read_ptr;
+	      register int i = (int)count;
+	      while (--i >= 0) *s++ = *p++;
+	      fp->_IO_read_ptr = p;
+            }
+            more -= count;
+        }
+#if 0
+      if (! _IO_in put_mode (fp)
+	  && ! _IO_have_markers (fp) && ! IO_have_backup (fp))
+	{
+	  /* This is an optimization of _IO_file_underflow */
+	  if (fp->_flags & _IO_NO_READS)
+	    break;
+	  /* 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);
+	  if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
+	    _IO_flush_all_linebuffered();
+
+	  _IO_switch_to_get_mode(fp); ???;
+	  count = _IO_SYSREAD (fp, s, more);
+	  if (count <= 0)
+	     {
+	       if (count == 0)
+		 fp->_flags |= _IO_EOF_SEEN;
+	       else
+		 fp->_flags |= _IO_ERR_SEEN, count = 0;
+	     }
+	  
+	  s += count;
+	  more -= count;
+	}
+#endif
+      if (more == 0 || __underflow(fp) == EOF)
+	break;
+    }
+  return n - more;
+}
+#endif
+
+struct _IO_jump_t _IO_file_jumps = {
+  JUMP_INIT_DUMMY,
+  JUMP_INIT(finish, _IO_file_finish),
+  JUMP_INIT(overflow, _IO_file_overflow),
+  JUMP_INIT(underflow, _IO_file_underflow),
+  JUMP_INIT(uflow, _IO_default_uflow),
+  JUMP_INIT(pbackfail, _IO_default_pbackfail),
+  JUMP_INIT(xsputn, _IO_file_xsputn),
+  JUMP_INIT(xsgetn, _IO_default_xsgetn),
+  JUMP_INIT(seekoff, _IO_file_seekoff),
+  JUMP_INIT(seekpos, _IO_default_seekpos),
+  JUMP_INIT(setbuf, _IO_file_setbuf),
+  JUMP_INIT(sync, _IO_file_sync),
+  JUMP_INIT(doallocate, _IO_file_doallocate),
+  JUMP_INIT(read, _IO_file_read),
+  JUMP_INIT(write, _IO_file_write),
+  JUMP_INIT(seek, _IO_file_seek),
+  JUMP_INIT(close, _IO_file_close),
+  JUMP_INIT(stat, _IO_file_stat)
+};
diff --git a/libio/fputc.c b/libio/fputc.c
new file mode 100644
index 0000000000..2339139f72
--- /dev/null
+++ b/libio/fputc.c
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fputc (c, fp)
+     int c;
+     _IO_FILE *fp;
+{
+  CHECK_FILE (fp, EOF);
+  return _IO_putc (c, fp);
+}
diff --git a/libio/freopen.c b/libio/freopen.c
new file mode 100644
index 0000000000..22fa13a697
--- /dev/null
+++ b/libio/freopen.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+FILE*
+freopen (filename, mode, fp)
+     const char* filename;
+     const char* mode;
+     FILE* fp;
+{
+  CHECK_FILE (fp, NULL);
+  if (!(fp->_flags & _IO_IS_FILEBUF))
+    return NULL;
+  return _IO_freopen (filename, mode, fp);
+}
diff --git a/libio/fseek.c b/libio/fseek.c
new file mode 100644
index 0000000000..3afc4283e6
--- /dev/null
+++ b/libio/fseek.c
@@ -0,0 +1,36 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "stdio.h"
+#include "libioP.h"
+
+int
+fseek (fp, offset, whence)
+     _IO_FILE* fp;
+     long int offset;
+     int whence;
+{
+  CHECK_FILE (fp, -1);
+  return _IO_fseek (fp, offset, whence);
+}
diff --git a/libio/genops.c b/libio/genops.c
new file mode 100644
index 0000000000..7eb2d43ee1
--- /dev/null
+++ b/libio/genops.c
@@ -0,0 +1,837 @@
+/* 
+Copyright (C) 1993, 1995 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. */
+
+/* Generic or default I/O operations. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+void
+DEFUN(_IO_un_link, (fp),
+      _IO_FILE *fp)
+{
+  if (fp->_flags & _IO_LINKED) {
+    _IO_FILE **f;
+    for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain) {
+      if (*f == fp) {
+	*f = fp->_chain;
+	break;
+      }
+    }
+    fp->_flags &= ~_IO_LINKED;
+  }
+}
+
+void
+DEFUN(_IO_link_in, (fp),
+      _IO_FILE *fp)
+{
+    if ((fp->_flags & _IO_LINKED) == 0) {
+	fp->_flags |= _IO_LINKED;
+	fp->_chain = _IO_list_all;
+	_IO_list_all = fp;
+    }
+}
+
+/* Return minimum _pos markers
+   Assumes the current get area is the main get area. */
+
+_IO_size_t
+DEFUN(_IO_least_marker, (fp),
+      register _IO_FILE *fp)
+{
+  _IO_ssize_t least_so_far = fp->_IO_read_end - fp->_IO_read_base;
+  register struct _IO_marker *mark;
+  for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+    if (mark->_pos < least_so_far)
+      least_so_far = mark->_pos;
+  return least_so_far;
+}
+
+/* Switch current get area from backup buffer to (start of) main get area. */
+
+void
+DEFUN(_IO_switch_to_main_get_area, (fp),
+      _IO_FILE *fp)
+{
+  char *tmp;
+  fp->_flags &= ~_IO_IN_BACKUP;
+  /* Swap _IO_read_end and _IO_save_end. */
+  tmp = fp->_IO_read_end; fp->_IO_read_end= fp->_IO_save_end; fp->_IO_save_end= tmp;
+  /* Swap _IO_read_base and _IO_save_base. */
+  tmp = fp->_IO_read_base; fp->_IO_read_base = fp->_IO_save_base; fp->_IO_save_base = tmp;
+  fp->_IO_read_ptr = fp->_IO_read_base;
+}
+
+/* Switch current get area from main get area to (end of) backup area. */
+
+void
+DEFUN(_IO_switch_to_backup_area, (fp),
+     register _IO_FILE *fp)
+{
+  char *tmp;
+  fp->_flags |= _IO_IN_BACKUP;
+  /* Swap _IO_read_end and _IO_save_end. */
+  tmp = fp->_IO_read_end; fp->_IO_read_end = fp->_IO_save_end; fp->_IO_save_end = tmp;
+  /* Swap _gbase and _IO_save_base. */
+  tmp = fp->_IO_read_base; fp->_IO_read_base = fp->_IO_save_base; fp->_IO_save_base = tmp;
+  fp->_IO_read_ptr = fp->_IO_read_end;
+}
+
+int
+DEFUN(_IO_switch_to_get_mode, (fp),
+     register _IO_FILE *fp)
+{
+  if (fp->_IO_write_ptr > fp->_IO_write_base)
+    if (_IO_OVERFLOW (fp, EOF) == EOF)
+      return EOF;
+  if (_IO_in_backup(fp))
+    fp->_IO_read_base = fp->_IO_backup_base;
+  else
+    {
+      fp->_IO_read_base = fp->_IO_buf_base;
+      if (fp->_IO_write_ptr > fp->_IO_read_end)
+	fp->_IO_read_end = fp->_IO_write_ptr;
+    }
+  fp->_IO_read_ptr = fp->_IO_write_ptr;
+
+  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
+
+  fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+  return 0;
+}
+
+void
+DEFUN(_IO_free_backup_area, (fp),
+     register _IO_FILE *fp)
+{
+  if (_IO_in_backup (fp))
+    _IO_switch_to_main_get_area(fp);  /* Just in case. */
+  free (fp->_IO_save_base);
+  fp->_IO_save_base = NULL;
+  fp->_IO_save_end = NULL;
+  fp->_IO_backup_base = NULL;
+}
+
+#if 0
+int
+DEFUN(_IO_switch_to_put_mode, (fp),
+      register _IO_FILE *fp)
+{
+  fp->_IO_write_base = fp->_IO_read_ptr;
+  fp->_IO_write_ptr = fp->_IO_read_ptr;
+  /* Following is wrong if line- or un-buffered? */
+  fp->_IO_write_end = fp->_flags & _IO_IN_BACKUP ? fp->_IO_read_end : fp->_IO_buf_end;
+
+  fp->_IO_read_ptr = fp->_IO_read_end;
+  fp->_IO_read_base = fp->_IO_read_end;
+
+  fp->_flags |= _IO_CURRENTLY_PUTTING;
+  return 0;
+}
+#endif
+
+int
+DEFUN(__overflow, (f, ch),
+      _IO_FILE *f AND int ch)
+{
+  return _IO_OVERFLOW (f, ch);
+}
+
+static int
+DEFUN(save_for_backup, (fp),
+      _IO_FILE *fp)
+{
+  /* Append [_IO_read_base.._IO_read_end] to backup area. */
+  int least_mark = _IO_least_marker(fp);
+  /* needed_size is how much space we need in the backup area. */
+  int needed_size = (fp->_IO_read_end - fp->_IO_read_base) - least_mark;
+  int current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
+  int avail; /* Extra space available for future expansion. */
+  int delta;
+  struct _IO_marker *mark;
+  if (needed_size > current_Bsize)
+    {
+      char *new_buffer;
+      avail = 100;
+      new_buffer = (char*)malloc(avail+needed_size);
+      if (new_buffer == NULL)
+	return EOF;		/* FIXME */
+      if (least_mark < 0)
+	{
+	  memcpy(new_buffer + avail,
+		 fp->_IO_save_end + least_mark,
+		 -least_mark);
+	  memcpy(new_buffer +avail - least_mark,
+		 fp->_IO_read_base,
+		 fp->_IO_read_end - fp->_IO_read_base);
+	}
+      else
+	memcpy(new_buffer + avail,
+	       fp->_IO_read_base + least_mark,
+	       needed_size);
+      if (fp->_IO_save_base)
+	free (fp->_IO_save_base);
+      fp->_IO_save_base = new_buffer;
+      fp->_IO_save_end = new_buffer + avail + needed_size;
+    }
+  else
+    {
+      avail = current_Bsize - needed_size;
+      if (least_mark < 0)
+	{
+	  memmove(fp->_IO_save_base + avail,
+		  fp->_IO_save_end + least_mark,
+		  -least_mark);
+	  memcpy(fp->_IO_save_base + avail - least_mark,
+		 fp->_IO_read_base,
+		 fp->_IO_read_end - fp->_IO_read_base);
+	}
+      else if (needed_size > 0)
+	memcpy(fp->_IO_save_base + avail,
+	       fp->_IO_read_base + least_mark,
+	       needed_size);
+    }
+  /* FIXME: Dubious arithmetic if pointers are NULL */
+  fp->_IO_backup_base = fp->_IO_save_base + avail;
+  /* Adjust all the streammarkers. */
+  delta = fp->_IO_read_end - fp->_IO_read_base;
+  for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+    mark->_pos -= delta;
+  return 0;
+}
+
+int
+DEFUN(__underflow, (fp),
+      _IO_FILE *fp)
+{
+  if (_IO_in_put_mode(fp))
+    if (_IO_switch_to_get_mode(fp) == EOF) return EOF;
+  if (fp->_IO_read_ptr < fp->_IO_read_end)
+    return *(unsigned char*)fp->_IO_read_ptr;
+  if (_IO_in_backup(fp))
+    {
+      _IO_switch_to_main_get_area(fp);
+      if (fp->_IO_read_ptr < fp->_IO_read_end)
+	return *fp->_IO_read_ptr;
+    }
+  if (_IO_have_markers(fp))
+    {
+      if (save_for_backup (fp))
+	return EOF;
+    }
+  else if (_IO_have_backup(fp))
+    _IO_free_backup_area(fp);
+  return _IO_UNDERFLOW (fp);
+}
+
+int
+DEFUN(__uflow, (fp),
+     _IO_FILE *fp)
+{
+  if (_IO_in_put_mode(fp))
+    if (_IO_switch_to_get_mode(fp) == EOF) return EOF;
+  if (fp->_IO_read_ptr < fp->_IO_read_end)
+    return *(unsigned char*)fp->_IO_read_ptr++;
+  if (_IO_in_backup(fp))
+    {
+      _IO_switch_to_main_get_area(fp);
+      if (fp->_IO_read_ptr < fp->_IO_read_end)
+	return *fp->_IO_read_ptr++;
+    }
+  if (_IO_have_markers(fp))
+    {
+      if (save_for_backup (fp))
+	return EOF;
+    }
+  else if (_IO_have_backup(fp))
+    _IO_free_backup_area(fp);
+  return _IO_UFLOW (fp);
+}
+
+void
+DEFUN(_IO_setb, (f, b, eb, a),
+      _IO_FILE *f AND char *b AND char *eb AND int a)
+{
+  if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
+    FREE_BUF(f->_IO_buf_base);
+  f->_IO_buf_base = b;
+  f->_IO_buf_end = eb;
+  if (a)
+    f->_flags &= ~_IO_USER_BUF;
+  else
+    f->_flags |= _IO_USER_BUF;
+}
+
+void
+DEFUN(_IO_doallocbuf, (fp),
+      register _IO_FILE *fp)
+{
+  if (fp->_IO_buf_base)
+    return;
+  if (!(fp->_flags & _IO_UNBUFFERED))
+    if (_IO_DOALLOCATE (fp) != EOF)
+      return;
+  _IO_setb(fp, fp->_shortbuf, fp->_shortbuf+1, 0);
+}
+
+int
+DEFUN(_IO_default_underflow, (fp),
+      _IO_FILE *fp)
+{
+  return EOF;
+}
+
+int
+DEFUN(_IO_default_uflow, (fp),
+      _IO_FILE *fp)
+{
+  int ch = _IO_UNDERFLOW (fp);
+  if (ch == EOF)
+    return EOF;
+  return *(unsigned char*)fp->_IO_read_ptr++;
+}
+
+_IO_size_t
+DEFUN(_IO_default_xsputn, (f, data, n),
+      register _IO_FILE *f AND const void *data AND _IO_size_t n)
+{
+  register const char *s = (char*) data;
+  register _IO_size_t more = n;
+  if (more <= 0)
+    return 0;
+  for (;;)
+    {
+      _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
+      if (count > 0)
+	{
+	  if (count > more)
+	    count = more;
+	  if (count > 20)
+	    {
+	      memcpy(f->_IO_write_ptr, s, count);
+	      s += count;
+	      f->_IO_write_ptr += count;
+            }
+	  else if (count <= 0)
+	    count = 0;
+	  else
+	    {
+	      register char *p = f->_IO_write_ptr;
+	      register _IO_ssize_t i;
+	      for (i = count; --i >= 0; ) *p++ = *s++;
+	      f->_IO_write_ptr = p;
+            }
+	  more -= count;
+        }
+      if (more == 0 || __overflow(f, (unsigned char)*s++) == EOF)
+	break;
+      more--;
+    }
+  return n - more;
+}
+
+_IO_size_t
+DEFUN(_IO_sgetn, (fp, data, n),
+      _IO_FILE *fp AND void *data AND _IO_size_t n)
+{
+  /* FIXME handle putback buffer here! */
+  return _IO_XSGETN (fp, data, n);
+}
+
+_IO_size_t
+DEFUN(_IO_default_xsgetn, (fp, data, n),
+      _IO_FILE *fp AND void *data AND _IO_size_t n)
+{
+  register _IO_size_t more = n;
+  register char *s = (char*) data;
+  for (;;)
+    {
+      _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; /* Data available. */
+      if (count > 0)
+	{
+	  if (count > more)
+	    count = more;
+	  if (count > 20)
+	    {
+	      memcpy(s, fp->_IO_read_ptr, count);
+	      s += count;
+	      fp->_IO_read_ptr += count;
+	    }
+	  else if (count <= 0)
+	    count = 0;
+	  else
+	    {
+	      register char *p = fp->_IO_read_ptr;
+	      register int i = (int)count;
+	      while (--i >= 0) *s++ = *p++;
+	      fp->_IO_read_ptr = p;
+            }
+            more -= count;
+        }
+      if (more == 0 || __underflow(fp) == EOF)
+	break;
+    }
+  return n - more;
+}
+
+int
+DEFUN(_IO_sync, (fp),
+      register _IO_FILE *fp)
+{
+  return 0;
+}
+
+_IO_FILE*
+DEFUN(_IO_default_setbuf, (fp, p, len),
+      register _IO_FILE *fp AND char* p AND _IO_ssize_t len)
+{
+    if (_IO_SYNC (fp) == EOF)
+	return NULL;
+    if (p == NULL || len == 0)
+      {
+	fp->_flags |= _IO_UNBUFFERED;
+	_IO_setb(fp, fp->_shortbuf, fp->_shortbuf+1, 0);
+      }
+    else
+      {
+	fp->_flags &= ~_IO_UNBUFFERED;
+	_IO_setb(fp, p, p+len, 0);
+      }
+    fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
+    fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
+    return fp;
+}
+
+_IO_pos_t
+DEFUN(_IO_default_seekpos, (fp, pos, mode),
+      _IO_FILE *fp AND _IO_pos_t pos AND int mode)
+{
+  return _IO_SEEKOFF (fp, _IO_pos_as_off(pos), 0, mode);
+}
+
+int
+DEFUN(_IO_default_doallocate, (fp),
+      _IO_FILE *fp)
+{
+  char *buf = ALLOC_BUF(_IO_BUFSIZ);
+  if (buf == NULL)
+    return EOF;
+  _IO_setb(fp, buf, buf+_IO_BUFSIZ, 1);
+  return 1;
+}
+
+void
+DEFUN(_IO_init, (fp, flags),
+      register _IO_FILE *fp AND int flags)
+{
+  fp->_flags = _IO_MAGIC|flags;
+  fp->_IO_buf_base = NULL;
+  fp->_IO_buf_end = NULL;
+  fp->_IO_read_base = NULL;
+  fp->_IO_read_ptr = NULL;
+  fp->_IO_read_end = NULL;
+  fp->_IO_write_base = NULL;
+  fp->_IO_write_ptr = NULL;
+  fp->_IO_write_end = NULL;
+  fp->_chain = NULL; /* Not necessary. */
+
+  fp->_IO_save_base = NULL;
+  fp->_IO_backup_base = NULL;
+  fp->_IO_save_end = NULL;
+  fp->_markers = NULL;
+  fp->_cur_column = 0;
+}
+
+int
+DEFUN(_IO_default_sync, (fp),
+      _IO_FILE *fp)
+{
+  return 0;
+}
+
+/* The way the C++ classes are mapped into the C functions in the
+   current implementation, this function can get called twice! */
+
+void
+DEFUN(_IO_default_finish, (fp),
+      _IO_FILE *fp)
+{
+  struct _IO_marker *mark;
+  if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+    {
+      FREE_BUF(fp->_IO_buf_base);
+      fp->_IO_buf_base = fp->_IO_buf_end = NULL;
+    }
+
+  for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+    mark->_sbuf = NULL;
+
+  if (fp->_IO_save_base)
+    {
+      free (fp->_IO_save_base);
+      fp->_IO_save_base = NULL;
+    }
+
+  _IO_un_link(fp);
+}
+
+_IO_pos_t
+DEFUN(_IO_default_seekoff, (fp, offset, dir, mode),
+      register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
+{
+    return _IO_pos_BAD;
+}
+
+int
+DEFUN(_IO_sputbackc, (fp, c),
+      register _IO_FILE *fp AND int c)
+{
+  if (fp->_IO_read_ptr > fp->_IO_read_base
+      && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
+    {
+      fp->_IO_read_ptr--;
+      return (unsigned char)c;
+    }
+  return _IO_PBACKFAIL (fp, c);
+}
+
+int
+DEFUN(_IO_sungetc, (fp),
+      register _IO_FILE *fp)
+{
+  if (fp->_IO_read_ptr > fp->_IO_read_base)
+    {
+      fp->_IO_read_ptr--;
+      return (unsigned char)*fp->_IO_read_ptr;
+    }
+  else
+    return _IO_PBACKFAIL (fp, EOF);
+}
+
+#if 0 /* Work in progress */
+void
+DEFUN(_IO_set_column, (fp, c),
+      register _IO_FILE *fp AND int c)
+{
+  if (c == -1)
+    fp->_column = -1;
+  else
+    fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
+}
+#else
+int
+DEFUN(_IO_set_column, (fp, i),
+      register _IO_FILE *fp AND int i)
+{
+  fp->_cur_column = i+1;
+  return 0;
+}
+#endif
+
+
+unsigned
+DEFUN(_IO_adjust_column, (start, line, count),
+      unsigned start AND const char *line AND int count)
+{
+  register const char *ptr = line + count;
+  while (ptr > line)
+    if (*--ptr == '\n')
+      return line + count - ptr - 1;
+  return start + count;
+}
+
+int
+DEFUN(_IO_get_column, (fp),
+      register _IO_FILE *fp)
+{
+  if (fp->_cur_column) 
+    return _IO_adjust_column(fp->_cur_column - 1,
+			      fp->_IO_write_base,
+			      fp->_IO_write_ptr - fp->_IO_write_base);
+  return -1;
+}
+
+int
+DEFUN_VOID(_IO_flush_all)
+{
+  int result = 0;
+  _IO_FILE *fp;
+  for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+    if (fp->_IO_write_ptr > fp->_IO_write_base
+	&& _IO_OVERFLOW (fp, EOF) == EOF)
+      result = EOF;
+  return result;
+}
+
+void
+DEFUN_VOID(_IO_flush_all_linebuffered)
+{
+  _IO_FILE *fp;
+  for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+    if (fp->_flags & _IO_LINE_BUF)
+      _IO_OVERFLOW (fp, EOF);
+}
+
+void
+DEFUN_VOID(_IO_unbuffer_all)
+{
+  _IO_FILE *fp;
+  for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
+    if (! (fp->_flags & _IO_UNBUFFERED))
+      _IO_SETBUF (fp, NULL, 0);
+}
+
+void
+DEFUN_VOID(_IO_cleanup)
+{
+  _IO_flush_all ();
+
+  /* We currently don't have a reliable mechanism for making sure that
+     C++ static destructors are executed in the correct order.
+     So it is possible that other static destructord might want to
+     write to cout - and they're supposed to be able to do so.
+
+     The following will make the standard streambufs be unbuffered, 
+     which forces any output from late destructors to be written out. */
+  _IO_unbuffer_all ();
+}
+
+void
+DEFUN(_IO_init_marker, (marker, fp),
+      struct _IO_marker *marker AND _IO_FILE *fp)
+{
+  marker->_sbuf = fp;
+  if (_IO_in_put_mode(fp))
+    _IO_switch_to_get_mode(fp);
+  if (_IO_in_backup(fp))
+    marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
+  else
+    marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
+  
+  /* Should perhaps sort the chain? */
+  marker->_next = fp->_markers;
+  fp->_markers = marker;
+}
+
+void
+DEFUN(_IO_remove_marker, (marker),
+      register struct _IO_marker *marker)
+{
+  /* Unlink from sb's chain. */
+  register struct _IO_marker **ptr = &marker->_sbuf->_markers;
+  for (; ; ptr = &(*ptr)->_next)
+    {
+      if (*ptr == NULL)
+	break;
+      else if (*ptr == marker)
+	{
+	  *ptr = marker->_next;
+	  return;
+	}
+    }
+#if 0
+    if _sbuf has a backup area that is no longer needed, should we delete
+    it now, or wait until the next underflow?
+#endif
+}
+
+#define BAD_DELTA EOF
+
+int
+DEFUN(_IO_marker_difference, (mark1, mark2),
+      struct _IO_marker *mark1 AND struct _IO_marker *mark2)
+{
+  return mark1->_pos - mark2->_pos;
+}
+
+/* Return difference between MARK and current posistion of MARK's stream. */
+int
+DEFUN(_IO_marker_delta, (mark),
+      struct _IO_marker *mark)
+{
+  int cur_pos;
+  if (mark->_sbuf == NULL)
+    return BAD_DELTA;
+  if (_IO_in_backup(mark->_sbuf))
+    cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
+  else
+    cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
+  return mark->_pos - cur_pos;
+}
+
+int
+DEFUN(_IO_seekmark, (fp, mark, delta),
+      _IO_FILE *fp AND struct _IO_marker *mark AND int delta)
+{
+  if (mark->_sbuf != fp)
+    return EOF;
+ if (mark->_pos >= 0)
+    {
+      if (_IO_in_backup(fp))
+	_IO_switch_to_main_get_area(fp);
+      fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
+    }
+  else
+    {
+      if (!_IO_in_backup(fp))
+	_IO_switch_to_backup_area(fp);
+      fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
+    }
+  return 0;
+}
+
+void
+DEFUN(_IO_unsave_markers, (fp),
+     register _IO_FILE *fp)
+{
+  register struct _IO_marker *mark = fp->_markers;
+  if (mark)
+    {
+#ifdef TODO
+      streampos offset = seekoff(0, ios::cur, ios::in);
+      if (offset != EOF)
+	{
+	  offset += eGptr() - Gbase();
+	  for ( ; mark != NULL; mark = mark->_next)
+	    mark->set_streampos(mark->_pos + offset);
+	}
+    else
+      {
+	for ( ; mark != NULL; mark = mark->_next)
+	  mark->set_streampos(EOF);
+      }
+#endif
+      fp->_markers = 0;
+    }
+
+  if (_IO_have_backup(fp))
+    _IO_free_backup_area(fp);
+}
+
+int
+DEFUN(_IO_nobackup_pbackfail, (fp, c),
+     register _IO_FILE *fp AND int c)
+{
+  if (fp->_IO_read_ptr > fp->_IO_read_base)
+	fp->_IO_read_ptr--;
+  if (c != EOF && *fp->_IO_read_ptr != c)
+      *fp->_IO_read_ptr = c;
+  return (unsigned char)c;
+}
+
+int
+DEFUN(_IO_default_pbackfail, (fp, c),
+      register _IO_FILE *fp AND int c)
+{
+  if (fp->_IO_read_ptr <= fp->_IO_read_base)
+      {
+	/* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
+	if (_IO_have_backup(fp) && !_IO_in_backup(fp))
+	  _IO_switch_to_backup_area(fp);
+	
+	if (!_IO_have_backup(fp))
+	  {
+	    /* No backup buffer: allocate one. */
+	    /* Use nshort buffer, if unused? (probably not)  FIXME */
+	    int backup_size = 128;
+	    char *bbuf = (char*)malloc(backup_size);
+	    if (bbuf == NULL)
+	      return EOF;
+	    fp->_IO_save_base = bbuf;
+	    fp->_IO_save_end = fp->_IO_save_base + backup_size;
+	    fp->_IO_backup_base = fp->_IO_save_end;
+	    _IO_switch_to_backup_area(fp);
+	  }
+	else if (fp->_IO_read_ptr <= fp->_IO_read_base)
+	  {
+	    /* Increase size of existing backup buffer. */
+	    _IO_size_t new_size;
+	    _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
+	    char *new_buf;
+	    new_size = 2 * old_size;
+	    new_buf = (char*)malloc(new_size);
+	    if (new_buf == NULL)
+	      return EOF;
+	    memcpy(new_buf+(new_size-old_size), fp->_IO_read_base, old_size);
+	    free (fp->_IO_read_base);
+	    _IO_setg(fp,
+		     new_buf, new_buf+(new_size-old_size), new_buf+new_size);
+	    fp->_IO_backup_base = fp->_IO_read_ptr;
+	  }
+      }
+  fp->_IO_read_ptr--;
+  if (c != EOF && *fp->_IO_read_ptr != c)
+    *fp->_IO_read_ptr = c;
+  return (unsigned char)*fp->_IO_read_ptr;
+}
+
+_IO_pos_t
+DEFUN(_IO_default_seek, (fp, offset, dir),
+      _IO_FILE *fp AND _IO_off_t offset AND int dir)
+{
+  return _IO_pos_BAD;
+}
+
+int
+DEFUN(_IO_default_stat, (fp, st),
+      _IO_FILE *fp AND void* st)
+{
+  return EOF;
+}
+
+_IO_ssize_t
+DEFUN(_IO_default_read, (fp, data, n),
+      register _IO_FILE* fp AND void* data AND _IO_ssize_t n)
+{
+  return -1;
+}
+
+_IO_ssize_t
+DEFUN(_IO_default_write, (fp, data, n),
+      register _IO_FILE* fp AND const void* data AND _IO_ssize_t n)
+{
+  return 0;
+}
+
+
+#ifdef TODO
+#if defined(linux)
+#define IO_CLEANUP ;
+#endif
+
+#ifdef IO_CLEANUP
+  IO_CLEANUP
+#else
+struct __io_defs {
+    __io_defs() { }
+    ~__io_defs() { _IO_cleanup(); }
+};   
+__io_defs io_defs__;
+#endif
+
+#endif /* TODO */
diff --git a/libio/getc.c b/libio/getc.c
new file mode 100644
index 0000000000..844bca4750
--- /dev/null
+++ b/libio/getc.c
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef getc
+
+int
+getc (stream)
+     FILE *stream;
+{
+  return _IO_getc (stream);
+}
diff --git a/libio/getchar.c b/libio/getchar.c
new file mode 100644
index 0000000000..875bceb83d
--- /dev/null
+++ b/libio/getchar.c
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef getchar
+
+int
+getchar ()
+{
+  return _IO_getc (stdin);
+}
diff --git a/libio/iofclose.c b/libio/iofclose.c
new file mode 100644
index 0000000000..c797d86fd8
--- /dev/null
+++ b/libio/iofclose.c
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+int
+_IO_fclose (fp)
+     register _IO_FILE *fp;
+{
+  int status;
+
+  CHECK_FILE(fp, EOF);
+
+  if (fp->_IO_file_flags & _IO_IS_FILEBUF)
+    status = _IO_file_close_it (fp);
+  else
+    status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
+  _IO_FINISH (fp);
+  if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
+    {
+      fp->_IO_file_flags = 0;
+      free(fp);
+    }
+  return status;
+}
+
+weak_alias (_IO_fclose, fclose)
diff --git a/libio/iofdopen.c b/libio/iofdopen.c
new file mode 100644
index 0000000000..6bb19fa214
--- /dev/null
+++ b/libio/iofdopen.c
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 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. */
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "libioP.h"
+#include <fcntl.h>
+
+#ifndef _IO_fcntl
+#define _IO_fcntl fcntl
+#endif
+
+_IO_FILE *
+_IO_fdopen (fd, mode)
+     int fd;
+     const char *mode;
+{
+  int read_write;
+  int posix_mode = 0;
+  struct _IO_FILE_plus *fp;
+  int fd_flags;
+
+  switch (*mode++)
+    {
+    case 'r':
+      read_write = _IO_NO_WRITES;
+      break;
+    case 'w':
+      read_write = _IO_NO_READS;
+      break;
+    case 'a':
+      posix_mode = O_APPEND;
+      read_write = _IO_NO_READS|_IO_IS_APPENDING;
+      break;
+    default:
+#ifdef EINVAL
+      errno = EINVAL;
+#endif
+      return NULL;
+  }
+  if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
+    read_write &= _IO_IS_APPENDING;
+#ifdef F_GETFL
+  fd_flags = _IO_fcntl (fd, F_GETFL);
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#endif
+  if (fd_flags == -1
+      || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
+      || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
+    return NULL;
+
+  /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
+     [System Application Program Interface (API) Amendment 1:
+     Realtime Extensions], Rationale B.8.3.3
+     Open a Stream on a File Descriptor says:
+
+         Although not explicitly required by POSIX.1, a good
+         implementation of append ("a") mode would cause the
+         O_APPEND flag to be set.
+
+     (Historical implementations [such as Solaris2] do a one-time
+     seek in fdopen.)
+
+     However, we do not turn O_APPEND off if the mode is "w" (even
+     though that would seem consistent) because that would be more
+     likely to break historical programs.
+     */
+  if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
+    {
+#ifdef F_SETFL
+      if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
+#endif
+	return NULL;
+    }
+#endif
+
+  fp = (struct _IO_FILE_plus *) malloc (sizeof (struct _IO_FILE_plus));
+  if (fp == NULL)
+    return NULL;
+  _IO_init (&fp->file, 0);
+  _IO_JUMPS (&fp->file) = &_IO_file_jumps;
+  _IO_file_init (&fp->file);
+#if  !_IO_UNIFIED_JUMPTABLES
+  fp->vtable = NULL;
+#endif
+  if (_IO_file_attach (&fp->file, fd) == NULL)
+    {
+      _IO_un_link (&fp->file);
+      free (fp);
+      return NULL;
+    }
+  fp->file._flags &= ~_IO_DELETE_DONT_CLOSE;
+
+  fp->file._IO_file_flags =
+    _IO_mask_flags (&fp->file, read_write,
+		    _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+
+  return (_IO_FILE *) fp;
+}
+
+weak_alias (_IO_fdopen, fdopen)
diff --git a/libio/iofflush.c b/libio/iofflush.c
new file mode 100644
index 0000000000..1f549505c5
--- /dev/null
+++ b/libio/iofflush.c
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+
+int
+_IO_fflush (fp)
+     register _IO_FILE *fp;
+{
+  if (fp == NULL)
+    return _IO_flush_all ();
+  else
+    {
+      CHECK_FILE (fp, EOF);
+      return _IO_SYNC (fp) ? EOF : 0;
+    }
+}
+
+weak_alias (_IO_fflush, fflush)
diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c
new file mode 100644
index 0000000000..bc2215fc01
--- /dev/null
+++ b/libio/iofgetpos.c
@@ -0,0 +1,49 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#include <errno.h>
+/* ANSI explicily requires setting errno to a positive value on failure. */
+
+int
+_IO_fgetpos (fp, posp)
+     _IO_FILE* fp;
+     _IO_fpos_t *posp;
+{
+  _IO_fpos_t pos;
+  CHECK_FILE (fp, EOF);
+  pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
+  if (pos == _IO_pos_BAD)
+    {
+#ifdef EIO
+      if (errno == 0)
+	errno = EIO;
+#endif
+      return EOF;
+    }
+  *posp = pos;
+  return 0;
+}
+
+weak_alias (_IO_fgetpos, fgetpos)
diff --git a/libio/iofgets.c b/libio/iofgets.c
new file mode 100644
index 0000000000..a9f161dce8
--- /dev/null
+++ b/libio/iofgets.c
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+
+char*
+_IO_fgets (buf, n, fp)
+     char* buf;
+     int n;
+     _IO_FILE* fp;
+{
+  _IO_size_t count;
+  CHECK_FILE (fp, NULL);
+  if (n <= 0)
+    return NULL;
+  count = _IO_getline (fp, buf, n - 1, '\n', 1);
+  if (count == 0 || (fp->_IO_file_flags & _IO_ERR_SEEN))
+    return NULL;
+  buf[count] = 0;
+  return buf;
+}
+
+weak_alias (_IO_fgets, fgets)
diff --git a/libio/iofopen.c b/libio/iofopen.c
new file mode 100644
index 0000000000..14cce5336a
--- /dev/null
+++ b/libio/iofopen.c
@@ -0,0 +1,52 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+_IO_FILE *
+_IO_fopen (filename, mode)
+     const char *filename;
+     const char *mode;
+{
+  struct _IO_FILE_plus *fp =
+    (struct _IO_FILE_plus *) malloc (sizeof (struct _IO_FILE_plus));
+  if (fp == NULL)
+    return NULL;
+  _IO_init (&fp->file, 0);
+  _IO_JUMPS (&fp->file) = &_IO_file_jumps;
+  _IO_file_init (&fp->file);
+#if  !_IO_UNIFIED_JUMPTABLES
+  fp->vtable = NULL;
+#endif
+  if (_IO_file_fopen (&fp->file, filename, mode) != NULL)
+        return (_IO_FILE *) fp;
+  _IO_un_link (&fp->file);
+  free (fp);
+  return NULL;
+}
+
+weak_alias (_IO_fopen, fopen)
diff --git a/libio/iofopncook.c b/libio/iofopncook.c
new file mode 100644
index 0000000000..0b57ecd344
--- /dev/null
+++ b/libio/iofopncook.c
@@ -0,0 +1,163 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include <libioP.h>
+#include <stdlib.h>
+
+struct _IO_cookie_file {
+  struct _IO_FILE file;
+  const void *vtable;
+  void *cookie;
+  _IO_cookie_io_functions_t io_functions;
+};
+
+
+static _IO_ssize_t
+_IO_cookie_read (fp, buf, size)
+     register _IO_FILE* fp;
+     void* buf;
+     _IO_ssize_t size;
+{
+  struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+
+  if (cfile->io_functions.read == NULL)
+    return -1;
+
+  return cfile->io_functions.read (cfile->cookie, buf, size);
+}
+
+static _IO_ssize_t
+_IO_cookie_write (fp, buf, size)
+     register _IO_FILE* fp;
+     const void* buf;
+     _IO_ssize_t size;
+{
+  struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+
+  if (cfile->io_functions.write == NULL)
+    return -1;
+
+  return cfile->io_functions.write (cfile->cookie, buf, size);
+}
+
+static _IO_fpos_t
+_IO_cookie_seek (fp, offset, dir)
+     _IO_FILE *fp;
+     _IO_off_t offset;
+     int dir;
+{
+  struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+  _IO_fpos_t pos;
+
+  if (cfile->io_functions.seek == NULL)
+    return _IO_pos_BAD;
+
+  pos = _IO_pos_0;
+  _IO_pos_adjust (pos, offset);
+
+  if (cfile->io_functions.seek (cfile->cookie, pos, dir))
+    return _IO_pos_BAD;
+
+  return pos;
+}
+
+static int
+_IO_cookie_close (fp)
+     _IO_FILE* fp;
+{
+  struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
+
+  if (cfile->io_functions.close == NULL)
+    return 0;
+
+  return cfile->io_functions.close (cfile->cookie);
+}
+
+
+static struct _IO_jump_t _IO_cookie_jumps = {
+  JUMP_INIT_DUMMY,
+  JUMP_INIT(finish, _IO_file_finish),
+  JUMP_INIT(overflow, _IO_file_overflow),
+  JUMP_INIT(underflow, _IO_file_underflow),
+  JUMP_INIT(uflow, _IO_default_uflow),
+  JUMP_INIT(pbackfail, _IO_default_pbackfail),
+  JUMP_INIT(xsputn, _IO_file_xsputn),
+  JUMP_INIT(xsgetn, _IO_default_xsgetn),
+  JUMP_INIT(seekoff, _IO_file_seekoff),
+  JUMP_INIT(seekpos, _IO_default_seekpos),
+  JUMP_INIT(setbuf, _IO_file_setbuf),
+  JUMP_INIT(sync, _IO_file_sync),
+  JUMP_INIT(doallocate, _IO_file_doallocate),
+  JUMP_INIT(read, _IO_cookie_read),
+  JUMP_INIT(write, _IO_cookie_write),
+  JUMP_INIT(seek, _IO_cookie_seek),
+  JUMP_INIT(close, _IO_cookie_close),
+  JUMP_INIT(stat, _IO_default_stat)
+};
+
+
+_IO_FILE *
+fopencookie (cookie, mode, io_functions)
+     void *cookie;
+     const char *mode;
+     _IO_cookie_io_functions_t io_functions;
+{
+  int read_write;
+  struct _IO_cookie_file *cfile;
+
+  switch (*mode++)
+    {
+    case 'r':
+      read_write = _IO_NO_WRITES;
+      break;
+    case 'w':
+      read_write = _IO_NO_READS;
+      break;
+    case 'a':
+      read_write = _IO_NO_READS|_IO_IS_APPENDING;
+      break;
+    default:
+      return NULL;
+  }
+  if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
+    read_write &= _IO_IS_APPENDING;
+
+  cfile  = (struct _IO_cookie_file *) malloc (sizeof (struct _IO_cookie_file));
+  if (cfile == NULL)
+    return NULL;
+
+  _IO_init (&cfile->file, 0);
+  _IO_JUMPS (&cfile->file) = &_IO_cookie_jumps;
+  cfile->cookie = cookie;
+  cfile->io_functions = io_functions;
+
+  _IO_file_init(&cfile->file);
+
+  cfile->file._IO_file_flags =
+    _IO_mask_flags (&cfile->file, read_write,
+		    _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+
+  return &cfile->file;
+}
+
diff --git a/libio/iofprintf.c b/libio/iofprintf.c
new file mode 100644
index 0000000000..74e28263b5
--- /dev/null
+++ b/libio/iofprintf.c
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_fprintf
+#ifdef __STDC__
+  (_IO_FILE *fp, const char* format, ...)
+#else
+(fp, format, va_alist) _IO_FILE *fp; char *format; va_dcl
+#endif
+{
+  int ret;
+  va_list args;
+  CHECK_FILE (fp, -1);
+  _IO_va_start (args, format);
+  ret = _IO_vfprintf (fp, format, args);
+  va_end (args);
+  return ret;
+}
diff --git a/libio/iofputs.c b/libio/iofputs.c
new file mode 100644
index 0000000000..62bc981e1d
--- /dev/null
+++ b/libio/iofputs.c
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include <string.h>
+
+int
+_IO_fputs (str, fp)
+      const char *str;
+      _IO_FILE *fp;
+{
+  _IO_size_t len = strlen (str);
+  CHECK_FILE (fp, EOF);
+  if (_IO_sputn( fp, str, len) != len)
+    return EOF;
+  return 1;
+}
+
+weak_alias (_IO_fputs, fputs)
diff --git a/libio/iofread.c b/libio/iofread.c
new file mode 100644
index 0000000000..babe2c54cc
--- /dev/null
+++ b/libio/iofread.c
@@ -0,0 +1,42 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+
+_IO_size_t
+_IO_fread (buf, size, count, fp)
+     void *buf;
+     _IO_size_t size;
+     _IO_size_t count;
+     _IO_FILE* fp;
+{
+  _IO_size_t bytes_requested = size*count;
+  _IO_size_t bytes_read;
+  CHECK_FILE (fp, 0);
+  if (bytes_requested == 0)
+    return 0;
+  bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
+  return bytes_requested == bytes_read ? count : bytes_read / size;
+}
+weak_alias (_IO_fread, fread)
diff --git a/libio/iofscanf.c b/libio/iofscanf.c
new file mode 100644
index 0000000000..512d5e515e
--- /dev/null
+++ b/libio/iofscanf.c
@@ -0,0 +1,50 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_fscanf
+#ifdef __STDC__
+  (_IO_FILE *fp, const char* format, ...)
+#else
+(fp, format, va_alist) _IO_FILE *fp; char *format; va_dcl
+#endif
+{
+  int ret;
+  va_list args;
+  CHECK_FILE (fp, EOF);
+  _IO_va_start (args, format);
+  ret = _IO_vfscanf (fp, format, args, NULL);
+  va_end (args);
+  return ret;
+}
+
+weak_alias (_IO_fscanf, fscanf)
diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c
new file mode 100644
index 0000000000..72db3b1fa0
--- /dev/null
+++ b/libio/iofsetpos.c
@@ -0,0 +1,46 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include <libioP.h>
+#include <errno.h>
+
+int
+_IO_fsetpos (fp, posp)
+     _IO_FILE* fp;
+     const _IO_fpos_t *posp;
+{
+  CHECK_FILE (fp, EOF);
+  if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
+    {
+      /*ANSI explicily requires setting errno to a positive value on failure.*/
+#ifdef EIO
+      if (errno == 0)
+	errno = EIO;
+#endif
+      return EOF;
+    }
+  return 0;
+}
+
+weak_alias (_IO_fsetpos, fsetpos)
diff --git a/libio/ioftell.c b/libio/ioftell.c
new file mode 100644
index 0000000000..8af2ce7f1f
--- /dev/null
+++ b/libio/ioftell.c
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1993, 1995 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. */
+
+#include "libioP.h"
+#include <errno.h>
+/* ANSI explicily requires setting errno to a positive value on failure. */
+
+long int
+_IO_ftell (fp)
+     _IO_FILE* fp;
+{
+  _IO_pos_t pos;
+  CHECK_FILE (fp, -1L);
+  pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
+  if (pos == _IO_pos_BAD)
+    {
+#ifdef EIO
+      if (errno == 0)
+	errno = EIO;
+#endif
+      return -1L;
+    }
+  return _IO_pos_as_off (pos);
+}
+
+weak_alias (_IO_ftell, ftell)
diff --git a/libio/iofwrite.c b/libio/iofwrite.c
new file mode 100644
index 0000000000..b8f02f2dd0
--- /dev/null
+++ b/libio/iofwrite.c
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+
+_IO_size_t
+_IO_fwrite (buf, size, count, fp)
+     const void* buf;
+     _IO_size_t size;
+     _IO_size_t count;
+     _IO_FILE *fp;
+{
+  _IO_size_t request = size*count;
+  _IO_size_t written;
+  CHECK_FILE (fp, 0);
+  if (request == 0)
+    return 0;
+  written = _IO_sputn (fp, (const char *) buf, request);
+  /* Many traditional implementations return 0 if size==0 && count > 0,
+     but ANSI seems to require us to return count in this case. */
+  if (written == request)
+    return count;
+  else
+    return written/size;
+}
+
+weak_alias (_IO_fwrite, fwrite)
diff --git a/libio/iogetdelim.c b/libio/iogetdelim.c
new file mode 100644
index 0000000000..a6894a5ae6
--- /dev/null
+++ b/libio/iogetdelim.c
@@ -0,0 +1,105 @@
+/*
+Copyright (C) 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. */
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "libioP.h"
+#include <string.h>
+#include <errno.h>
+
+/* Read up to (and including) a TERMINATOR from FP into *LINEPTR
+   (and null-terminate it).  *LINEPTR is a pointer returned from malloc (or
+   NULL), pointing to *N characters of space.  It is realloc'ed as
+   necessary.  Returns the number of characters read (not including the
+   null terminator), or -1 on error or EOF.  */
+
+_IO_ssize_t
+_IO_getdelim (lineptr, n, delimiter, fp)
+     char **lineptr;
+     _IO_size_t *n;
+      int delimiter;
+      _IO_FILE *fp;
+{
+  register _IO_ssize_t cur_len = 0;
+  _IO_ssize_t len;
+
+  if (lineptr == NULL || n == NULL)
+    {
+#ifdef EINVAL
+      errno = EINVAL;
+#endif
+      return -1;
+    }
+  CHECK_FILE (fp, -1);
+  if (_IO_ferror (fp))
+    return -1;
+
+  if (*lineptr == NULL || *n == 0)
+    {
+      *n = 120;
+      *lineptr = (char *) malloc (*n);
+      if (*lineptr == NULL)
+	return -1;
+    }
+
+  len = fp->_IO_read_end - fp->_IO_read_ptr;
+  if (len <= 0)
+    {
+      if (__underflow (fp) == EOF)
+	return -1;
+      len = fp->_IO_read_end - fp->_IO_read_ptr;
+    }
+
+  for (;;)
+    {
+      _IO_size_t needed;
+      char *t;
+      t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
+      if (t != NULL)
+	len = (t - fp->_IO_read_ptr) + 1;
+      /* make enough space for len+1 (for final NUL) bytes. */
+      needed = cur_len + len + 1;
+      if (needed > *n)
+	{
+	  if (t == NULL && needed < 2 * *n)
+	    needed = 2 * *n;  /* Be generous. */
+	  *n = needed;
+	  *lineptr = (char *) realloc (*lineptr, needed);
+	  if (*lineptr == NULL)
+	    return -1;
+	}
+      memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
+      fp->_IO_read_ptr += len;
+      cur_len += len;
+      if (t != NULL || __underflow (fp) == EOF)
+	break;
+      len = fp->_IO_read_end - fp->_IO_read_ptr;
+    }
+  lineptr[cur_len] = '\0';
+  return cur_len;
+}
+
+weak_alias (_IO_getdelim, __getdelim)
+weak_alias (_IO_getdelim, getdelim)
diff --git a/libio/iogetline.c b/libio/iogetline.c
new file mode 100644
index 0000000000..85dff7e3e7
--- /dev/null
+++ b/libio/iogetline.c
@@ -0,0 +1,74 @@
+/* 
+Copyright (C) 1993 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 <string.h>
+
+/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation.
+
+   Read chars into buf (of size n), until delim is seen.
+   Return number of chars read (at most n).
+   Does not put a terminating '\0' in buf.
+   If extract_delim < 0, leave delimiter unread.
+   If extract_delim > 0, insert delim in output. */
+
+_IO_size_t
+DEFUN(_IO_getline, (fp, buf, n, delim, extract_delim),
+      _IO_FILE *fp AND char* buf AND _IO_size_t n
+      AND int delim AND int extract_delim)
+{
+  register char *ptr = buf;
+  do
+    {
+      _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr;
+      char *t;
+      if (len <= 0)
+	if (__underflow(fp) == EOF)
+	  break;
+	else
+	  len = fp->_IO_read_end - fp->_IO_read_ptr;
+      if (len >= n)
+	len = n;
+      t = (char*)memchr((void*)fp->_IO_read_ptr, delim, len);
+      if (t != NULL)
+	{
+	  _IO_size_t old_len = ptr-buf;
+	  len = t - fp->_IO_read_ptr;
+	  if (extract_delim >= 0)
+	    {
+	      t++;
+	      if (extract_delim > 0)
+		len++;
+	    }
+	  memcpy((void*)ptr, (void*)fp->_IO_read_ptr, len);
+	  fp->_IO_read_ptr = t;
+	  return old_len + len;
+	}
+      memcpy((void*)ptr, (void*)fp->_IO_read_ptr, len);
+      fp->_IO_read_ptr += len;
+      ptr += len;
+      n -= len;
+    } while (n != 0);
+  return ptr - buf;
+}
diff --git a/libio/iogets.c b/libio/iogets.c
new file mode 100644
index 0000000000..419342fb12
--- /dev/null
+++ b/libio/iogets.c
@@ -0,0 +1,49 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include <limits.h>
+
+char*
+_IO_gets (buf)
+     char* buf;
+{
+  _IO_size_t count;
+  int ch = _IO_getc (_IO_stdin);
+  if (ch == EOF)
+    return NULL;
+  if (ch == '\n')
+    count = 0;
+  else
+    {
+      buf[0] = (char)ch;
+      count = _IO_getline (_IO_stdin, buf + 1, INT_MAX, '\n', 0) + 1;
+      if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN)
+	return NULL;
+    }
+  buf[count] = 0;
+  return buf;
+}
+
+weak_alias (_IO_gets, gets)
diff --git a/libio/iolibio.h b/libio/iolibio.h
new file mode 100644
index 0000000000..e5de77ea85
--- /dev/null
+++ b/libio/iolibio.h
@@ -0,0 +1,53 @@
+#include "libio.h"
+
+/* These emulate stdio functionality, but with a different name
+   (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int _IO_fclose __P((_IO_FILE*));
+extern _IO_FILE *_IO_fdopen __P((int, const char*));
+extern int _IO_fflush __P((_IO_FILE*));
+extern int _IO_fgetpos __P((_IO_FILE*, _IO_fpos_t*));
+extern char* _IO_fgets __P((char*, int, _IO_FILE*));
+extern _IO_FILE *_IO_fopen __P((const char*, const char*));
+extern int _IO_fprintf __P((_IO_FILE*, const char*, ...));
+extern int _IO_fputs __P((const char*, _IO_FILE*));
+extern int _IO_fsetpos __P((_IO_FILE*, const _IO_fpos_t *));
+extern long int _IO_ftell __P((_IO_FILE*));
+extern _IO_size_t _IO_fread __P((void*, _IO_size_t, _IO_size_t, _IO_FILE*));
+extern _IO_size_t _IO_fwrite __P((const void*,
+				      _IO_size_t, _IO_size_t, _IO_FILE*));
+extern char* _IO_gets __P((char*));
+extern void _IO_perror __P((const char*));
+extern int _IO_printf __P((const char*, ...));
+extern int _IO_puts __P((const char*));
+extern int _IO_scanf __P((const char*, ...));
+extern void _IO_setbuffer __P((_IO_FILE *, char*, _IO_size_t));
+extern int _IO_setvbuf __P((_IO_FILE*, char*, int, _IO_size_t));
+extern int _IO_sscanf __P((const char*, const char*, ...));
+extern int _IO_sprintf __P((char *, const char*, ...));
+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));
+#ifndef _IO_pos_BAD
+#define _IO_pos_BAD ((_IO_fpos_t)(-1))
+#endif
+#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN))
+#define _IO_fseek(__fp, __offset, __whence) \
+  (_IO_seekoff(__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD ? EOF : 0)
+#define _IO_rewind(FILE) (void)_IO_seekoff(FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT)
+#define _IO_vprintf(FORMAT, ARGS) _IO_vfprintf(_IO_stdout, FORMAT, ARGS)
+#define _IO_freopen(FILENAME, MODE, FP) \
+  (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE))
+#define _IO_fileno(FP) ((FP)->_fileno)
+extern _IO_FILE* _IO_popen __P((const char*, const char*));
+#define _IO_pclose _IO_fclose
+#define _IO_setbuf(_FP, _BUF) _IO_setbuffer(_FP, _BUF, _IO_BUFSIZ)
+#define _IO_setlinebuf(_FP) _IO_setvbuf(_FP, NULL, 1, 0)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libio/iopadn.c b/libio/iopadn.c
new file mode 100644
index 0000000000..94166a3eb1
--- /dev/null
+++ b/libio/iopadn.c
@@ -0,0 +1,65 @@
+/* 
+Copyright (C) 1993 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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"
+
+#define PADSIZE 16
+static char const blanks[PADSIZE] =
+{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+static char const zeroes[PADSIZE] =
+{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+_IO_ssize_t
+DEFUN(_IO_padn, (fp, pad, count),
+      _IO_FILE *fp AND int pad AND _IO_ssize_t count)
+{
+  char padbuf[PADSIZE];
+  const char *padptr;
+  register int i;
+  _IO_size_t written = 0, w;
+  
+  if (pad == ' ')
+    padptr = blanks;
+  else if (pad == '0')
+    padptr = zeroes;
+  else
+    {
+      for (i = PADSIZE; --i >= 0; ) padbuf[i] = pad;
+      padptr = padbuf;
+    }
+  for (i = count; i >= PADSIZE; i -= PADSIZE)
+    {
+      w = _IO_sputn(fp, padptr, PADSIZE);
+      written += w;
+      if (w != PADSIZE)
+	return written;
+    }
+      
+  if (i > 0)
+    {
+      w = _IO_sputn(fp, padptr, i);
+      written += w;
+    }
+  return written;
+}
diff --git a/libio/ioprims.c b/libio/ioprims.c
new file mode 100644
index 0000000000..d17c10a168
--- /dev/null
+++ b/libio/ioprims.c
@@ -0,0 +1,73 @@
+/*
+Copyright (C) 1993 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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. */
+
+/* I/O OS-level primitives.
+   Needs to be replaced if not using Unix.
+   Also needs to be replaced if avoiding name-space pollution
+   (in which case read would be defined in terms of _IO_read,
+   rather than vice versa). */
+
+#include "libioP.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef TODO
+/* Add open, isatty */
+#endif
+
+_IO_ssize_t
+DEFUN(_IO_read, (fildes, buf, nbyte),
+      int fildes AND void *buf AND _IO_size_t nbyte)
+{
+  return __read (fildes, buf, nbyte);
+}
+
+_IO_ssize_t
+DEFUN(_IO_write, (fildes, buf, nbyte),
+      int fildes AND const void *buf AND _IO_size_t nbyte)
+{
+  return __write (fildes, buf, nbyte);
+}
+
+_IO_off_t
+DEFUN(_IO_lseek, (fildes, offset, whence),
+      int fildes AND _IO_off_t offset AND int whence)
+{
+  return __lseek (fildes, offset, whence);
+}
+
+int
+DEFUN(_IO_close, (fildes),
+      int fildes)
+{
+  return __close (fildes);
+}
+
+int
+DEFUN(_IO_fstat, (fildes, buf),
+      int fildes AND struct stat *buf)
+{
+  return __fstat (fildes, buf);
+}
diff --git a/libio/ioputs.c b/libio/ioputs.c
new file mode 100644
index 0000000000..129da1d821
--- /dev/null
+++ b/libio/ioputs.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include <string.h>
+
+int
+_IO_puts (str)
+      const char *str;
+{
+  _IO_size_t len = strlen (str);
+  if (_IO_sputn (_IO_stdout, str, len) != len)
+    return EOF;
+  if (_IO_putc ('\n', _IO_stdout) == EOF)
+    return EOF;
+  return len+1;
+}
+weak_alias (_IO_puts, puts)
diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c
new file mode 100644
index 0000000000..1de4f7bdc9
--- /dev/null
+++ b/libio/ioseekoff.c
@@ -0,0 +1,43 @@
+/* 
+Copyright (C) 1993 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+_IO_pos_t
+DEFUN(_IO_seekoff, (fp, offset, dir, mode),
+      _IO_FILE* fp AND _IO_off_t offset AND int dir AND int mode)
+{
+  /* If we have a backup buffer, get rid of it, since the __seekoff
+     callback may not know to do the right thing about it.
+     This may be over-kill, but it'll do for now. TODO */
+
+  if (_IO_have_backup (fp))
+    {
+      if (dir == _IO_seek_cur && _IO_in_backup (fp))
+	offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+      _IO_free_backup_area (fp);
+    }
+
+  return _IO_SEEKOFF (fp, offset, dir, mode);
+}
diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c
new file mode 100644
index 0000000000..be6863370a
--- /dev/null
+++ b/libio/ioseekpos.c
@@ -0,0 +1,39 @@
+/* 
+Copyright (C) 1993 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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>
+
+_IO_pos_t
+DEFUN(_IO_seekpos, (fp, pos, mode),
+      _IO_FILE* fp AND _IO_pos_t pos AND int mode)
+{
+  /* If we have a backup buffer, get rid of it, since the __seekoff
+     callback may not know to do the right thing about it.
+     This may be over-kill, but it'll do for now. TODO */
+
+  if (_IO_have_backup (fp))
+    _IO_free_backup_area (fp);
+
+  return _IO_SEEKPOS (fp, pos, mode);
+}
diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c
new file mode 100644
index 0000000000..0ad38111d6
--- /dev/null
+++ b/libio/iosetbuffer.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+
+void
+_IO_setbuffer (fp, buf, size)
+     _IO_FILE *fp;
+     char *buf;
+     _IO_size_t size;
+{
+  CHECK_FILE (fp, );
+  fp->_flags &= ~_IO_LINE_BUF;
+  if (!buf)
+    size = 0;
+  (void) _IO_SETBUF (fp, buf, size);
+}
diff --git a/libio/iosetvbuf.c b/libio/iosetvbuf.c
new file mode 100644
index 0000000000..316179e330
--- /dev/null
+++ b/libio/iosetvbuf.c
@@ -0,0 +1,80 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+
+#define _IOFBF 0 /* Fully buffered. */
+#define _IOLBF 1 /* Line buffered. */
+#define _IONBF 2 /* No buffering. */
+
+int
+_IO_setvbuf (fp, buf, mode, size)
+     _IO_FILE* fp;
+     char* buf;
+     int mode;
+     _IO_size_t size;
+{
+  CHECK_FILE (fp, EOF);
+  switch (mode)
+    {
+    case _IOFBF:
+      fp->_IO_file_flags &= ~_IO_LINE_BUF;
+      if (buf == NULL)
+	{
+	  if (fp->_IO_buf_base == NULL)
+	    {
+	      /* There is no flag to distinguish between "fully buffered
+		 mode has been explicitly set" as opposed to "line
+		 buffering has not been explicitly set".  In both
+		 cases, _IO_LINE_BUF is off.  If this is a tty, and
+		 _IO_filedoalloc later gets called, it cannot know if
+		 it should set the _IO_LINE_BUF flag (because that is
+		 the default), or not (because we have explicitly asked
+		 for fully buffered mode).  So we make sure a buffer
+		 gets allocated now, and explicitly turn off line
+		 buffering.
+
+		 A possibly cleaner alternative would be to add an
+		 extra flag, but then flags are a finite resource.  */
+	      if (_IO_DOALLOCATE (fp) < 0)
+		return EOF;
+	      fp->_IO_file_flags &= ~_IO_LINE_BUF;
+	    }
+	  return 0;
+	}
+      break;
+    case _IOLBF:
+      fp->_IO_file_flags |= _IO_LINE_BUF;
+      if (buf == NULL)
+	return 0;
+      break;
+    case _IONBF:
+      buf = NULL;
+      size = 0;
+      break;
+    default:
+      return EOF;
+    }
+  return _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;
+}
diff --git a/libio/iosprintf.c b/libio/iosprintf.c
new file mode 100644
index 0000000000..b873eb4455
--- /dev/null
+++ b/libio/iosprintf.c
@@ -0,0 +1,47 @@
+/* 
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+_IO_sprintf
+#ifdef __STDC__
+  (char *string, const char* format, ...)
+#else
+(string, format, va_alist) char *string; char *format; va_dcl
+#endif
+{
+  int ret;
+  va_list args;
+  _IO_va_start(args, format);
+  ret = _IO_vsprintf(string, format, args);
+  va_end(args);
+  return ret;
+}
diff --git a/libio/ioungetc.c b/libio/ioungetc.c
new file mode 100644
index 0000000000..1a6988ef16
--- /dev/null
+++ b/libio/ioungetc.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+
+int
+_IO_ungetc (c, fp)
+     int c;
+     _IO_FILE *fp;
+{
+  CHECK_FILE (fp, EOF);
+  if (c == EOF)
+    return EOF;
+  return _IO_sputbackc (fp, (unsigned char) c);
+}
+
+weak_alias (_IO_ungetc, ungetc)
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
new file mode 100644
index 0000000000..182c4ff306
--- /dev/null
+++ b/libio/iovsprintf.c
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+int
+_IO_vsprintf (string, format, args)
+     char *string;
+     const char *format;
+      _IO_va_list args;
+{
+  _IO_strfile sf;
+  int ret;
+  _IO_init ((_IO_FILE *) &sf, 0);
+  _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_str_jumps;
+  _IO_str_init_static ((_IO_FILE *) &sf, string, -1, string);
+  ret = _IO_vfprintf ((_IO_FILE *) &sf, format, args);
+  _IO_putc('\0', (_IO_FILE *) &sf);
+  return ret;
+}
+
+weak_alias (_IO_vsprintf, vsprintf)
diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c
new file mode 100644
index 0000000000..61eeed2f3e
--- /dev/null
+++ b/libio/iovsscanf.c
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1993 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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"
+
+int
+DEFUN(_IO_vsscanf, (string, format, args),
+      const char *string AND const char *format AND _IO_va_list args)
+{
+  _IO_strfile sf;
+  _IO_init((_IO_FILE*)&sf, 0);
+  _IO_JUMPS((_IO_FILE*)&sf) = &_IO_str_jumps;
+  _IO_str_init_static ((_IO_FILE*)&sf, (char*)string, 0, NULL);
+  return _IO_vfscanf((_IO_FILE*)&sf, format, args, NULL);
+}
+weak_alias (_IO_vsscanf, vsscanf)
diff --git a/libio/libio.h b/libio/libio.h
new file mode 100644
index 0000000000..405036dfb6
--- /dev/null
+++ b/libio/libio.h
@@ -0,0 +1,272 @@
+/*
+Copyright (C) 1991, 1992, 1993, 1994, 1995 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. */
+
+#ifndef _IO_STDIO_H
+#define _IO_STDIO_H
+
+#include <_G_config.h>
+#define _IO_pos_t _G_fpos_t /* obsolete */
+#define _IO_fpos_t _G_fpos_t
+#define _IO_size_t _G_size_t
+#define _IO_ssize_t _G_ssize_t
+#define _IO_off_t _G_off_t
+#define _IO_pid_t _G_pid_t
+#define _IO_uid_t _G_uid_t
+#define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT
+#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE
+#define _IO_BUFSIZ _G_BUFSIZ
+#define _IO_va_list _G_va_list
+
+#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 */
+#endif
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(protos) protos
+#else
+#define __P(protos) ()
+#endif
+#endif /*!__P*/
+
+/* For backward compatibility */
+#ifndef _PARAMS
+#define _PARAMS(protos) __P(protos)
+#endif /*!_PARAMS*/
+
+#ifndef __STDC__
+#define const
+#endif
+#define _IO_UNIFIED_JUMPTABLES 1
+
+#if 0
+#ifdef _IO_NEED_STDARG_H
+#include <stdarg.h>
+#endif
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef NULL
+#if !defined(__cplusplus) || defined(__GNUC__)
+#define NULL ((void*)0)
+#else
+#define NULL (0)
+#endif
+#endif
+
+#define _IOS_INPUT	1
+#define _IOS_OUTPUT	2
+#define _IOS_ATEND	4
+#define _IOS_APPEND	8
+#define _IOS_TRUNC	16
+#define _IOS_NOCREATE	32
+#define _IOS_NOREPLACE	64
+#define _IOS_BIN	128
+
+/* 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.
+   Note: The magic numbers must all be negative if stdio
+   emulation is desired. */
+
+#define _IO_MAGIC 0xFBAD0000 /* Magic number */
+#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
+#define _IO_MAGIC_MASK 0xFFFF0000
+#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */
+#define _IO_UNBUFFERED 2
+#define _IO_NO_READS 4 /* Reading not allowed */
+#define _IO_NO_WRITES 8 /* Writing not allowd */
+#define _IO_EOF_SEEN 0x10
+#define _IO_ERR_SEEN 0x20
+#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */
+#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/
+#define _IO_IN_BACKUP 0x100
+#define _IO_LINE_BUF 0x200
+#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */
+#define _IO_CURRENTLY_PUTTING 0x800
+#define _IO_IS_APPENDING 0x1000
+#define _IO_IS_FILEBUF 0x2000
+
+/* These are "formatting flags" matching the iostream fmtflags enum values. */
+#define _IO_SKIPWS 01
+#define _IO_LEFT 02
+#define _IO_RIGHT 04
+#define _IO_INTERNAL 010
+#define _IO_DEC 020
+#define _IO_OCT 040
+#define _IO_HEX 0100
+#define _IO_SHOWBASE 0200
+#define _IO_SHOWPOINT 0400
+#define _IO_UPPERCASE 01000
+#define _IO_SHOWPOS 02000
+#define _IO_SCIENTIFIC 04000
+#define _IO_FIXED 010000
+#define _IO_UNITBUF 020000
+#define _IO_STDIO 040000
+#define _IO_DONT_CLOSE 0100000
+
+
+struct _IO_jump_t;  struct _IO_FILE;
+
+/* 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;
+
+
+/* The reentrant version of the libio implementation needs a semaphore for
+   each _IO_FILE struture.  Because we don't know how the semaphore
+   will be implemented we try to be very general.  */
+struct _IO_lock_t {
+  void *ptr;
+  short int field1;
+  short int field2;
+};
+
+/* A streammarker remembers a position in a buffer. */
+
+struct _IO_marker {
+  struct _IO_marker *_next;
+  struct _IO_FILE *_sbuf;
+  /* If _pos >= 0
+ it points to _buf->Gbase()+_pos. FIXME comment */
+  /* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */
+  int _pos;
+#if 0
+    void set_streampos(streampos sp) { _spos = sp; }
+    void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); }
+  public:
+    streammarker(streambuf *sb);
+    ~streammarker();
+    int saving() { return  _spos == -2; }
+    int delta(streammarker&);
+    int delta();
+#endif
+};
+
+struct _IO_FILE {
+  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. */
+  char* _IO_read_ptr;	/* Current read pointer */
+  char* _IO_read_end;	/* End of get area. */
+  char* _IO_read_base;	/* Start of putback+get area. */
+  char* _IO_write_base;	/* Start of put area. */
+  char* _IO_write_ptr;	/* Current put pointer. */
+  char* _IO_write_end;	/* End of put area. */
+  char* _IO_buf_base;	/* Start of reserve area. */
+  char* _IO_buf_end;	/* End of reserve area. */
+  /* The following fields are used to support backing up and undo. */
+  char *_IO_save_base; /* Pointer to start of non-current get area. */
+  char *_IO_backup_base;  /* Pointer to first valid character of backup area */
+  char *_IO_save_end; /* Pointer to end of non-current get area. */
+
+  struct _IO_marker *_markers;
+
+  struct _IO_FILE *_chain;
+
+#if  !_IO_UNIFIED_JUMPTABLES
+  struct _IO_jump_t *_jumps; /* Jump table */
+#endif
+
+  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; */
+
+  struct _IO_lock_t _IO_lock;
+};
+
+#ifndef __cplusplus
+typedef struct _IO_FILE _IO_FILE;
+#endif
+
+struct _IO_FILE_plus;
+extern struct _IO_FILE_plus _IO_stdin_, _IO_stdout_, _IO_stderr_;
+#define _IO_stdin ((_IO_FILE*)(&_IO_stdin_))
+#define _IO_stdout ((_IO_FILE*)(&_IO_stdout_))
+#define _IO_stderr ((_IO_FILE*)(&_IO_stderr_))
+
+#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) \
+       ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end \
+	  && __underflow(_fp) == EOF ? EOF \
+	: *(unsigned char*)(_fp)->_IO_read_ptr)
+
+#define _IO_putc(_ch, _fp) \
+   (((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \
+    ? __overflow(_fp, (unsigned char)(_ch)) \
+    : (unsigned char)(*(_fp)->_IO_write_ptr++ = (_ch)))
+
+#define _IO_feof(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
+#define _IO_ferror(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
+
+/* 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_free_backup_area __P((_IO_FILE*));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IO_STDIO_H */
diff --git a/libio/libioP.h b/libio/libioP.h
new file mode 100644
index 0000000000..a955151ade
--- /dev/null
+++ b/libio/libioP.h
@@ -0,0 +1,397 @@
+/*
+Copyright (C) 1993 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. */
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#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
+
+#define _IO_seek_set 0
+#define _IO_seek_cur 1
+#define _IO_seek_end 2
+
+typedef int (*_IO_overflow_t) __P((_IO_FILE*, int));
+typedef int (*_IO_underflow_t) __P((_IO_FILE*));
+typedef _IO_size_t (*_IO_xsputn_t) __P((_IO_FILE*,const void*,_IO_size_t));
+typedef _IO_size_t (*_IO_xsgetn_t) __P((_IO_FILE*, void*, _IO_size_t));
+typedef _IO_ssize_t (*_IO_read_t) __P((_IO_FILE*, void*, _IO_ssize_t));
+typedef _IO_ssize_t (*_IO_write_t) __P((_IO_FILE*,const void*,_IO_ssize_t));
+typedef int (*_IO_stat_t) __P((_IO_FILE*, void*));
+typedef _IO_fpos_t (*_IO_seek_t) __P((_IO_FILE*, _IO_off_t, int));
+typedef int (*_IO_doallocate_t) __P((_IO_FILE*));
+typedef int (*_IO_pbackfail_t) __P((_IO_FILE*, int));
+typedef _IO_FILE* (*_IO_setbuf_t) __P((_IO_FILE*, char *, _IO_ssize_t));
+typedef int (*_IO_sync_t) __P((_IO_FILE*));
+typedef void (*_IO_finish_t) __P((_IO_FILE*)); /* finalize */
+typedef int (*_IO_close_t) __P((_IO_FILE*)); /* finalize */
+typedef _IO_fpos_t (*_IO_seekoff_t) __P((_IO_FILE*, _IO_off_t, int, int));
+
+/* 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));
+
+#if  !_IO_UNIFIED_JUMPTABLES
+#define _IO_JUMPS(THIS) (THIS)->_jumps
+#else
+#define _IO_JUMPS(THIS) ((struct _IO_FILE_plus*)(THIS))->vtable
+#endif
+
+#if  !_IO_UNIFIED_JUMPTABLES
+#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
+#else
+#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}
+#endif
+#define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0)
+
+#define _IO_FINISH(FP) JUMP0(__finish, FP)
+#define _IO_OVERFLOW(FP, CH) JUMP1(__overflow, FP, CH)
+#define _IO_UNDERFLOW(FP) JUMP0(__underflow, FP)
+#define _IO_UFLOW(FP) JUMP0(__uflow, FP)
+#define _IO_PBACKFAIL(FP, CH) JUMP1(__pbackfail, FP, CH)
+#define _IO_XSPUTN(FP, DATA, N) JUMP2(__xsputn, FP, DATA, N)
+#define _IO_XSGETN(FP, DATA, N) JUMP2(__xsgetn, FP, DATA, N)
+#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3(__seekoff, FP, OFF, DIR, MODE)
+#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2(__seekpos, FP, POS, FLAGS)
+#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2(__setbuf, FP, BUFFER, LENGTH)
+#define _IO_SYNC(FP) JUMP0(__sync, FP)
+#define _IO_DOALLOCATE(FP) JUMP0(__doallocate, FP)
+#define _IO_SYSREAD(FP, DATA, LEN) JUMP2(__read, FP, DATA, LEN)
+#define _IO_SYSWRITE(FP, DATA, LEN) JUMP2(__write, FP, DATA, LEN)
+#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2(__seek, FP, OFFSET, MODE)
+#define _IO_SYSCLOSE(FP) JUMP0(__close, FP)
+#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 {
+    JUMP_FIELD(_G_size_t, __dummy);
+    JUMP_FIELD(_IO_finish_t, __finish);
+    JUMP_FIELD(_IO_overflow_t, __overflow);
+    JUMP_FIELD(_IO_underflow_t, __underflow);
+    JUMP_FIELD(_IO_underflow_t, __uflow);
+    JUMP_FIELD(_IO_pbackfail_t, __pbackfail);
+    /* showmany */
+    JUMP_FIELD(_IO_xsputn_t, __xsputn);
+    JUMP_FIELD(_IO_xsgetn_t, __xsgetn);
+    JUMP_FIELD(_IO_seekoff_t, __seekoff);
+    JUMP_FIELD(_IO_seekpos_t, __seekpos);
+    JUMP_FIELD(_IO_setbuf_t, __setbuf);
+    JUMP_FIELD(_IO_sync_t, __sync);
+    JUMP_FIELD(_IO_doallocate_t, __doallocate);
+    JUMP_FIELD(_IO_read_t, __read);
+    JUMP_FIELD(_IO_write_t, __write);
+    JUMP_FIELD(_IO_seek_t, __seek);
+    JUMP_FIELD(_IO_close_t, __close);
+    JUMP_FIELD(_IO_stat_t, __stat);
+#if 0
+    get_column;
+    set_column;
+#endif
+};
+
+/* We always allocate an extra word following an _IO_FILE.
+   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 {
+  _IO_FILE file;
+#if _IO_UNIFIED_JUMPTABLES
+  const struct _IO_jump_t *vtable;
+#else
+  const void *vtable;
+#endif
+};
+
+/* Generic functions */
+
+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 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));
+
+/* 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 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));
+
+#define _IO_do_flush(_f) \
+  _IO_do_write(_f, (_f)->_IO_write_base, \
+	       (_f)->_IO_write_ptr-(_f)->_IO_write_base)
+#define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING)
+#define _IO_mask_flags(fp, f, mask) \
+       ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask)))
+#define _IO_setg(fp, eb, g, eg)  ((fp)->_IO_read_base = (eb),\
+	(fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg))
+#define _IO_setp(__fp, __p, __ep) \
+       ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr = __p, (__fp)->_IO_write_end = (__ep))
+#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
+#define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
+#define _IO_have_markers(fp) ((fp)->_markers != NULL)
+#define _IO_blen(p) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
+
+/* 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));
+#define _IO_file_is_open(__fp) ((__fp)->_fileno >= 0)
+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*));
+
+/* Other file functions. */
+extern _IO_FILE* _IO_file_attach __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*));
+
+/* 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 void _IO_str_finish __P ((_IO_FILE*));
+
+/* 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 _IO_FILE *_IO_list_all;
+extern void (*_IO_cleanup_registration_needed) __P ((void));
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef NULL
+#if !defined(__cplusplus) || defined(__GNUC__)
+#define NULL ((void*)0)
+#else
+#define NULL (0)
+#endif
+#endif
+
+#define FREE_BUF(_B) free(_B)
+#define ALLOC_BUF(_S) (char*)malloc(_S)
+
+#ifndef OS_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 *));
+
+/* Operations on _IO_fpos_t.
+   Normally, these are trivial, but we provide hooks for configurations
+   where an _IO_fpos_t is a struct.
+   Note that _IO_off_t must be an integral type. */
+
+/* _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))
+#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))
+#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))
+#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)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#if  _IO_UNIFIED_JUMPTABLES
+#define _IO_FJUMP /* nothing */
+#else
+#define _IO_FJUMP &_IO_file_jumps,
+#endif
+/* 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, _IO_FJUMP FD}
+
+/* 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) \
+  extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CNLENGTH #CLASS);
+#else
+#define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
+  extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CLASS);
+#endif
+#endif /* __GNUC__ */
+
+#if !defined(builtinbuf_vtable) && defined(__cplusplus)
+#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
+#endif /* !defined(builtinbuf_vtable) && defined(__cplusplus) */
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define _IO_va_start(args, last) va_start(args, last)
+#else
+#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 */
+#else
+/* This is part of the kludge for binary compatibility with old stdio. */
+#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
+#else
+#define MAYBE_SET_EINVAL /* nothing */
+#endif
+
+#ifdef 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; }}
+#else
+#define CHECK_FILE(FILE,RET) \
+	COERCE_FILE(FILE)
+#endif
diff --git a/libio/memstream.c b/libio/memstream.c
new file mode 100644
index 0000000000..b1cefb0959
--- /dev/null
+++ b/libio/memstream.c
@@ -0,0 +1,129 @@
+/* Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "strfile.h"
+#include "libioP.h"
+#include <stdlib.h>
+
+
+struct _IO_FILE_memstream
+{
+  _IO_strfile _sf;
+  char **bufloc;
+  _IO_size_t *sizeloc;
+};
+
+
+static int _IO_mem_sync __P ((_IO_FILE* fp));
+static int _IO_mem_close __P ((_IO_FILE* fp));
+
+
+static const struct _IO_jump_t _IO_mem_jumps =
+{
+  JUMP_INIT_DUMMY,
+  JUMP_INIT (finish, _IO_str_finish),
+  JUMP_INIT (overflow, _IO_str_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_mem_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_mem_close),
+  JUMP_INIT (stat, _IO_default_stat)
+};
+
+/* Open a stream that writes into a malloc'd buffer that is expanded as
+   necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
+   and the number of characters written on fflush or fclose.  */
+_IO_FILE *
+open_memstream (bufloc, sizeloc)
+     char **bufloc;
+     _IO_size_t *sizeloc;
+{
+  struct _IO_FILE_memstream *fp;
+  char *buf;
+
+  fp = (struct _IO_FILE_memstream *)
+    malloc (sizeof (struct _IO_FILE_memstream));
+  if (fp == NULL)
+    return NULL;
+
+  buf = ALLOC_BUF (_IO_BUFSIZ);
+  _IO_init (&fp->_sf._f, 0);
+  _IO_JUMPS (&fp->_sf._f) = &_IO_mem_jumps;
+  _IO_str_init_static (&fp->_sf._f, buf, _IO_BUFSIZ, buf);
+  fp->_sf._f._flags &= ~_IO_USER_BUF;
+  fp->_sf._s._allocate_buffer = (_IO_alloc_type) malloc;
+  fp->_sf._s._free_buffer = (_IO_free_type) free;
+
+  return &fp->_sf._f;
+}
+
+
+static int
+_IO_mem_sync (fp)
+     _IO_FILE* fp;
+{
+  struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
+  int res;
+
+  res = _IO_default_sync (fp);
+  if (res < 0)
+    return res;
+
+  if (fp->_IO_write_ptr == fp->_IO_write_end)
+    {
+      _IO_str_overflow (fp, '\0');
+      --fp->_IO_write_ptr;
+    }
+  else
+    *fp->_IO_write_ptr = '\0';
+
+  *mp->bufloc = fp->_IO_buf_base;
+  *mp->sizeloc = _IO_blen (fp);
+
+  return 0;
+}
+
+
+static int _IO_mem_close (fp)
+     _IO_FILE* fp;
+{
+  struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
+  int res;
+
+  res = _IO_default_close (fp);
+  if (res < 0)
+    return res;
+
+  *mp->bufloc = (char *) realloc (fp->_IO_buf_base, _IO_blen (fp) + 1);
+  if (*mp->bufloc == NULL)
+    return -1;
+  (*mp->bufloc)[_IO_blen (fp)] = '\0';
+  *mp->sizeloc = _IO_blen (fp);
+
+  return 0;
+}
diff --git a/libio/putc.c b/libio/putc.c
new file mode 100644
index 0000000000..675fe5eedf
--- /dev/null
+++ b/libio/putc.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1991, 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef putc
+
+int
+putc (c, stream)
+     int c;
+     _IO_FILE *stream;
+{
+  return _IO_putc (c, stream);
+}
diff --git a/libio/putchar.c b/libio/putchar.c
new file mode 100644
index 0000000000..bf10da9468
--- /dev/null
+++ b/libio/putchar.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991, 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef putchar
+
+int
+putchar (c)
+     int c;
+{
+  return _IO_putc (c, stdout);
+}
diff --git a/libio/rewind.c b/libio/rewind.c
new file mode 100644
index 0000000000..dfb02cc3f2
--- /dev/null
+++ b/libio/rewind.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1993 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. */
+
+#include "stdio.h"
+#include "libioP.h"
+
+void
+rewind (fp)
+     _IO_FILE* fp;
+{
+  CHECK_FILE (fp, );
+  _IO_rewind (fp);
+}
diff --git a/libio/setbuf.c b/libio/setbuf.c
new file mode 100644
index 0000000000..f3518aadad
--- /dev/null
+++ b/libio/setbuf.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1993 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 "stdio.h"
+
+void
+setbuf (fp, buf)
+     _IO_FILE *fp;
+     char *buf;
+{
+  _IO_setbuffer (fp, buf, _IO_BUFSIZ);
+}
diff --git a/libio/setlinebuf.c b/libio/setlinebuf.c
new file mode 100644
index 0000000000..b456d5846c
--- /dev/null
+++ b/libio/setlinebuf.c
@@ -0,0 +1,35 @@
+/*
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef setlinebuf
+
+void
+setlinebuf (stream)
+     _IO_FILE *stream;
+{
+  _IO_setvbuf (stream, NULL, 1, 0);
+}
diff --git a/libio/stdfiles.c b/libio/stdfiles.c
new file mode 100644
index 0000000000..1d0ef85be9
--- /dev/null
+++ b/libio/stdfiles.c
@@ -0,0 +1,44 @@
+/* 
+Copyright (C) 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 file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
+   for C code.  Compare stdstreams.cc.
+   (The difference is that here the vtable field is set to 0,
+   so the objects defined are not valid C++ objects.  On the other
+   hand, we don't need a C++ compiler to build this file.) */
+
+#include "libioP.h"
+
+
+#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+  struct _IO_FILE_plus NAME \
+    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps}
+
+DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
+DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_.file, _IO_NO_READS);
+DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_.file,
+            _IO_NO_READS+_IO_UNBUFFERED);
+
+_IO_FILE *_IO_list_all = &_IO_stderr_.file;
diff --git a/libio/stdio.c b/libio/stdio.c
new file mode 100644
index 0000000000..cd56dba307
--- /dev/null
+++ b/libio/stdio.c
@@ -0,0 +1,12 @@
+#include "libioP.h"
+#include "stdio.h"
+
+/* Define non-macro versions of stdin/stdout/stderr,
+ * for use by debuggers. */
+
+#undef stdin
+#undef stdout
+#undef stderr
+FILE* stdin = &_IO_stdin_.file;
+FILE* stdout = &_IO_stdout_.file;
+FILE* stderr = &_IO_stderr_.file;
diff --git a/libio/stdio.h b/libio/stdio.h
new file mode 100644
index 0000000000..893e7bf3fe
--- /dev/null
+++ b/libio/stdio.h
@@ -0,0 +1,196 @@
+/* This is part of the iostream/stdio library, providing -*- C -*- I/O.
+   Define ANSI C stdio on top of C++ iostreams.
+   Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+ *	ANSI Standard: 4.9 INPUT/OUTPUT <stdio.h>
+ */
+
+#ifndef _STDIO_H
+#define _STDIO_H
+#define _STDIO_USES_IOSTREAM
+
+#include <libio.h>
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL (void*)0
+#endif
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+#define _IOFBF 0 /* Fully buffered. */
+#define _IOLBF 1 /* Line buffered. */
+#define _IONBF 2 /* No buffering. */
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+ /* define size_t.  Crud in case <sys/types.h> has defined it. */
+#if !defined(_SIZE_T) && !defined(_T_SIZE_) && !defined(_T_SIZE)
+#if !defined(__SIZE_T) && !defined(_SIZE_T_) && !defined(___int_size_t_h)
+#if !defined(_GCC_SIZE_T) && !defined(_SIZET_)
+#define _SIZE_T
+#define _T_SIZE_
+#define _T_SIZE
+#define __SIZE_T
+#define _SIZE_T_
+#define ___int_size_t_h
+#define _GCC_SIZE_T
+#define _SIZET_
+typedef _IO_size_t size_t;
+#endif
+#endif
+#endif
+
+typedef struct _IO_FILE FILE;
+typedef _IO_fpos_t fpos_t;
+
+#define FOPEN_MAX     _G_FOPEN_MAX
+#define FILENAME_MAX _G_FILENAME_MAX
+#define TMP_MAX 999 /* Only limited by filename length */
+
+#define L_ctermid     9
+#define L_cuserid     9
+#define P_tmpdir      "/tmp"
+#define L_tmpnam      20
+
+/* For use by debuggers. These are linked in if printf or fprintf are used. */
+extern FILE *stdin, *stdout, *stderr; /* TODO */
+
+#define stdin _IO_stdin
+#define stdout _IO_stdout
+#define stderr _IO_stderr
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __P
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif /*!__P*/
+
+extern void clearerr __P ((FILE*));
+extern int fclose __P ((FILE*));
+extern int feof __P ((FILE*));
+extern int ferror __P ((FILE*));
+extern int fflush __P ((FILE*));
+extern int fgetc __P ((FILE *));
+extern int fgetpos __P ((FILE* fp, fpos_t *pos));
+extern char* fgets __P ((char*, int, FILE*));
+extern FILE* fopen __P ((__const char*, __const char*));
+extern int fprintf __P ((FILE*, __const char* format, ...));
+extern int fputc __P ((int, FILE*));
+extern int fputs __P ((__const char *str, FILE *fp));
+extern size_t fread __P ((void*, size_t, size_t, FILE*));
+extern FILE* freopen __P ((__const char*, __const char*, FILE*));
+extern int fscanf __P ((FILE *fp, __const char* format, ...));
+extern int fseek __P ((FILE* fp, long int offset, int whence));
+extern int fsetpos __P ((FILE* fp, __const fpos_t *pos));
+extern long int ftell __P ((FILE* fp));
+extern size_t fwrite __P ((__const void*, size_t, size_t, FILE*));
+extern int getc __P ((FILE *));
+extern int getchar __P ((void));
+extern char* gets __P ((char*));
+extern void perror __P ((__const char *));
+extern int printf __P ((__const char* format, ...));
+extern int putc __P ((int, FILE *));
+extern int putchar __P ((int));
+extern int puts __P ((__const char *str));
+extern int remove __P ((__const char*));
+extern int rename __P ((__const char* _old, __const char* _new));
+extern void rewind __P ((FILE*));
+extern int scanf __P ((__const char* format, ...));
+extern void setbuf __P ((FILE*, char*));
+extern void setlinebuf __P ((FILE*));
+extern void setbuffer __P ((FILE*, char*, int));
+extern int setvbuf __P ((FILE*, char*, int mode, size_t size));
+extern int sprintf __P ((char*, __const char* format, ...));
+extern int sscanf __P ((__const char* string, __const char* format, ...));
+extern FILE* tmpfile __P ((void));
+extern char* tmpnam __P ((char*));
+extern int ungetc __P ((int c, FILE* fp));
+extern int vfprintf __P ((FILE *fp, char __const *fmt0, _G_va_list));
+extern int vprintf __P ((char __const *fmt, _G_va_list));
+extern int vsprintf __P ((char* string, __const char* format, _G_va_list));
+
+#ifndef __STRICT_ANSI__
+extern int dprintf __P ((int, __const char *, ...));
+extern int vdprintf __P ((int, __const char *, _G_va_list));
+extern int vfscanf __P ((FILE*, __const char *, _G_va_list));
+extern int vscanf __P ((__const char *, _G_va_list));
+extern int vsscanf __P ((__const char *, __const char *, _G_va_list));
+#endif
+
+#if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE)
+extern FILE *fdopen __P ((int, __const char *));
+extern int fileno __P ((FILE*));
+extern FILE* popen __P ((__const char*, __const char*));
+extern int pclose __P ((FILE*));
+#endif
+
+#ifdef __USE_GNU
+extern _IO_ssize_t getdelim __P ((char **, size_t *, int, FILE*));
+extern _IO_ssize_t getline __P ((char **, size_t *, FILE *));
+
+extern int snprintf __P ((char *, size_t, __const char *, ...));
+extern int __snprintf __P ((char *, size_t, __const char *, ...));
+extern int vsnprintf __P ((char *, size_t, __const char *, _G_va_list));
+
+/* Open a stream that writes into a malloc'd buffer that is expanded as
+   necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
+   and the number of characters written on fflush or fclose.  */
+extern FILE *open_memstream __P ((char **__bufloc, size_t *__sizeloc));
+#endif
+
+extern int __underflow __P ((struct _IO_FILE*));
+extern int __overflow __P ((struct _IO_FILE*, int));
+
+#define getc(fp) _IO_getc (fp)
+#define putc(c, fp) _IO_putc (c, fp)
+#define putchar(c) putc (c, stdout)
+#define getchar() getc (stdin)
+
+#ifdef  __USE_BSD
+extern int sys_nerr;
+extern const char *const sys_errlist[];
+#endif
+#ifdef  __USE_GNU
+extern int _sys_nerr;
+extern const char *const _sys_errlist[];
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_STDIO_H */
diff --git a/libio/strfile.h b/libio/strfile.h
new file mode 100644
index 0000000000..55783bb5c1
--- /dev/null
+++ b/libio/strfile.h
@@ -0,0 +1,46 @@
+/* 
+Copyright (C) 1993 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. */
+
+#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*));
+
+struct _IO_str_fields
+{
+  /* The current length is max(_len, _IO_write_ptr-_IO_write_base). */
+  _IO_size_t _len;
+  _IO_alloc_type _allocate_buffer;
+  _IO_free_type _free_buffer;
+};
+
+typedef struct _IO_strfile_
+{
+  struct _IO_FILE _f;
+  const void *_vtable;
+  struct _IO_str_fields _s;
+} _IO_strfile;
diff --git a/libio/strops.c b/libio/strops.c
new file mode 100644
index 0000000000..f4f45259fb
--- /dev/null
+++ b/libio/strops.c
@@ -0,0 +1,285 @@
+/* 
+Copyright (C) 1993 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. */
+
+#include "strfile.h"
+#include "libioP.h"
+#include <string.h>
+
+#define LEN(fp) (((_IO_strfile*)(fp))->_s._len)
+
+#ifdef TODO
+/* An "unbounded buffer" is when a buffer is supplied, but with no
+   specified length.  An example is the buffer argument to sprintf.
+   */
+#endif
+
+void
+DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
+      _IO_FILE *fp AND char *ptr AND int size AND char *pstart)
+{
+  if (size == 0)
+    size = strlen(ptr);
+  else if (size < 0)
+    {
+      /* If size is negative 'the characters are assumed to
+	 continue indefinitely.'  This is kind of messy ... */
+#if 1
+      int s;
+      size = 512;
+      /* Try increasing powers of 2, as long as we don't wrap around.
+	 This can lose in pathological cases (ptr near the end
+	 of the address space).  A better solution might be to
+	 adjust the size on underflow/overflow.  FIXME. */
+      for (s; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
+	size = s;
+      size = s;
+#else
+      /* The following semi-portable kludge assumes that
+	 sizeof(unsigned long) == sizeof(char*). Hence,
+	 (unsigned long)(-1) should be the largest possible address. */
+      unsigned long highest = (unsigned long)(-1);
+      /* Pointers are signed on some brain-damaged systems, in
+	 which case we divide by two to get the maximum signed address. */
+      if  ((char*)highest < ptr)
+	highest >>= 1;
+      size = (char*)highest - ptr;
+#endif
+    }
+  _IO_setb(fp, ptr, ptr+size, 0);
+
+  fp->_IO_write_base = ptr;
+  fp->_IO_read_base = ptr;
+  fp->_IO_read_ptr = ptr;
+  if (pstart)
+    {
+      fp->_IO_write_ptr = pstart;
+      fp->_IO_write_end = ptr+size;
+      fp->_IO_read_end = pstart;
+    }
+  else
+    {
+      fp->_IO_write_ptr = ptr;
+      fp->_IO_write_end = ptr;
+      fp->_IO_read_end = ptr+size;
+    }
+  LEN(fp) = size;
+  /* A null _allocate_buffer function flags the strfile as being static. */
+  (((_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_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)
+{
+  int flush_only = c == EOF;
+  _IO_size_t pos = fp->_IO_write_ptr - fp->_IO_write_base;
+  _IO_size_t get_pos = fp->_IO_read_ptr - fp->_IO_read_base;
+  if (fp->_flags & _IO_NO_WRITES)
+      return flush_only ? 0 : EOF;
+  if (pos > LEN(fp)) LEN(fp) = pos;
+  if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
+    {
+      pos = get_pos;
+      fp->_flags |= _IO_CURRENTLY_PUTTING;
+      get_pos = LEN(fp);
+    }
+  if (pos >= _IO_blen(fp) + flush_only)
+    {
+      if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
+	{
+#ifdef TODO
+	  if (indefinite size)
+	    {
+	      fp->_IO_buf_end += 512;
+	    }
+	  else
+#endif
+	  return EOF;
+	}
+      else
+	{
+	  char *new_buf;
+	  _IO_size_t new_size = 2 * _IO_blen(fp);
+	  new_buf
+	    = (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
+	  if (new_buf == NULL)
+	    {
+	      /*	  __ferror(fp) = 1; */
+	      return EOF;
+	    }
+	  memcpy(new_buf, fp->_IO_buf_base, _IO_blen(fp));
+#if 0
+	  if (lenp == &LEN(fp)) /* use '\0'-filling */
+	      memset(new_buf + pos, 0, blen() - pos);
+#endif
+	  if (fp->_IO_buf_base)
+	    {
+	      (*((_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;
+	    }
+	  _IO_setb(fp, new_buf, new_buf + new_size, 1);
+	  fp->_IO_write_base = new_buf;
+	}
+      fp->_IO_write_end = fp->_IO_buf_end;
+    }
+
+  fp->_IO_write_ptr = fp->_IO_buf_base + pos;
+
+  fp->_IO_read_base = fp->_IO_buf_base;
+  fp->_IO_read_ptr = fp->_IO_buf_base + get_pos;
+  fp->_IO_read_end = fp->_IO_buf_base + LEN(fp);
+
+  if (!flush_only)
+    *fp->_IO_write_ptr++ = (unsigned char) c;
+  return c;
+}
+
+int
+DEFUN(_IO_str_underflow, (fp),
+      register _IO_FILE* fp)
+{
+  _IO_size_t ppos = fp->_IO_write_ptr - fp->_IO_write_base;
+  if (ppos > LEN(fp)) LEN(fp) = ppos;
+  if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
+    {
+      fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+      fp->_IO_write_ptr = fp->_IO_write_end;
+    }
+  fp->_IO_read_end = fp->_IO_read_base + LEN(fp);
+  if (fp->_IO_read_ptr < fp->_IO_read_end)
+    return *fp->_IO_read_ptr;
+  else
+    return EOF;
+}
+
+_IO_ssize_t
+DEFUN(_IO_str_count, (fp),
+      register _IO_FILE *fp)
+{
+  _IO_ssize_t put_len = fp->_IO_write_ptr - fp->_IO_write_base;
+  if (put_len < LEN(fp))
+    put_len = LEN(fp);
+  return put_len;
+}     
+
+_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_ssize_t cur_size = _IO_str_count(fp);
+  _IO_pos_t new_pos = EOF;
+
+  /* Move the get pointer, if requested. */
+  if (mode & _IOS_INPUT)
+    {
+      switch (dir)
+	{
+	case _IO_seek_end:
+	  offset += cur_size;
+	  break;
+	case _IO_seek_cur:
+	  offset += fp->_IO_read_ptr - fp->_IO_read_base;
+	  break;
+	default: /* case _IO_seek_set: */
+	  break;
+	}
+      if (offset < 0 || (_IO_size_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;
+      new_pos = offset;
+    }
+
+  /* Move the put pointer, if requested. */
+  if (mode & _IOS_OUTPUT)
+    {
+      switch (dir)
+	{
+	case _IO_seek_end:
+	  offset += cur_size;
+	  break;
+	case _IO_seek_cur:
+	  offset += fp->_IO_write_ptr - fp->_IO_write_base;
+	  break;
+	default: /* case _IO_seek_set: */
+	  break;
+	}
+      if (offset < 0 || (_IO_size_t)offset > cur_size)
+	return EOF;
+      LEN(fp) = cur_size;
+      fp->_IO_write_ptr = fp->_IO_write_base + offset;
+      new_pos = offset;
+    }
+  return new_pos;
+}
+
+int
+DEFUN(_IO_str_pbackfail, (fp, c),
+      register _IO_FILE *fp AND int c)
+{
+  if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
+    return EOF;
+  return _IO_default_pbackfail(fp, c);
+}
+
+void
+DEFUN (_IO_str_finish, (fp),
+      register _IO_FILE* fp)
+{
+  if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+    (((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
+  fp->_IO_buf_base = NULL;
+
+  _IO_default_finish(fp);
+}
+
+struct _IO_jump_t _IO_str_jumps = {
+  JUMP_INIT_DUMMY,
+  JUMP_INIT(finish, _IO_str_finish),
+  JUMP_INIT(overflow, _IO_str_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)
+};
diff --git a/libio/vasprintf.c b/libio/vasprintf.c
new file mode 100644
index 0000000000..ee92f83b1c
--- /dev/null
+++ b/libio/vasprintf.c
@@ -0,0 +1,61 @@
+/*
+Copyright (C) 1995 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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;
+  int ret;
+  string = ALLOC_BUF(init_string_size);
+  if (string == NULL)
+    return -1;
+  _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._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._f._IO_buf_base,
+			       (sf._f._IO_write_ptr - sf._f._IO_write_base) +1);
+  if (*result_ptr == NULL)
+    *result_ptr = sf._f._IO_buf_base;
+  (*result_ptr)[sf._f._IO_write_ptr-sf._f._IO_write_base] = '\0';
+  return ret;
+}
+weak_alias (_IO_vasprintf, vasprintf)
diff --git a/libio/vdprintf.c b/libio/vdprintf.c
new file mode 100644
index 0000000000..b92251eada
--- /dev/null
+++ b/libio/vdprintf.c
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 1995 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. */
+
+#include "libioP.h"
+#include "libio.h"
+
+int
+_IO_vdprintf (d, format, arg)
+     int d;
+     const char *format;
+     _IO_va_list arg;
+{
+  struct _IO_FILE_plus tmpfil;
+  int done;
+
+  _IO_init (&tmpfil.file, 0);
+  _IO_JUMPS (&tmpfil.file) = &_IO_file_jumps;
+  _IO_file_init (&tmpfil.file);
+#if  !_IO_UNIFIED_JUMPTABLES
+  tmpfil.vtable = NULL;
+#endif
+  if (_IO_file_attach (&tmpfil.file, d) == NULL)
+    {
+      _IO_un_link (&tmpfil.file);
+      return EOF;
+    }
+  tmpfil.file._flags &= ~_IO_DELETE_DONT_CLOSE;
+
+  tmpfil.file._IO_file_flags =
+    _IO_mask_flags (&tmpfil.file, _IO_NO_READS,
+		    _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
+
+  done = _IO_vfprintf (&tmpfil.file, format, arg);
+
+  _IO_FINISH (&tmpfil.file);
+
+  return done;
+}
+weak_alias (_IO_vdprintf, vdprintf)
diff --git a/libio/vscanf.c b/libio/vscanf.c
new file mode 100644
index 0000000000..f905cff5a3
--- /dev/null
+++ b/libio/vscanf.c
@@ -0,0 +1,37 @@
+/* 
+Copyright (C) 1993 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. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef vscanf
+
+int
+_IO_vscanf (format, args)
+     const char *format;
+     _IO_va_list args;
+{
+  return _IO_vfscanf (_IO_stdin, format, args, NULL);
+}
+weak_alias (_IO_vscanf, vscanf)
diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c
new file mode 100644
index 0000000000..a04da8242a
--- /dev/null
+++ b/libio/vsnprintf.c
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 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. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+int
+_IO_vsnprintf (string, maxlen, format, args)
+     char *string;
+     _IO_size_t maxlen;
+     const char *format;
+     _IO_va_list args;
+{
+  _IO_strfile sf;
+  int ret;
+  _IO_init ((_IO_FILE *) &sf, 0);
+  _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_str_jumps;
+  _IO_str_init_static ((_IO_FILE *) &sf, string, maxlen - 1, string);
+  ret = _IO_vfprintf ((_IO_FILE *) &sf, format, args);
+  *((_IO_FILE *) &sf)->_IO_write_ptr = '\0';
+  return ret;
+}
+weak_alias (_IO_vsnprintf, vsnprintf)
diff --git a/stdio-common/getline.c b/stdio-common/getline.c
index 1a2f975c75..f103979333 100644
--- a/stdio-common/getline.c
+++ b/stdio-common/getline.c
@@ -22,6 +22,11 @@ Cambridge, MA 02139, USA.  */
 
 #undef __getline
 
+#ifdef USE_IN_LIBIO
+# define ssize_t _IO_ssize_t
+# define __getdelim _IO_getdelim
+#endif
+
 /* Like getdelim, but always looks for a newline.  */
 ssize_t
 DEFUN(__getline, (lineptr, n, stream),
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 28d13d61b8..31c009e891 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -269,7 +269,7 @@ __printf_fp (fp, info, args)
 	{
 	  fracsize = __mpn_extract_long_double (fp_input,
 						(sizeof (fp_input) /
-						 sizeof (fp_input[0])), 
+						 sizeof (fp_input[0])),
 						&exponent, &is_neg,
 						fpnum.ldbl);
 	  to_shift = 1 + fracsize * BITS_PER_MP_LIMB - LDBL_MANT_DIG;
@@ -496,7 +496,7 @@ __printf_fp (fp, info, args)
 
       /* Now shift the input value to its right place.	*/
       cy = __mpn_lshift (frac, fp_input, fracsize, to_shift);
-      frac[fracsize++] = cy; 
+      frac[fracsize++] = cy;
       assert (cy == 1 || (frac[fracsize - 2] == 0 && frac[0] == 0));
 
       expsign = 1;
@@ -524,7 +524,7 @@ __printf_fp (fp, info, args)
 	      if (cy == 0)
 		--tmpsize;
 
-	      count_leading_zeros (cnt_h, tmp[tmpsize - 1]); 
+	      count_leading_zeros (cnt_h, tmp[tmpsize - 1]);
 	      incr = (tmpsize - fracsize) * BITS_PER_MP_LIMB
 		     + BITS_PER_MP_LIMB - 1 - cnt_h;
 
@@ -559,7 +559,7 @@ __printf_fp (fp, info, args)
 			   && tmp[tmpsize - 2] < topval[0]))))
 		{
 		  /* The factor is right.  Adapt binary and decimal
-		     exponents.	 */ 
+		     exponents.	 */
 		  exponent -= incr;
 		  exp10 |= 1 << explog;
 
@@ -639,7 +639,7 @@ __printf_fp (fp, info, args)
 
       /* Now shift the input value to its right place.	*/
       cy = __mpn_lshift (frac, fp_input, fracsize, (exponent + to_shift));
-      frac[fracsize++] = cy; 
+      frac[fracsize++] = cy;
       exponent = 0;
     }
 
@@ -714,7 +714,7 @@ __printf_fp (fp, info, args)
        it is possible that we need two more characters in front of all the
        other output.  */
     buffer = alloca (2 + chars_needed);
-    cp = startp = buffer + 2;	/* Let room for rounding.  */ 
+    cp = startp = buffer + 2;	/* Let room for rounding.  */
 
     /* Do the real work: put digits in allocated buffer.  */
     if (expsign == 0 || type != 'f')
@@ -886,7 +886,7 @@ __printf_fp (fp, info, args)
       }
 
     /* Compute number of characters which must be filled with the padding
-       character.  */ 
+       character.  */
     if (is_neg || info->showsign || info->space)
       --width;
     width -= cp - startp;
diff --git a/stdio-common/snprintf.c b/stdio-common/snprintf.c
index a7a6e722ee..ca0b60aed6 100644
--- a/stdio-common/snprintf.c
+++ b/stdio-common/snprintf.c
@@ -20,6 +20,7 @@ Cambridge, MA 02139, USA.  */
 #include <stdio.h>
 
 #ifdef USE_IN_LIBIO
+# include <libioP.h>
 # define __vsnprintf _IO_vsnprintf
 #endif
 
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index e22403be22..9e855ded56 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -239,11 +239,11 @@ vfprintf (s, format, ap)
   /* Fill in the types of all the arguments.  */
   for (cnt = 0; cnt < nspecs; ++cnt)
     {
-      /* If the width is determined by an argument this is an int.  */ 
+      /* If the width is determined by an argument this is an int.  */
       if (specs[cnt].width_arg != -1)
 	args_type[specs[cnt].width_arg] = PA_INT;
 
-      /* If the precision is determined by an argument this is an int.  */ 
+      /* If the precision is determined by an argument this is an int.  */
       if (specs[cnt].prec_arg != -1)
 	args_type[specs[cnt].prec_arg] = PA_INT;
 
@@ -583,16 +583,16 @@ vfprintf (s, format, ap)
           case 'n':
             /* Answer the count of characters written.  */
             if (specs[cnt].info.is_longlong)
-	      *(long long int *) 
+	      *(long long int *)
 		args_value[specs[cnt].data_arg].pa_pointer = done;
             else if (specs[cnt].info.is_long)
-	      *(long int *) 
+	      *(long int *)
 		args_value[specs[cnt].data_arg].pa_pointer = done;
             else if (!specs[cnt].info.is_short)
-	      *(int *) 
+	      *(int *)
 		args_value[specs[cnt].data_arg].pa_pointer = done;
             else
-	      *(short int *) 
+	      *(short int *)
 		args_value[specs[cnt].data_arg].pa_pointer = done;
             break;
 
@@ -745,23 +745,24 @@ _IO_helper_overflow (s, c)
 
 static const struct _IO_jump_t _IO_helper_jumps =
   {
-    _IO_helper_overflow,
-    _IO_default_underflow,
-    _IO_default_xsputn,
-    _IO_default_xsgetn,
-    _IO_default_read,
-    _IO_default_write,
-    _IO_default_doallocate,
-    _IO_default_pbackfail,
-    _IO_default_setbuf,
-    _IO_default_sync,
-    _IO_default_finish,
-    _IO_default_close,
-    _IO_default_stat,
-    _IO_default_seek,
-    _IO_default_seekoff,
-    _IO_default_seekpos,
-    _IO_default_uflow
+    JUMP_INIT_DUMMY,
+    JUMP_INIT (finish, _IO_default_finish),
+    JUMP_INIT (overflow, _IO_helper_overflow),
+    JUMP_INIT (underflow, _IO_default_underflow),
+    JUMP_INIT (uflow, _IO_default_uflow),
+    JUMP_INIT (pbackfail, _IO_default_pbackfail),
+    JUMP_INIT (xsputn, _IO_default_xsputn),
+    JUMP_INIT (xsgetn, _IO_default_xsgetn),
+    JUMP_INIT (seekoff, _IO_default_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)
   };
 
 static int
@@ -781,8 +782,8 @@ buffered_vfprintf (s, format, args)
   hp->_IO_write_ptr = buf;
   hp->_IO_write_end = buf + sizeof buf;
   hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS;
-  hp->_jumps = (struct _IO_jump_t *) &_IO_helper_jumps;
-  
+  _IO_JUMPS (hp) = (struct _IO_jump_t *) &_IO_helper_jumps;
+
   /* Now print to helper instead.  */
   result = _IO_vfprintf (hp, format, args);
 
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
index a778346287..a3c058495e 100644
--- a/stdio-common/vfscanf.c
+++ b/stdio-common/vfscanf.c
@@ -34,23 +34,79 @@ Cambridge, MA 02139, USA.  */
 #define	LONGLONG	long
 #endif
 
-
-#define	inchar()	((c = getc(s)) == EOF ? EOF : (++read_in, c))
-#define	conv_error()	return (ungetc(c, s), done)
-#define input_error()	return (done == 0 ? EOF : done)
-#define	memory_error()	return ((errno = ENOMEM), EOF)
+#ifdef USE_IN_LIBIO
+# include <libioP.h>
+# include <libio.h>
+
+/* Those are flags in the conversion format. */
+# define LONG		0x01	/* l: long or double */
+# define LONGDBL	0x02	/* L: long long or long double */
+# define SHORT		0x04	/* h: short */
+# define SUPPRESS	0x08	/* suppress assignment */
+# define POINTER	0x10	/* weird %p pointer (`fake hex') */
+# define NOSKIP		0x20	/* do not skip blanks */
+# define WIDTH		0x40	/* width */
+
+
+# define va_list	_IO_va_list
+# define ungetc(c, s)	_IO_ungetc (c, s)
+# define inchar()	((c = _IO_getc(s)), ++read_in, c)
+# define conv_error()	return ((errp != NULL && (*errp |= 2)), \
+				(c == EOF || _IO_ungetc(c, s)), done)
+
+# define input_error()	return ((errp != NULL && (*errp |= 1)), \
+				done == 0 ? EOF : done)
+# define memory_error()	return ((errno = ENOMEM), EOF)
+# define ARGCHECK(s, format)						     \
+  do									     \
+    {									     \
+      /* Check file argument for consistence.  */			     \
+      CHECK_FILE (s, -1);						     \
+      if (s->_flags & _IO_NO_READS || format == NULL)			     \
+       {								     \
+         MAYBE_SET_EINVAL;						     \
+         return -1;							     \
+       }								     \
+    } while (0)
+#else
+# define inchar()	((c = getc(s)) == EOF ? EOF : (++read_in, c))
+# define conv_error()	return (ungetc(c, s), done)
+# define input_error()	return (done == 0 ? EOF : done)
+# define memory_error()	return ((errno = ENOMEM), EOF)
+# define ARGCHECK(s, format)						     \
+  do									     \
+    {									     \
+      /* Check file argument for consistence.  */			     \
+      if (!__validfp (s) || !s->__mode.__read || format == NULL)	     \
+	{								     \
+	  errno = EINVAL;						     \
+	  return -1;							     \
+	}								     \
+    } while (0)
+#endif
 
 
 /* Read formatted input from S according to the format string
    FORMAT, using the argument list in ARG.
    Return the number of assignments made, or -1 for an input error.  */
+#ifdef USE_IN_LIBIO
 int
-DEFUN(__vfscanf, (s, format, arg),
-      FILE *s AND CONST char *format AND va_list argptr)
+_IO_vfscanf (s, format, argptr, errp)
+     _IO_FILE *s;
+     const char *format;
+     _IO_va_list argptr;
+     int *errp;
+#else
+int
+__vfscanf (s, format, arg)
+     FILE *s;
+     const char *format;
+     va_list argptr;
+#endif
 {
   va_list arg = (va_list) argptr;
 
-  register CONST char *f = format;
+  register const char *f = format;
   register char fc;		/* Current character of the format.  */
   register size_t done = 0;	/* Assignments done.  */
   register size_t read_in = 0;	/* Chars read in.  */
@@ -58,14 +114,17 @@ DEFUN(__vfscanf, (s, format, arg),
   register int do_assign;	/* Whether to do an assignment.  */
   register int width;		/* Maximum field width.  */
   int group_flag;		/* %' modifier flag.  */
+#ifdef USE_IN_LIBIO
+  int flags;			/* Trace flags for current format element.  */
+#endif
 
   /* Type modifiers.  */
   int is_short, is_long, is_long_double;
 #ifdef	HAVE_LONGLONG
   /* We use the `L' modifier for `long long int'.  */
-#define	is_longlong	is_long_double
+# define is_longlong	is_long_double
 #else
-#define	is_longlong	0
+# define is_longlong	0
 #endif
   int malloc_string;		/* Args are char ** to be filled in.  */
   /* Status for reading F-P nums.  */
@@ -92,18 +151,14 @@ DEFUN(__vfscanf, (s, format, arg),
   char *w;			/* Pointer into WORK.  */
   wchar_t decimal;		/* Decimal point character.  */
 
-  if (!__validfp(s) || !s->__mode.__read || format == NULL)
-    {
-      errno = EINVAL;
-      return EOF;
-    }
+  ARGCHECK (s, format);
 
   /* Figure out the decimal point character.  */
   if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
 	      strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)
     decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
 
-  c = inchar();
+  c = inchar ();
 
   /* Run through the format string.  */
   while (*f != '\0')
@@ -112,27 +167,38 @@ DEFUN(__vfscanf, (s, format, arg),
       /* Extract the next argument, which is of type TYPE.
 	 For a %N$... spec, this is the Nth argument from the beginning;
 	 otherwise it is the next argument after the state now in ARG.  */
-#define ARG(type)	(argpos == 0 ? va_arg (arg, type) :		      \
+#if 0
+      /* XXX Possible optimization.  */
+# define ARG(type)	(argpos == 0 ? va_arg (arg, type) :		      \
+			 ({ va_list arg = (va_list) argptr;		      \
+			    arg = (va_list) ((char *) arg		      \
+					     + (argpos - 1)		      \
+					     * __va_rounded_size (void *));   \
+			    va_arg (arg, type);				      \
+			 }))
+#else
+# define ARG(type)	(argpos == 0 ? va_arg (arg, type) :		      \
 			 ({ unsigned int pos = argpos;			      \
 			    va_list arg = (va_list) argptr;		      \
 			    while (--pos > 0)				      \
 			      (void) va_arg (arg, void *);		      \
 			    va_arg (arg, type);				      \
 			  }))
+#endif
 
       if (!isascii (*f))
 	{
 	  /* Non-ASCII, may be a multibyte.  */
-	  int len = mblen (f, strlen(f));
+	  int len = mblen (f, strlen (f));
 	  if (len > 0)
 	    {
 	      while (len-- > 0)
 		if (c == EOF)
-		  input_error();
+		  input_error ();
 		else if (c == *f++)
-		  (void) inchar();
+		  (void) inchar ();
 		else
-		  conv_error();
+		  conv_error ();
 	      continue;
 	    }
 	}
@@ -142,8 +208,8 @@ DEFUN(__vfscanf, (s, format, arg),
 	{
 	  /* Characters other than format specs must just match.  */
 	  if (c == EOF)
-	    input_error();
-	  if (isspace(fc))
+	    input_error ();
+	  if (isspace (fc))
 	    {
 	      /* Whitespace characters match any amount of whitespace.  */
 	      while (isspace (c))
@@ -151,12 +217,17 @@ DEFUN(__vfscanf, (s, format, arg),
 	      continue;
 	    }
 	  else if (c == fc)
-	    (void) inchar();
+	    (void) inchar ();
 	  else
-	    conv_error();
+	    conv_error ();
 	  continue;
 	}
 
+#ifdef USE_IN_LIBIO
+      /* That is the start of the coversion string. */
+      flags = 0;
+#endif
+
       /* Initialize state of modifiers.  */
       argpos = 0;
       do_assign = 1;
@@ -185,6 +256,9 @@ DEFUN(__vfscanf, (s, format, arg),
 	switch (*f++)
 	  {
 	  case '*':
+#ifdef USE_IN_LIBIO
+	    flags = SUPPRESS;
+#endif
 	    do_assign = 0;
 	    break;
 	  case '\'':
@@ -192,9 +266,15 @@ DEFUN(__vfscanf, (s, format, arg),
 	    break;
 	  }
 
+#ifdef USE_IN_LIBIO
+      /* We have seen width. */
+      if (isdigit (*f))
+	flags |= WIDTH;
+#endif
+
       /* Find the maximum field width.  */
       width = 0;
-      while (isdigit(*f))
+      while (isdigit (*f))
 	{
 	  width *= 10;
 	  width += *f++ - '0';
@@ -209,19 +289,44 @@ DEFUN(__vfscanf, (s, format, arg),
 	  {
 	  case 'h':
 	    /* int's are short int's.  */
+#ifdef USE_IN_LIBIO
+	    if (flags & ~(SUPPRESS | WIDTH))
+	      /* Signal illegal format element.  */
+	      conv_error ();
+	    flags |= SHORT;
+#endif
 	    is_short = 1;
 	    break;
 	  case 'l':
 	    if (is_long)
-	      /* A double `l' is equivalent to an `L'.  */
-	      is_longlong = 1;
+	      {
+		/* A double `l' is equivalent to an `L'.  */
+#ifdef USE_IN_LIBIO
+		if ((flags & ~(SUPPRESS | WIDTH)) && (flags & LONGDBL))
+		  conv_error ();
+		flags &= ~LONG;
+		flags |= LONGDBL;
+#endif
+		is_longlong = 1;
+	      }
 	    else
-	      /* int's are long int's.  */
-	      is_long = 1;
+	      {
+		/* int's are long int's.  */
+#ifdef USE_IN_LIBIO
+		flags |= LONG;
+#endif
+		is_long = 1;
+	      }
 	    break;
 	  case 'q':
 	  case 'L':
 	    /* double's are long double's, and int's are long long int's.  */
+#ifdef USE_IN_LIBIO
+	    if (flags & ~(SUPPRESS | WIDTH))
+	      /* Signal illegal format element.  */
+	      conv_error ();
+	    flags |= LONGDBL;
+#endif
 	    is_long_double = 1;
 	    break;
 	  case 'a':
@@ -233,20 +338,20 @@ DEFUN(__vfscanf, (s, format, arg),
 
       /* End of the format string?  */
       if (*f == '\0')
-	conv_error();
+	conv_error ();
 
       /* Find the conversion specifier.  */
       w = work;
       fc = *f++;
       if (fc != '[' && fc != 'c' && fc != 'n')
 	/* Eat whitespace.  */
-	while (isspace(c))
-	  (void) inchar();
+	while (isspace (c))
+	  (void) inchar ();
       switch (fc)
 	{
 	case '%':	/* Must match a literal '%'.  */
 	  if (c != fc)
-	    conv_error();
+	    conv_error ();
 	  break;
 
 	case 'n':	/* Answer number of assignments done.  */
@@ -263,7 +368,7 @@ DEFUN(__vfscanf, (s, format, arg),
 	    }
 
 	  if (c == EOF)
-	    input_error();
+	    input_error ();
 
 	  if (width == -1)
 	    width = 1;
@@ -272,10 +377,10 @@ DEFUN(__vfscanf, (s, format, arg),
 	    {
 	      do
 		*str++ = c;
-	      while (inchar() != EOF && --width > 0);
+	      while (inchar () != EOF && --width > 0);
 	    }
 	  else
-	    while (inchar() != EOF && --width > 0);
+	    while (inchar () != EOF && --width > 0);
 
 	  if (do_assign)
 	    ++done;
@@ -289,7 +394,7 @@ DEFUN(__vfscanf, (s, format, arg),
 	      if (malloc_string)					      \
 		{							      \
 		  /* The string is to be stored in a malloc'd buffer.  */     \
-		  strptr = ARG (char **);			      \
+		  strptr = ARG (char **);				      \
 		  if (strptr == NULL)					      \
 		    conv_error ();					      \
 		  /* Allocate an initial buffer.  */			      \
@@ -297,7 +402,7 @@ DEFUN(__vfscanf, (s, format, arg),
 		  *strptr = str = malloc (strsize);			      \
 		}							      \
 	      else							      \
-		str = ARG (char *);				      \
+		str = ARG (char *);					      \
 	      if (str == NULL)						      \
 		conv_error ();						      \
 	    }
@@ -357,7 +462,7 @@ DEFUN(__vfscanf, (s, format, arg),
 	  break;
 
 	case 'x':	/* Hexadecimal integer.  */
-	case 'X':	/* Ditto.  */ 
+	case 'X':	/* Ditto.  */
 	  base = 16;
 	  number_signed = 0;
 	  goto number;
@@ -383,7 +488,7 @@ DEFUN(__vfscanf, (s, format, arg),
 
 	number:
 	  if (c == EOF)
-	    input_error();
+	    input_error ();
 
 	  /* Check for a sign.  */
 	  if (c == '-' || c == '+')
@@ -391,7 +496,7 @@ DEFUN(__vfscanf, (s, format, arg),
 	      *w++ = c;
 	      if (width > 0)
 		--width;
-	      (void) inchar();
+	      (void) inchar ();
 	    }
 
 	  /* Look for a leading indication of base.  */
@@ -401,9 +506,9 @@ DEFUN(__vfscanf, (s, format, arg),
 		--width;
 	      *w++ = '0';
 
-	      (void) inchar();
+	      (void) inchar ();
 
-	      if (tolower(c) == 'x')
+	      if (tolower (c) == 'x')
 		{
 		  if (base == 0)
 		    base = 16;
@@ -411,7 +516,7 @@ DEFUN(__vfscanf, (s, format, arg),
 		    {
 		      if (width > 0)
 			--width;
-		      (void) inchar();
+		      (void) inchar ();
 		    }
 		}
 	      else if (base == 0)
@@ -422,21 +527,21 @@ DEFUN(__vfscanf, (s, format, arg),
 	    base = 10;
 
 	  /* Read the number into WORK.  */
-	  while (width != 0 && c != EOF)
+	  do
 	    {
-	      if (base == 16 ? !isxdigit(c) :
-		  (!isdigit(c) || c - '0' >= base))
+	      if (base == 16 ? !isxdigit (c) :
+		  (!isdigit (c) || c - '0' >= base))
 		break;
 	      *w++ = c;
 	      if (width > 0)
 		--width;
-	      (void) inchar ();
 	    }
+	  while (inchar () != EOF && width != 0);
 
 	  if (w == work ||
 	      (w - work == 1 && (work[0] == '+' || work[0] == '-')))
 	    /* There was no number.  */
-	    conv_error();
+	    conv_error ();
 
 	  /* Convert the number.  */
 	  *w = '\0';
@@ -492,15 +597,15 @@ DEFUN(__vfscanf, (s, format, arg),
 	case 'g':
 	case 'G':
 	  if (c == EOF)
-	    input_error();
+	    input_error ();
 
 	  /* Check for a sign.  */
 	  if (c == '-' || c == '+')
 	    {
 	      *w++ = c;
-	      if (inchar() == EOF)
+	      if (inchar () == EOF)
 		/* EOF is only an input error before we read any chars.  */
-		conv_error();
+		conv_error ();
 	      if (width > 0)
 		--width;
 	    }
@@ -508,11 +613,11 @@ DEFUN(__vfscanf, (s, format, arg),
 	  got_dot = got_e = 0;
 	  do
 	    {
-	      if (isdigit(c))
+	      if (isdigit (c))
 		*w++ = c;
 	      else if (got_e && w[-1] == 'e' && (c == '-' || c == '+'))
 		*w++ = c;
-	      else if (!got_e && tolower(c) == 'e')
+	      else if (!got_e && tolower (c) == 'e')
 		{
 		  *w++ = 'e';
 		  got_e = got_dot = 1;
@@ -526,12 +631,12 @@ DEFUN(__vfscanf, (s, format, arg),
 		break;
 	      if (width > 0)
 		--width;
-	    } while (inchar() != EOF && width != 0);
+	    } while (inchar () != EOF && width != 0);
 
 	  if (w == work)
 	    conv_error();
 	  if (w[-1] == '-' || w[-1] == '+' || w[-1] == 'e')
-	    conv_error();
+	    conv_error ();
 
 	  /* Convert the number.  */
 	  *w = '\0';
@@ -614,11 +719,14 @@ DEFUN(__vfscanf, (s, format, arg),
 	  base = 16;
 	  /* A PTR must be the same size as a `long int'.  */
 	  is_long = 1;
+	  number_signed = 0;
 	  goto number;
 	}
     }
 
-  conv_error();
+  return ((c == EOF || ungetc (c, s)), done);
 }
 
+#ifndef USE_IN_LIBIO
 weak_alias (__vfscanf, vfscanf)
+#endif
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index b7c717a823..e60617ffac 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -70,7 +70,7 @@ extern FLOAT MPN2FLOAT (mp_srcptr mpn, int exponent, int negative);
 #  define MAX_DIG_PER_LIMB	19
 #  define MAX_FAC_PER_LIMB	10000000000000000000L
 #else
-#  error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"	
+#  error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
 #endif
 
 
@@ -102,7 +102,7 @@ static const mp_limb _tens_in_limb[MAX_DIG_PER_LIMB + 1] =
 #define RETURN(val,end) \
     do { if (endptr != 0) *endptr = (char *) (end); return val; } while (0)
 
-/* Maximum size necessary for mpn integers to hold floating point numbers.  */ 
+/* Maximum size necessary for mpn integers to hold floating point numbers.  */
 #define	MPNSIZE		(howmany (MAX_EXP + 2 * MANT_DIG, BITS_PER_MP_LIMB) \
 			 + 2)
 /* Declare an mpn integer variable that big.  */
@@ -584,7 +584,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
     {
       errno = ERANGE;
       return 0.0;
-    }	
+    }
 
   if (int_no > 0)
     {
@@ -797,7 +797,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 	dig_no -= lead_zero;
       }
 
-    /* Read the fractional digits from the string.  */ 
+    /* Read the fractional digits from the string.  */
     (void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent);
 
 
@@ -964,7 +964,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 	    have_quot:
 	      got_limb;
 	    }
-	    
+
 	  return round_and_return (retval, exponent - 1, negative,
 				   quot, BITS_PER_MP_LIMB - 1 - used,
 				   more_bits || n1 != 0 || n0 != 0);
@@ -1105,9 +1105,6 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 
 /* External user entry point.  */
 
-#define weak_this(x) weak_symbol(x)
-weak_this (STRTOF)
-
 FLOAT
 STRTOF (nptr, endptr)
      const char *nptr;
@@ -1115,3 +1112,6 @@ STRTOF (nptr, endptr)
 {
   return INTERNAL (STRTOF) (nptr, endptr, 0);
 }
+
+#define weak_this(x) weak_symbol(x)
+weak_this (STRTOF)
diff --git a/stdlib/strtol.c b/stdlib/strtol.c
index 8c1a683880..d52f338c84 100644
--- a/stdlib/strtol.c
+++ b/stdlib/strtol.c
@@ -277,10 +277,6 @@ noconv:
 
 /* External user entry point.  */
 
-#ifdef weak_symbol
-weak_symbol (strtol)
-#endif
-
 INT
 strtol (nptr, endptr, base)
      const char *nptr;
@@ -289,3 +285,7 @@ strtol (nptr, endptr, base)
 {
   return INTERNAL (strtol) (nptr, endptr, base, 0);
 }
+
+#ifdef weak_symbol
+weak_symbol (strtol)
+#endif
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index f2da66a211..c70a6e8d35 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -27,6 +27,11 @@ Cambridge, MA 02139, USA.  */
 #include <fcntl.h>
 #include <unistd.h>
 
+#ifdef USE_IN_LIBIO
+# include "libioP.h"
+# include <libio.h>
+#endif
+
 /* Return nonzero if DIR is an existent directory.  */
 static int
 DEFUN(diraccess, (dir), CONST char *dir)
@@ -169,6 +174,41 @@ DEFUN(__stdio_gen_tempname, (dir, pfx, dir_search, lenptr, streamptr),
 	    {
 	      /* We got a new file that did not previously exist.
 		 Create a stream for it.  */
+#ifdef USE_IN_LIBIO
+	      int save;
+	      struct _IO_FILE_plus *fp;
+
+	      fp = (struct _IO_FILE_plus *)
+		malloc(sizeof (struct _IO_FILE_plus));
+	      if (fp == NULL)
+		{
+		  /* We lost trying to create a stream (out of memory?).
+		     Nothing to do but remove the file, close the descriptor,
+		     and return failure.  */
+		  save = errno;
+		lose:
+		  (void) remove (buf);
+		  (void) __close (fd);
+		  errno = save;
+		  return NULL;
+		}
+	      _IO_init (&fp->file, 0);
+	      _IO_JUMPS (&fp->file) = &_IO_file_jumps;
+	      _IO_file_init (&fp->file);
+# if !_IO_UNIFIED_JUMPTABLES
+	      fp->vtable = NULL;
+# endif
+	      if (_IO_file_attach (&fp->file, fd) == NULL)
+		{
+		  save = errno;
+		  free (fp);
+		  goto lose;
+		}
+	      fp->file._flags &= ~_IO_DELETE_DONT_CLOSE;
+	      fp->file._IO_file_flags = 0;
+
+	      *streamptr = (FILE *) fp;
+#else
 	      *streamptr = __newstream ();
 	      if (*streamptr == NULL)
 		{
@@ -185,6 +225,7 @@ DEFUN(__stdio_gen_tempname, (dir, pfx, dir_search, lenptr, streamptr),
 	      (*streamptr)->__mode.__write = 1;
 	      (*streamptr)->__mode.__read = 1;
 	      (*streamptr)->__mode.__binary = 1;
+#endif
 	    }
 	  else
 	    continue;
diff --git a/sysdeps/unix/sysv/linux/configure b/sysdeps/unix/sysv/linux/configure
new file mode 100644
index 0000000000..63693e088e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/configure
@@ -0,0 +1,3 @@
+# On Linux, the default is to use libio instead of stdio.
+
+test $stdio = default && stdio=libio