aboutsummaryrefslogtreecommitdiff
path: root/libio
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 /libio
parenta5a81fecc7194d050066265a15b1ba8bc3abc627 (diff)
downloadglibc-96aa2d94a2355cdc55c96e808d14a0e7f2ebe77d.tar
glibc-96aa2d94a2355cdc55c96e808d14a0e7f2ebe77d.tar.gz
glibc-96aa2d94a2355cdc55c96e808d14a0e7f2ebe77d.tar.bz2
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.
Diffstat (limited to 'libio')
-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
61 files changed, 5476 insertions, 0 deletions
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)