This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

implement funopen, fopencookie


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This patch does a couple of things.  First, it fixes some reentrancy
issues in stdio - before this patch, when one of the callback functions
failed, it set only the global errno, rather than the explicit struct
_reent->_errno field.  Note that fflush still has problems in this
regards, and I still think that it is worth writing _fflush_r for the very
reason that fflush can trigger the setting of errno, but I did not do it
here because this patch was already getting big.

Second, it adds two new functions, funopen from the BSD world, and
fopencookie from the Linux world.  The two functions are identical in
purpose, but different in signature, with a goal of letting a user specify
custom callback routines.  With this interface in place, it becomes a much
easier job to implement fmemopen (a FILE wrapper around a fixed-length
string) and open_memstream (a FILE wrapper around a malloc'd, autogrowing
string), two new functions that are slated for addition in the next
revision of POSIX.  When either of these two interfaces is available, GNU
autogen will use them for performance reasons (preference is given to
fopencookie, because it allows a mode argument; to see it in action, look
at
http://cvs.savannah.gnu.org/viewvc/autogen/agen5/fmemopen.c?revision=4.13&root=autogen&view=markup).

For platforms with large files, I intentionally did not write funopen vs.
funopen64; rather, I tried to implement funopen so that it always handles
large offsets.  Likewise for fopencookie.

OK to apply?

2007-05-16  Eric Blake  <ebb9@byu.net>

	* libc/include/sys/reent.h (struct __sFILE, struct __sFILE64):
	Switch to reentrant callbacks.
	* libc/stdio/local.h (__sread, __swrite, __sseek, __sclose)
	(__sseek64, __swrite64): Fix prototypes.
	* libc/stdio/stdio.c (__sread, __swrite, __sseek, __sclose): Fix
	reentrancy.
	* libc/stdio64/stdio64.c (__sseek64_r, __swrite64_r): Delete.
	(__sseek64, __swrite64): Fix reentrancy.
	* libc/stdio/ftell.c (_ftell_r): Account for overflow, and fix
	reentrancy.
	* libc/stdio/fseek.c (_fseek_r): Likewise.
	* libc/stdio/fclose.c (_fclose_r): Fix reentrancy.
	* libc/stdio/freopen.c (_freopen_r): Likewise.
	* libc/stdio/fvwrite.c (__sfvwrite_r): Likewise.
	* libc/stdio/refill.c (__srefill_r): Likewise.
	* libc/stdio/siscanf.c (eofread): Likewise.
	* libc/stdio/sscanf.c (eofread): Likewise.
	* libc/stdio/vsiscanf.c (eofread1): Likewise.
	* libc/stdio/vsscanf.c (eofread1): Likewise.
	* libc/stdio64/freopen64.c (_freopen64_r): Likewise.
	* libc/stdio64/fseeko64.c (_fseeko64_r): Likewise.
	* libc/stdio64/ftello64.c (_ftello64_r): Likewise.
	* libc/stdio/fflush.c (fflush): Improve reentrancy, although more
	could be fixed.
	* libc/include/stdio.h (funopen): Fix declaration.
	(fopencookie): Declare.
	* libc/stdio/fopencookie.c (_fopencookie_r, fopencookie): New
	file.
	* libc/stdio/funopen.c (_funopen_r, funopen): New file.
	* libc/stdio/Makefile.am (ELIX_4_SOURCES, CHEWOUT_FILES): Build
	new files.
	* libc/stdio/Makefile: Regenerate.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGSwVr84KuGfSFAYARAmydAKC6Z/pxDe1AbHqPRTSVOKToofYL4QCeM/Jj
i9qWtMx54Ey1/e40GNpVhhM=
=hkAj
-----END PGP SIGNATURE-----
Index: libc/include/stdio.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/stdio.h,v
retrieving revision 1.45
diff -u -p -r1.45 stdio.h
--- libc/include/stdio.h	4 May 2007 02:55:16 -0000	1.45
+++ libc/include/stdio.h	16 May 2007 12:51:52 -0000
@@ -480,15 +480,43 @@ int	_EXFUN(__swbuf_r, (struct _reent *, 
  */
 
 #ifndef __STRICT_ANSI__
+# ifdef __LARGE64_FILES
+FILE	*_EXFUN(funopen,(const _PTR _cookie,
+		int (*readfn)(_PTR _cookie, char *_buf, int _n),
+		int (*writefn)(_PTR _cookie, const char *_buf, int _n),
+		_fpos64_t (*seekfn)(_PTR _cookie, _fpos64_t _off, int _whence),
+		int (*closefn)(_PTR _cookie)));
+# else
 FILE	*_EXFUN(funopen,(const _PTR _cookie,
 		int (*readfn)(_PTR _cookie, char *_buf, int _n),
 		int (*writefn)(_PTR _cookie, const char *_buf, int _n),
 		fpos_t (*seekfn)(_PTR _cookie, fpos_t _off, int _whence),
 		int (*closefn)(_PTR _cookie)));
+# endif /* !__LARGE64_FILES */
 
 #define	fropen(cookie, fn) funopen(cookie, fn, (int (*)())0, (fpos_t (*)())0, (int (*)())0)
 #define	fwopen(cookie, fn) funopen(cookie, (int (*)())0, fn, (fpos_t (*)())0, (int (*)())0)
-#endif
+
+typedef ssize_t cookie_read_function_t(void *_cookie, char *_buf, size_t _n);
+typedef ssize_t cookie_write_function_t(void *_cookie, const char *_buf, size_t _n);
+# ifdef __LARGE64_FILES
+typedef int cookie_seek_function_t(void *_cookie, _off64_t *_off, int _whence);
+# else
+typedef int cookie_seek_function_t(void *_cookie, off_t *_off, int _whence);
+# endif /* !__LARGE64_FILES */
+typedef int cookie_close_function_t(void *_cookie);
+typedef struct
+{
+  /* These four struct member names are dictated by Linux; hopefully,
+     they don't conflict with any macros.  */
+  cookie_read_function_t  *read;
+  cookie_write_function_t *write;
+  cookie_seek_function_t  *seek;
+  cookie_close_function_t *close;
+} cookie_io_functions_t;
+FILE *_EXFUN(fopencookie,(void *_cookie, const char *_mode,
+                          cookie_io_functions_t _functions));
+#endif /* ! __STRICT_ANSI__ */
 
 #ifndef __CUSTOM_FILE_IO__
 /*
Index: libc/include/sys/reent.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/sys/reent.h,v
retrieving revision 1.37
diff -u -p -r1.37 reent.h
--- libc/include/sys/reent.h	1 Feb 2007 16:33:05 -0000	1.37
+++ libc/include/sys/reent.h	16 May 2007 12:51:52 -0000
@@ -181,11 +181,13 @@ struct __sFILE {
   /* operations */
   _PTR	_cookie;	/* cookie passed to io functions */
 
-  _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n));
-  _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf,
-					    int _n));
-  _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence));
-  int	_EXFUN((*_close),(_PTR _cookie));
+  _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(struct _reent *_data, _PTR _cookie,
+					   char *_buf, int _n));
+  _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *_data, _PTR _cookie,
+					    const char *_buf, int _n));
+  _fpos_t _EXFUN((*_seek),(struct _reent *_data, _PTR _cookie, _fpos_t _offset,
+			   int _whence));
+  int	_EXFUN((*_close),(struct _reent *_data, _PTR _cookie));
 
   /* separate buffer for long sequences of ungetc() */
   struct __sbuf _ub;	/* ungetc buffer */
@@ -233,11 +235,13 @@ struct __sFILE64 {
   /* operations */
   _PTR	_cookie;	/* cookie passed to io functions */
 
-  _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n));
-  _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf,
-					    int _n));
-  _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence));
-  int	_EXFUN((*_close),(_PTR _cookie));
+  _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(struct _reent *_data, _PTR _cookie,
+					   char *_buf, int _n));
+  _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *_data, _PTR _cookie,
+					    const char *_buf, int _n));
+  _fpos_t _EXFUN((*_seek),(struct _reent *_data, _PTR _cookie, _fpos_t _offset,
+			   int _whence));
+  int	_EXFUN((*_close),(struct _reent *_data, _PTR _cookie));
 
   /* separate buffer for long sequences of ungetc() */
   struct __sbuf _ub;	/* ungetc buffer */
@@ -256,7 +260,8 @@ struct __sFILE64 {
   int   _flags2;        /* for future use */
 
   _off64_t _offset;     /* current lseek offset */
-  _fpos64_t _EXFUN((*_seek64),(_PTR _cookie, _fpos64_t _offset, int _whence));
+  _fpos64_t _EXFUN((*_seek64),(struct _reent *_data, _PTR _cookie,
+			       _fpos64_t _offset, int _whence));
 
 #ifndef __SINGLE_THREAD__
   _flock_t _lock;	/* for thread-safety locking */
Index: libc/stdio/Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/Makefile.am,v
retrieving revision 1.24
diff -u -p -r1.24 Makefile.am
--- libc/stdio/Makefile.am	4 May 2007 02:55:16 -0000	1.24
+++ libc/stdio/Makefile.am	16 May 2007 12:51:52 -0000
@@ -117,6 +117,8 @@ ELIX_4_SOURCES = \
 	asnprintf.c		\
 	diprintf.c		\
 	dprintf.c		\
+	fopencookie.c		\
+	funopen.c		\
 	vasniprintf.c		\
 	vasnprintf.c
 endif !ELIX_LEVEL_3
@@ -179,6 +181,7 @@ CHEWOUT_FILES = \
 	fileno.def		\
 	fiprintf.def		\
 	fopen.def		\
+	fopencookie.def		\
 	fputc.def		\
 	fputs.def		\
 	fread.def		\
@@ -186,6 +189,7 @@ CHEWOUT_FILES = \
 	fseek.def		\
 	fsetpos.def		\
 	ftell.def		\
+	funopen.def		\
 	fwrite.def		\
 	getc.def		\
 	getchar.def		\
@@ -241,11 +245,13 @@ $(lpfx)fdopen.$(oext): local.h
 $(lpfx)fflush.$(oext): local.h
 $(lpfx)findfp.$(oext): local.h
 $(lpfx)fopen.$(oext): local.h
+$(lpfx)fopencookie.$(oext): local.h
 $(lpfx)fputs.$(oext): fvwrite.h
 $(lpfx)fread.$(oext): local.h
 $(lpfx)freopen.$(oext): local.h
 $(lpfx)fseek.$(oext): local.h
 $(lpfx)ftell.$(oext): local.h
+$(lpfx)funopen.$(oext): local.h
 $(lpfx)fvwrite.$(oext): local.h fvwrite.h
 $(lpfx)fwalk.$(oext): local.h
 $(lpfx)fwrite.$(oext): local.h fvwrite.h
Index: libc/stdio/Makefile.in
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/Makefile.in,v
retrieving revision 1.35
diff -u -p -r1.35 Makefile.in
--- libc/stdio/Makefile.in	4 May 2007 02:55:16 -0000	1.35
+++ libc/stdio/Makefile.in	16 May 2007 12:51:52 -0000
@@ -108,6 +108,8 @@ am__objects_1 = lib_a-clearerr.$(OBJEXT)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-asnprintf.$(OBJEXT) \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-diprintf.$(OBJEXT) \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-dprintf.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-fopencookie.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-funopen.$(OBJEXT) \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-vasniprintf.$(OBJEXT) \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-vasnprintf.$(OBJEXT)
 @USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) \
@@ -137,6 +139,8 @@ am__objects_4 = clearerr.lo fclose.lo fd
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	asnprintf.lo \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	diprintf.lo \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	dprintf.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	fopencookie.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	funopen.lo \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	vasniprintf.lo \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	vasnprintf.lo
 @USE_LIBTOOL_TRUE@am_libstdio_la_OBJECTS = $(am__objects_4) \
@@ -403,6 +407,8 @@ GENERAL_SOURCES = \
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	asnprintf.c		\
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	diprintf.c		\
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	dprintf.c		\
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	fopencookie.c		\
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	funopen.c		\
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	vasniprintf.c		\
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	vasnprintf.c
 
@@ -443,6 +449,7 @@ CHEWOUT_FILES = \
 	fileno.def		\
 	fiprintf.def		\
 	fopen.def		\
+	fopencookie.def		\
 	fputc.def		\
 	fputs.def		\
 	fread.def		\
@@ -450,6 +457,7 @@ CHEWOUT_FILES = \
 	fseek.def		\
 	fsetpos.def		\
 	ftell.def		\
+	funopen.def		\
 	fwrite.def		\
 	getc.def		\
 	getchar.def		\
@@ -1114,6 +1122,18 @@ lib_a-dprintf.o: dprintf.c
 lib_a-dprintf.obj: dprintf.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dprintf.obj `if test -f 'dprintf.c'; then $(CYGPATH_W) 'dprintf.c'; else $(CYGPATH_W) '$(srcdir)/dprintf.c'; fi`
 
+lib_a-fopencookie.o: fopencookie.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fopencookie.o `test -f 'fopencookie.c' || echo '$(srcdir)/'`fopencookie.c
+
+lib_a-fopencookie.obj: fopencookie.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fopencookie.obj `if test -f 'fopencookie.c'; then $(CYGPATH_W) 'fopencookie.c'; else $(CYGPATH_W) '$(srcdir)/fopencookie.c'; fi`
+
+lib_a-funopen.o: funopen.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-funopen.o `test -f 'funopen.c' || echo '$(srcdir)/'`funopen.c
+
+lib_a-funopen.obj: funopen.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-funopen.obj `if test -f 'funopen.c'; then $(CYGPATH_W) 'funopen.c'; else $(CYGPATH_W) '$(srcdir)/funopen.c'; fi`
+
 lib_a-vasniprintf.o: vasniprintf.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vasniprintf.o `test -f 'vasniprintf.c' || echo '$(srcdir)/'`vasniprintf.c
 
@@ -1307,11 +1327,13 @@ $(lpfx)fdopen.$(oext): local.h
 $(lpfx)fflush.$(oext): local.h
 $(lpfx)findfp.$(oext): local.h
 $(lpfx)fopen.$(oext): local.h
+$(lpfx)fopencookie.$(oext): local.h
 $(lpfx)fputs.$(oext): fvwrite.h
 $(lpfx)fread.$(oext): local.h
 $(lpfx)freopen.$(oext): local.h
 $(lpfx)fseek.$(oext): local.h
 $(lpfx)ftell.$(oext): local.h
+$(lpfx)funopen.$(oext): local.h
 $(lpfx)fvwrite.$(oext): local.h fvwrite.h
 $(lpfx)fwalk.$(oext): local.h
 $(lpfx)fwrite.$(oext): local.h fvwrite.h
Index: libc/stdio/fclose.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fclose.c,v
retrieving revision 1.13
diff -u -p -r1.13 fclose.c
--- libc/stdio/fclose.c	15 Mar 2007 18:40:48 -0000	1.13
+++ libc/stdio/fclose.c	16 May 2007 12:51:52 -0000
@@ -90,7 +90,7 @@ _DEFUN(_fclose_r, (rptr, fp),
      files to reposition file to last byte processed as opposed to
      last byte read ahead into the buffer.  */
   r = fflush (fp);
-  if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0)
+  if (fp->_close != NULL && (*fp->_close) (rptr, fp->_cookie) < 0)
     r = EOF;
   if (fp->_flags & __SMBF)
     _free_r (rptr, (char *) fp->_bf._base);
Index: libc/stdio/fflush.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fflush.c,v
retrieving revision 1.9
diff -u -p -r1.9 fflush.c
--- libc/stdio/fflush.c	15 Mar 2007 21:32:13 -0000	1.9
+++ libc/stdio/fflush.c	16 May 2007 12:51:52 -0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1990, 2006 The Regents of the University of California.
+ * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -90,7 +90,7 @@ _DEFUN(fflush, (fp),
   t = fp->_flags;
   if ((t & __SWR) == 0)
     {
-      _fpos_t _EXFUN((*seekfn), (_PTR, _fpos_t, int));
+      _fpos_t _EXFUN((*seekfn), (struct _reent *, _PTR, _fpos_t, int));
 
       /* For a read stream, an fflush causes the next seek to be
          unoptimized (i.e. forces a system-level seek).  This conforms
@@ -114,7 +114,7 @@ _DEFUN(fflush, (fp),
           else
             {
               /* We don't know current physical offset, so ask for it.  */
-              curoff = (*seekfn) (fp->_cookie, (_fpos_t) 0, SEEK_CUR);
+              curoff = (*seekfn) (_REENT, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
               if (curoff == -1L)
                 {
                   _funlockfile (fp);
@@ -130,7 +130,7 @@ _DEFUN(fflush, (fp),
                 curoff -= fp->_ur;
             }
           /* Now physically seek to after byte last read.  */
-          if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) != -1)
+          if ((*seekfn)(_REENT, fp->_cookie, curoff, SEEK_SET) != -1)
             {
               /* Seek successful.  We can clear read buffer now.  */
               fp->_flags &= ~__SNPT;
@@ -161,7 +161,7 @@ _DEFUN(fflush, (fp),
 
   while (n > 0)
     {
-      t = (*fp->_write) (fp->_cookie, (char *) p, n);
+      t = (*fp->_write) (_REENT, fp->_cookie, (char *) p, n);
       if (t <= 0)
 	{
           fp->_flags |= __SERR;
Index: libc/stdio/fopencookie.c
===================================================================
RCS file: libc/stdio/fopencookie.c
diff -N libc/stdio/fopencookie.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libc/stdio/fopencookie.c	16 May 2007 12:51:52 -0000
@@ -0,0 +1,248 @@
+/* Copyright (C) 2007 Eric Blake
+ * Permission to use, copy, modify, and distribute this software
+ * is freely granted, provided that this notice is preserved.
+ */
+
+/*
+FUNCTION
+<<fopencookie>>---open a stream with custom callbacks
+
+INDEX
+	fopencookie
+
+ANSI_SYNOPSIS
+	#include <stdio.h>
+	typedef ssize_t (*cookie_read_function_t)(void *_cookie, char *_buf,
+						  size_t _n);
+	typedef ssize_t (*cookie_write_function_t)(void *_cookie,
+						   const char *_buf, size_t _n);
+	typedef int (*cookie_seek_function_t)(void *_cookie, off_t *_off,
+					      int _whence);
+	typedef int (*cookie_close_function_t)(void *_cookie);
+	typedef struct
+	{
+		cookie_read_function_t	*read;
+		cookie_write_function_t *write;
+		cookie_seek_function_t	*seek;
+		cookie_close_function_t *close;
+	} cookie_io_functions_t;
+	FILE *fopencookie(const void *<[cookie]>, const char *<[mode]>,
+			  cookie_io_functions_t <[functions]>);
+
+DESCRIPTION
+<<fopencookie>> creates a <<FILE>> stream where I/O is performed using
+custom callbacks.  The stream is opened with <[mode]> treated as in
+<<fopen>>.  The callbacks <[functions.read]> and <[functions.write]>
+may only be NULL when <[mode]> does not require them.
+
+<[functions.read]> should return -1 on failure, or else the number of
+bytes read (0 on EOF).  It is similar to <<read>>, except that
+<[cookie]> will be passed as the first argument.
+
+<[functions.write]> should return -1 on failure, or else the number of
+bytes written.  It is similar to <<write>>, except that <[cookie]>
+will be passed as the first argument.
+
+<[functions.seek]> should return -1 on failure, and 0 on success, with
+*<[_off]> set to the current file position.  It is a cross between
+<<lseek>> and <<fseek>>, with the <[_whence]> argument interpreted in
+the same manner.  A NULL <[functions.seek]> makes the stream behave
+similarly to a pipe in relation to stdio functions that require
+positioning.
+
+<[functions.close]> should return -1 on failure, or 0 on success.  It
+is similar to <<close>>, except that <[cookie]> will be passed as the
+first argument.  A NULL <[functions.close]> merely flushes all data
+then lets <<fclose>> succeed.  A failed close will still invalidate
+the stream.
+
+Read and write I/O functions are allowed to change the underlying
+buffer on fully buffered or line buffered streams by calling
+<<setvbuf>>.  They are also not required to completely fill or empty
+the buffer.  They are not, however, allowed to change streams from
+unbuffered to buffered or to change the state of the line buffering
+flag.  They must also be prepared to have read or write calls occur on
+buffers other than the one most recently specified.
+
+RETURNS
+The return value is an open FILE pointer on success.  On error,
+<<NULL>> is returned, and <<errno>> will be set to EINVAL if a
+function pointer is missing or <[mode]> is invalid, ENOMEM if the
+stream cannot be created, or EMFILE if too many streams are already
+open.
+
+PORTABILITY
+This function is a newlib extension, copying the prototype from Linux.
+It is not portable.  See also the <<funopen>> interface from BSD.
+
+Supporting OS subroutines required: <<sbrk>>.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/lock.h>
+#include "local.h"
+
+typedef struct fccookie {
+  void *cookie;
+  cookie_read_function_t *readfn;
+  cookie_write_function_t *writefn;
+  cookie_seek_function_t *seekfn;
+  cookie_close_function_t *closefn;
+} fccookie;
+
+static _READ_WRITE_RETURN_TYPE
+_DEFUN(fcreader, (ptr, cookie, buf, n),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       char *buf _AND
+       int n)
+{
+  int result;
+  fccookie *c = (fccookie *) cookie;
+  errno = 0;
+  if ((result = c->readfn (c->cookie, buf, n)) < 0 && errno)
+    ptr->_errno = errno;
+  return result;
+}
+
+static _READ_WRITE_RETURN_TYPE
+_DEFUN(fcwriter, (ptr, cookie, buf, n),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       const char *buf _AND
+       int n)
+{
+  int result;
+  fccookie *c = (fccookie *) cookie;
+  errno = 0;
+  if ((result = c->writefn (c->cookie, buf, n)) < 0 && errno)
+    ptr->_errno = errno;
+  return result;
+}
+
+static _fpos_t
+_DEFUN(fcseeker, (ptr, cookie, off, whence),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       _fpos_t pos _AND
+       int whence)
+{
+  fccookie *c = (fccookie *) cookie;
+#ifndef __LARGE64_FILES
+  off_t offset = (off_t) pos;
+#else /* __LARGE64_FILES */
+  _off64_t offset = (_off64_t) pos;
+#endif /* __LARGE64_FILES */
+
+  errno = 0;
+  if (c->seekfn (c->cookie, &offset, whence) < 0 && errno)
+    ptr->_errno = errno;
+#ifdef __LARGE64_FILES
+  else if ((_fpos_t)offset != offset)
+    {
+      ptr->_errno = EOVERFLOW;
+      offset = -1;
+    }
+#endif /* __LARGE64_FILES */
+  return (_fpos_t) offset;
+}
+
+#ifdef __LARGE64_FILES
+static _fpos64_t
+_DEFUN(fcseeker64, (ptr, cookie, off, whence),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       _fpos64_t pos _AND
+       int whence)
+{
+  _off64_t offset;
+  fccookie *c = (fccookie *) cookie;
+  errno = 0;
+  if (c->seekfn (c->cookie, &offset, whence) < 0 && errno)
+    ptr->_errno = errno;
+  return (_fpos64_t) offset;
+}
+#endif /* __LARGE64_FILES */
+
+static int
+_DEFUN(fccloser, (ptr, cookie),
+       struct _reent *ptr _AND
+       void *cookie)
+{
+  int result = 0;
+  fccookie *c = (fccookie *) cookie;
+  if (c->closefn)
+    {
+      errno = 0;
+      if ((result = c->closefn (c->cookie)) < 0 && errno)
+	ptr->_errno = errno;
+    }
+  _free_r (ptr, c);
+  return result;
+}
+
+FILE *
+_DEFUN(_fopencookie_r, (ptr, cookie, mode, functions),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       const char *mode _AND
+       cookie_io_functions_t functions)
+{
+  FILE *fp;
+  fccookie *c;
+  int flags;
+  int dummy;
+
+  if ((flags = __sflags (ptr, mode, &dummy)) == 0)
+    return NULL;
+  if (((flags & (__SRD | __SRW)) && !functions.read)
+      || ((flags & (__SWR | __SRW)) && !functions.write))
+    {
+      ptr->_errno = EINVAL;
+      return NULL;
+    }
+  if ((fp = __sfp (ptr)) == NULL)
+    return NULL;
+  if ((c = (fccookie *) _malloc_r (ptr, sizeof *c)) == NULL)
+    {
+      __sfp_lock_acquire ();
+      fp->_flags = 0;		/* release */
+#ifndef __SINGLE_THREAD__
+      __lock_close_recursive (fp->_lock);
+#endif
+      __sfp_lock_release ();
+      return NULL;
+    }
+
+  _flockfile (fp);
+  fp->_file = -1;
+  fp->_flags = flags;
+  c->cookie = cookie;
+  fp->_cookie = c;
+  c->readfn = functions.read;
+  fp->_read = fcreader;
+  c->writefn = functions.write;
+  fp->_write = fcwriter;
+  c->seekfn = functions.seek;
+  fp->_seek = functions.seek ? fcseeker : NULL;
+#ifdef __LARGE64_FILES
+  fp->_seek64 = functions.seek ? fcseeker64 : NULL;
+  fp->_flags |= __SL64;
+#endif
+  c->closefn = functions.close;
+  fp->_close = fccloser;
+  _funlockfile (fp);
+  return fp;
+}
+
+#ifndef _REENT_ONLY
+FILE *
+_DEFUN(fopencookie, (cookie, mode, functions),
+       void *cookie _AND
+       const char *mode _AND
+       cookie_io_functions_t functions)
+{
+  return _fopencookie_r (_REENT, cookie, mode, functions);
+}
+#endif /* !_REENT_ONLY */
Index: libc/stdio/freopen.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/freopen.c,v
retrieving revision 1.19
diff -u -p -r1.19 freopen.c
--- libc/stdio/freopen.c	15 Mar 2007 18:40:48 -0000	1.19
+++ libc/stdio/freopen.c	16 May 2007 12:51:52 -0000
@@ -130,7 +130,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp)
        * If file is NULL, the file should not be closed.
        */
       if (fp->_close != NULL && file != NULL)
-	_CAST_VOID (*fp->_close) (fp->_cookie);
+	_CAST_VOID (*fp->_close) (ptr, fp->_cookie);
     }
 
   /*
@@ -176,7 +176,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp)
         {
           e = EBADF;
           if (fp->_close != NULL)
-            _CAST_VOID (*fp->_close) (fp->_cookie);
+            _CAST_VOID (*fp->_close) (ptr, fp->_cookie);
         }
     }
 
Index: libc/stdio/fseek.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fseek.c,v
retrieving revision 1.16
diff -u -p -r1.16 fseek.c
--- libc/stdio/fseek.c	1 May 2007 23:03:36 -0000	1.16
+++ libc/stdio/fseek.c	16 May 2007 12:51:52 -0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1990, 2007 The Regents of the University of California.
+ * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -122,7 +122,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whenc
        long offset        _AND
        int whence)
 {
-  _fpos_t _EXFUN((*seekfn), (_PTR, _fpos_t, int));
+  _fpos_t _EXFUN((*seekfn), (struct _reent *, _PTR, _fpos_t, int));
   _fpos_t target;
   _fpos_t curoff = 0;
   size_t n;
@@ -175,7 +175,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whenc
 	curoff = fp->_offset;
       else
 	{
-	  curoff = (*seekfn) (fp->_cookie, (_fpos_t) 0, SEEK_CUR);
+	  curoff = (*seekfn) (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
 	  if (curoff == -1L)
 	    {
 	      _funlockfile (fp);
@@ -259,6 +259,11 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whenc
 	goto dumb;
       target = st.st_size + offset;
     }
+  if ((long)target != target)
+    {
+      ptr->_errno = EOVERFLOW;
+      return EOF;
+    }
 
   if (!havepos)
     {
@@ -266,7 +271,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whenc
 	curoff = fp->_offset;
       else
 	{
-	  curoff = (*seekfn) (fp->_cookie, 0L, SEEK_CUR);
+	  curoff = (*seekfn) (ptr, fp->_cookie, 0L, SEEK_CUR);
 	  if (curoff == POS_ERR)
 	    goto dumb;
 	}
@@ -327,7 +332,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whenc
    */
 
   curoff = target & ~(fp->_blksize - 1);
-  if ((*seekfn) (fp->_cookie, curoff, SEEK_SET) == POS_ERR)
+  if ((*seekfn) (ptr, fp->_cookie, curoff, SEEK_SET) == POS_ERR)
     goto dumb;
   fp->_r = 0;
   fp->_p = fp->_bf._base;
@@ -351,7 +356,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whenc
    */
 
 dumb:
-  if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR)
+  if (fflush (fp) || (*seekfn) (ptr, fp->_cookie, offset, whence) == POS_ERR)
     {
       _funlockfile (fp);
       return EOF;
Index: libc/stdio/ftell.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/ftell.c,v
retrieving revision 1.10
diff -u -p -r1.10 ftell.c
--- libc/stdio/ftell.c	26 Sep 2006 21:22:19 -0000	1.10
+++ libc/stdio/ftell.c	16 May 2007 12:51:52 -0000
@@ -125,7 +125,7 @@ _DEFUN(_ftell_r, (ptr, fp),
     pos = fp->_offset;
   else
     {
-      pos = (*fp->_seek) (fp->_cookie, (_fpos_t) 0, SEEK_CUR);
+      pos = (*fp->_seek) (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
       if (pos == -1L)
         {
           _funlockfile (fp);
@@ -154,6 +154,11 @@ _DEFUN(_ftell_r, (ptr, fp),
     }
 
   _funlockfile (fp);
+  if ((long)pos != pos)
+    {
+      pos = -1;
+      ptr->_errno = EOVERFLOW;
+    }
   return pos;
 }
 
Index: libc/stdio/funopen.c
===================================================================
RCS file: libc/stdio/funopen.c
diff -N libc/stdio/funopen.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libc/stdio/funopen.c	16 May 2007 12:51:52 -0000
@@ -0,0 +1,278 @@
+/* Copyright (C) 2007 Eric Blake
+ * Permission to use, copy, modify, and distribute this software
+ * is freely granted, provided that this notice is preserved.
+ */
+
+/*
+FUNCTION
+<<funopen>>, <<fropen>>, <<fwopen>>---open a stream with custom callbacks
+
+INDEX
+	funopen
+INDEX
+	fropen
+INDEX
+	fwopen
+
+ANSI_SYNOPSIS
+	#include <stdio.h>
+	FILE *funopen(const void *<[cookie]>,
+	              int (*<[readfn]>) (void *cookie, char *buf, int n),
+	              int (*<[writefn]>) (void *cookie, const char *buf, int n),
+	              fpos_t (*<[seekfn]>) (void *cookie, fpos_t off, int whence),
+	              int (*<[closefn]>) (void *cookie));
+	FILE *fropen(const void *<[cookie]>,
+	             int (*<[readfn]>) (void *cookie, char *buf, int n));
+	FILE *fwopen(const void *<[cookie]>,
+	             int (*<[writefn]>) (void *cookie, const char *buf, int n));
+
+DESCRIPTION
+<<funopen>> creates a <<FILE>> stream where I/O is performed using
+custom callbacks.  At least one of <[readfn]> and <[writefn]> must be
+provided, which determines whether the stream behaves with mode <"r">,
+<"w">, or <"r+">.
+
+<[readfn]> should return -1 on failure, or else the number of bytes
+read (0 on EOF).  It is similar to <<read>>, except that <int> rather
+than <size_t> bounds a transaction size, and <[cookie]> will be passed
+as the first argument.  A NULL <[readfn]> makes attempts to read the
+stream fail.
+
+<[writefn]> should return -1 on failure, or else the number of bytes
+written.  It is similar to <<write>>, except that <int> rather than
+<size_t> bounds a transaction size, and <[cookie]> will be passed as
+the first argument.  A NULL <[writefn]> makes attempts to write the
+stream fail.
+
+<[seekfn]> should return (fpos_t)-1 on failure, or else the current
+file position.  It is similar to <<lseek>>, except that <[cookie]>
+will be passed as the first argument.  A NULL <[seekfn]> makes the
+stream behave similarly to a pipe in relation to stdio functions that
+require positioning.  This implementation assumes fpos_t and off_t are
+the same type.
+
+<[closefn]> should return -1 on failure, or 0 on success.  It is
+similar to <<close>>, except that <[cookie]> will be passed as the
+first argument.  A NULL <[closefn]> merely flushes all data then lets
+<<fclose>> succeed.  A failed close will still invalidate the stream.
+
+Read and write I/O functions are allowed to change the underlying
+buffer on fully buffered or line buffered streams by calling
+<<setvbuf>>.  They are also not required to completely fill or empty
+the buffer.  They are not, however, allowed to change streams from
+unbuffered to buffered or to change the state of the line buffering
+flag.  They must also be prepared to have read or write calls occur on
+buffers other than the one most recently specified.
+
+The functions <<fropen>> and <<fwopen>> are convenience macros around
+<<funopen>> that only use the specified callback.
+
+RETURNS
+The return value is an open FILE pointer on success.  On error,
+<<NULL>> is returned, and <<errno>> will be set to EINVAL if a
+function pointer is missing, ENOMEM if the stream cannot be created,
+or EMFILE if too many streams are already open.
+
+PORTABILITY
+This function is a newlib extension, copying the prototype from BSD.
+It is not portable.  See also the <<fopencookie>> interface from Linux.
+
+Supporting OS subroutines required: <<sbrk>>.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/lock.h>
+#include "local.h"
+
+typedef int (*funread)(void *_cookie, char *_buf, int _n);
+typedef int (*funwrite)(void *_cookie, const char *_buf, int _n);
+#ifdef __LARGE64_FILES
+typedef _fpos64_t (*funseek)(void *_cookie, _fpos64_t _off, int _whence);
+#else
+typedef fpos_t (*funseek)(void *_cookie, fpos_t _off, int _whence);
+#endif
+typedef int (*funclose)(void *_cookie);
+
+typedef struct funcookie {
+  void *cookie;
+  funread readfn;
+  funwrite writefn;
+  funseek seekfn;
+  funclose closefn;
+} funcookie;
+
+static _READ_WRITE_RETURN_TYPE
+_DEFUN(funreader, (ptr, cookie, buf, n),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       char *buf _AND
+       int n)
+{
+  int result;
+  funcookie *c = (funcookie *) cookie;
+  errno = 0;
+  if ((result = c->readfn (c->cookie, buf, n)) < 0 && errno)
+    ptr->_errno = errno;
+  return result;
+}
+
+static _READ_WRITE_RETURN_TYPE
+_DEFUN(funwriter, (ptr, cookie, buf, n),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       const char *buf _AND
+       int n)
+{
+  int result;
+  funcookie *c = (funcookie *) cookie;
+  errno = 0;
+  if ((result = c->writefn (c->cookie, buf, n)) < 0 && errno)
+    ptr->_errno = errno;
+  return result;
+}
+
+static _fpos_t
+_DEFUN(funseeker, (ptr, cookie, off, whence),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       _fpos_t off _AND
+       int whence)
+{
+  funcookie *c = (funcookie *) cookie;
+#ifndef __LARGE64_FILES
+  fpos_t result;
+  errno = 0;
+  if ((result = c->seekfn (c->cookie, (fpos_t) off, whence)) < 0 && errno)
+    ptr->_errno = errno;
+#else /* __LARGE64_FILES */
+  _fpos64_t result;
+  errno = 0;
+  if ((result = c->seekfn (c->cookie, (_fpos64_t) off, whence)) < 0 && errno)
+    ptr->_errno = errno;
+  else if ((_fpos_t)result != result)
+    {
+      ptr->_errno = EOVERFLOW;
+      result = -1;
+    }
+#endif /* __LARGE64_FILES */
+  return result;
+}
+
+#ifdef __LARGE64_FILES
+static _fpos64_t
+_DEFUN(funseeker64, (ptr, cookie, off, whence),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       _fpos64_t off _AND
+       int whence)
+{
+  _fpos64_t result;
+  funcookie *c = (funcookie *) cookie;
+  errno = 0;
+  if ((result = c->seekfn (c->cookie, off, whence)) < 0 && errno)
+    ptr->_errno = errno;
+  return result;
+}
+#endif /* __LARGE64_FILES */
+
+static int
+_DEFUN(funcloser, (ptr, cookie),
+       struct _reent *ptr _AND
+       void *cookie)
+{
+  int result = 0;
+  funcookie *c = (funcookie *) cookie;
+  if (c->closefn)
+    {
+      errno = 0;
+      if ((result = c->closefn (c->cookie)) < 0 && errno)
+	ptr->_errno = errno;
+    }
+  _free_r (ptr, c);
+  return result;
+}
+
+FILE *
+_DEFUN(_funopen_r, (ptr, cookie, readfn, writefn, seekfn, closefn),
+       struct _reent *ptr _AND
+       const void *cookie _AND
+       funread readfn _AND
+       funwrite writefn _AND
+       funseek seekfn _AND
+       funclose closefn)
+{
+  FILE *fp;
+  funcookie *c;
+
+  if (!readfn && !writefn)
+    {
+      ptr->_errno = EINVAL;
+      return NULL;
+    }
+  if ((fp = __sfp (ptr)) == NULL)
+    return NULL;
+  if ((c = (funcookie *) _malloc_r (ptr, sizeof *c)) == NULL)
+    {
+      __sfp_lock_acquire ();
+      fp->_flags = 0;		/* release */
+#ifndef __SINGLE_THREAD__
+      __lock_close_recursive (fp->_lock);
+#endif
+      __sfp_lock_release ();
+      return NULL;
+    }
+
+  _flockfile (fp);
+  fp->_file = -1;
+  c->cookie = (void *) cookie; /* cast away const */
+  fp->_cookie = c;
+  if (readfn)
+    {
+      c->readfn = readfn;
+      fp->_read = funreader;
+      if (writefn)
+	{
+	  fp->_flags = __SRW;
+	  c->writefn = writefn;
+	  fp->_write = funwriter;
+	}
+      else
+	{
+	  fp->_flags = __SRD;
+	  c->writefn = NULL;
+	  fp->_write = NULL;
+	}
+    }
+  else
+    {
+      fp->_flags = __SWR;
+      c->writefn = writefn;
+      fp->_write = funwriter;
+      c->readfn = NULL;
+      fp->_read = NULL;
+    }
+  c->seekfn = seekfn;
+  fp->_seek = seekfn ? funseeker : NULL;
+#ifdef __LARGE64_FILES
+  fp->_seek64 = seekfn ? funseeker64 : NULL;
+  fp->_flags |= __SL64;
+#endif
+  c->closefn = closefn;
+  fp->_close = funcloser;
+  _funlockfile (fp);
+  return fp;
+}
+
+#ifndef _REENT_ONLY
+FILE *
+_DEFUN(funopen, (cookie, readfn, writefn, seekfn, closefn),
+       const void *cookie _AND
+       funread readfn _AND
+       funwrite writefn _AND
+       funseek seekfn _AND
+       funclose closefn)
+{
+  return _funopen_r (_REENT, cookie, readfn, writefn, seekfn, closefn);
+}
+#endif /* !_REENT_ONLY */
Index: libc/stdio/fvwrite.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fvwrite.c,v
retrieving revision 1.12
diff -u -p -r1.12 fvwrite.c
--- libc/stdio/fvwrite.c	4 May 2007 02:55:16 -0000	1.12
+++ libc/stdio/fvwrite.c	16 May 2007 12:51:52 -0000
@@ -98,7 +98,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
       do
 	{
 	  GETIOV (;);
-	  w = (*fp->_write) (fp->_cookie, p, MIN (len, BUFSIZ));
+	  w = (*fp->_write) (ptr, fp->_cookie, p, MIN (len, BUFSIZ));
 	  if (w <= 0)
 	    goto err;
 	  p += w;
@@ -191,7 +191,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
 	  else if (len >= (w = fp->_bf._size))
 	    {
 	      /* write directly */
-	      w = (*fp->_write) (fp->_cookie, p, w);
+	      w = (*fp->_write) (ptr, fp->_cookie, p, w);
 	      if (w <= 0)
 		goto err;
 	    }
@@ -240,7 +240,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
 	    }
 	  else if (s >= (w = fp->_bf._size))
 	    {
-	      w = (*fp->_write) (fp->_cookie, p, w);
+	      w = (*fp->_write) (ptr, fp->_cookie, p, w);
 	      if (w <= 0)
 		goto err;
 	    }
Index: libc/stdio/local.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/local.h,v
retrieving revision 1.21
diff -u -p -r1.21 local.h
--- libc/stdio/local.h	1 May 2007 23:03:36 -0000	1.21
+++ libc/stdio/local.h	16 May 2007 12:51:52 -0000
@@ -34,10 +34,10 @@ extern int    _EXFUN(__svfiscanf_r,(stru
 extern FILE  *_EXFUN(__sfp,(struct _reent *));
 extern int    _EXFUN(__sflags,(struct _reent *,_CONST char*, int*));
 extern int    _EXFUN(__srefill_r,(struct _reent *,FILE *));
-extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(_PTR, char *, int));
-extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(_PTR, char _CONST *, int));
-extern _fpos_t _EXFUN(__sseek,(_PTR, _fpos_t, int));
-extern int    _EXFUN(__sclose,(_PTR));
+extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, _PTR, char *, int));
+extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, _PTR, char _CONST *, int));
+extern _fpos_t _EXFUN(__sseek,(struct _reent *, _PTR, _fpos_t, int));
+extern int    _EXFUN(__sclose,(struct _reent *, _PTR));
 extern int    _EXFUN(__stextmode,(int));
 extern _VOID   _EXFUN(__sinit,(struct _reent *));
 extern _VOID   _EXFUN(_cleanup_r,(struct _reent *));
@@ -47,10 +47,8 @@ extern int    _EXFUN(_fwalk_reent,(struc
 struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n));
 
 #ifdef __LARGE64_FILES
-extern _fpos64_t _EXFUN(__sseek64,(void *, _fpos64_t, int));
-extern _fpos64_t _EXFUN(__sseek64_r,(struct _reent *, void *, _fpos64_t, int));
-extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(void *, char const *, int));
-extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64_r,(struct _reent *, void *,
+extern _fpos64_t _EXFUN(__sseek64,(struct _reent *, void *, _fpos64_t, int));
+extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
                                       char const *, int));
 #endif
 
Index: libc/stdio/refill.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/refill.c,v
retrieving revision 1.9
diff -u -p -r1.9 refill.c
--- libc/stdio/refill.c	15 Mar 2007 18:40:48 -0000	1.9
+++ libc/stdio/refill.c	16 May 2007 12:51:52 -0000
@@ -104,7 +104,7 @@ _DEFUN(__srefill_r, (ptr, fp),
   if (fp->_flags & (__SLBF | __SNBF))
     _CAST_VOID _fwalk (_GLOBAL_REENT, lflush);
   fp->_p = fp->_bf._base;
-  fp->_r = (*fp->_read) (fp->_cookie, (char *) fp->_p, fp->_bf._size);
+  fp->_r = (*fp->_read) (ptr, fp->_cookie, (char *) fp->_p, fp->_bf._size);
   fp->_flags &= ~__SMOD;	/* buffer contents are again pristine */
 #ifndef __CYGWIN__
   if (fp->_r <= 0)
Index: libc/stdio/siscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/siscanf.c,v
retrieving revision 1.2
diff -u -p -r1.2 siscanf.c
--- libc/stdio/siscanf.c	28 Oct 2005 21:38:59 -0000	1.2
+++ libc/stdio/siscanf.c	16 May 2007 12:51:52 -0000
@@ -112,7 +112,8 @@ Supporting OS subroutines required: <<cl
 /* | ARGSUSED */
 /*SUPPRESS 590*/
 static _READ_WRITE_RETURN_TYPE
-_DEFUN(eofread, (cookie, buf, len),
+_DEFUN(eofread, (ptr, cookie, buf, len),
+       struct _reent *ptr _AND
        _PTR cookie _AND
        char *buf   _AND
        int len)
Index: libc/stdio/sscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/sscanf.c,v
retrieving revision 1.10
diff -u -p -r1.10 sscanf.c
--- libc/stdio/sscanf.c	17 Apr 2007 20:53:24 -0000	1.10
+++ libc/stdio/sscanf.c	16 May 2007 12:51:52 -0000
@@ -393,7 +393,8 @@ Supporting OS subroutines required: <<cl
 /* | ARGSUSED */
 /*SUPPRESS 590*/
 static _READ_WRITE_RETURN_TYPE
-_DEFUN(eofread, (cookie, buf, len),
+_DEFUN(eofread, (ptr, cookie, buf, len),
+       struct _reent *ptr _AND
        _PTR cookie _AND
        char *buf   _AND
        int len)
Index: libc/stdio/stdio.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/stdio.c,v
retrieving revision 1.7
diff -u -p -r1.7 stdio.c
--- libc/stdio/stdio.c	23 Apr 2004 20:01:55 -0000	1.7
+++ libc/stdio/stdio.c	16 May 2007 12:51:52 -0000
@@ -30,9 +30,10 @@
  */
 
 _READ_WRITE_RETURN_TYPE
-_DEFUN(__sread, (cookie, buf, n),
-       _PTR cookie _AND
-       char *buf   _AND
+_DEFUN(__sread, (ptr, cookie, buf, n),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       char *buf _AND
        int n)
 {
   register FILE *fp = (FILE *) cookie;
@@ -44,7 +45,7 @@ _DEFUN(__sread, (cookie, buf, n),
     oldmode = setmode (fp->_file, O_BINARY);
 #endif
 
-  ret = _read_r (_REENT, fp->_file, buf, n);
+  ret = _read_r (ptr, fp->_file, buf, n);
 
 #ifdef __SCLE
   if (oldmode)
@@ -61,9 +62,10 @@ _DEFUN(__sread, (cookie, buf, n),
 }
 
 _READ_WRITE_RETURN_TYPE
-_DEFUN(__swrite, (cookie, buf, n),
-       _PTR cookie      _AND
-       char _CONST *buf _AND
+_DEFUN(__swrite, (ptr, cookie, buf, n),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       char const *buf _AND
        int n)
 {
   register FILE *fp = (FILE *) cookie;
@@ -73,7 +75,7 @@ _DEFUN(__swrite, (cookie, buf, n),
 #endif
 
   if (fp->_flags & __SAPP)
-    _CAST_VOID _lseek_r (_REENT, fp->_file, (_off_t) 0, SEEK_END);
+    _CAST_VOID _lseek_r (ptr, fp->_file, (_off_t) 0, SEEK_END);
   fp->_flags &= ~__SOFF;	/* in case O_APPEND mode is set */
 
 #ifdef __SCLE
@@ -81,7 +83,7 @@ _DEFUN(__swrite, (cookie, buf, n),
     oldmode = setmode (fp->_file, O_BINARY);
 #endif
 
-  w = _write_r (_REENT, fp->_file, buf, n);
+  w = _write_r (ptr, fp->_file, buf, n);
 
 #ifdef __SCLE
   if (oldmode)
@@ -92,15 +94,16 @@ _DEFUN(__swrite, (cookie, buf, n),
 }
 
 _fpos_t
-_DEFUN(__sseek, (cookie, offset, whence),
-       _PTR cookie    _AND
+_DEFUN(__sseek, (ptr, cookie, offset, whence),
+       struct _reent *ptr _AND
+       void *cookie _AND
        _fpos_t offset _AND
        int whence)
 {
   register FILE *fp = (FILE *) cookie;
   register _off_t ret;
 
-  ret = _lseek_r (_REENT, fp->_file, (_off_t) offset, whence);
+  ret = _lseek_r (ptr, fp->_file, (_off_t) offset, whence);
   if (ret == -1L)
     fp->_flags &= ~__SOFF;
   else
@@ -112,17 +115,18 @@ _DEFUN(__sseek, (cookie, offset, whence)
 }
 
 int
-_DEFUN(__sclose, (cookie),
-       _PTR cookie)
+_DEFUN(__sclose, (ptr, cookie),
+       struct _reent *ptr _AND
+       void *cookie)
 {
   FILE *fp = (FILE *) cookie;
 
-  return _close_r (_REENT, fp->_file);
+  return _close_r (ptr, fp->_file);
 }
 
 #ifdef __SCLE
 int
-_DEFUN(__stextmode, (fd), 
+_DEFUN(__stextmode, (fd),
        int fd)
 {
 #ifdef __CYGWIN__
Index: libc/stdio/vsiscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vsiscanf.c,v
retrieving revision 1.1
diff -u -p -r1.1 vsiscanf.c
--- libc/stdio/vsiscanf.c	24 Nov 2004 00:45:41 -0000	1.1
+++ libc/stdio/vsiscanf.c	16 May 2007 12:51:52 -0000
@@ -29,7 +29,8 @@
 #include "local.h"
 
 static _READ_WRITE_RETURN_TYPE
-_DEFUN(eofread1, (cookie, buf, len),
+_DEFUN(eofread1, (ptr, cookie, buf, len),
+       struct _reent *ptr _AND
        _PTR cookie _AND
        char *buf   _AND
        int len)
Index: libc/stdio/vsscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vsscanf.c,v
retrieving revision 1.4
diff -u -p -r1.4 vsscanf.c
--- libc/stdio/vsscanf.c	16 Sep 2004 21:30:51 -0000	1.4
+++ libc/stdio/vsscanf.c	16 May 2007 12:51:52 -0000
@@ -29,7 +29,8 @@
 #include "local.h"
 
 static _READ_WRITE_RETURN_TYPE
-_DEFUN(eofread1, (cookie, buf, len),
+_DEFUN(eofread1, (ptr, cookie, buf, len),
+       struct _reent *_ptr _AND
        _PTR cookie _AND
        char *buf   _AND
        int len)
Index: libc/stdio64/freopen64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/freopen64.c,v
retrieving revision 1.15
diff -u -p -r1.15 freopen64.c
--- libc/stdio64/freopen64.c	1 May 2007 23:03:36 -0000	1.15
+++ libc/stdio64/freopen64.c	16 May 2007 12:51:52 -0000
@@ -130,7 +130,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, 
        * If file is NULL, the file should not be closed.
        */
       if (fp->_close != NULL && file != NULL)
-	(void) (*fp->_close) (fp->_cookie);
+	(void) (*fp->_close) (ptr, fp->_cookie);
     }
 
   /*
@@ -176,7 +176,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, 
         {
           e = EBADF;
           if (fp->_close != NULL)
-            (void) (*fp->_close) (fp->_cookie);
+            (void) (*fp->_close) (ptr, fp->_cookie);
         }
     }
 
Index: libc/stdio64/fseeko64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/fseeko64.c,v
retrieving revision 1.10
diff -u -p -r1.10 fseeko64.c
--- libc/stdio64/fseeko64.c	1 May 2007 23:03:36 -0000	1.10
+++ libc/stdio64/fseeko64.c	16 May 2007 12:51:52 -0000
@@ -104,7 +104,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, w
      _off64_t offset _AND
      int whence)
 {
-  _fpos64_t _EXFUN ((*seekfn), (void *, _fpos64_t, int));
+  _fpos64_t _EXFUN ((*seekfn), (struct _reent *, void *, _fpos64_t, int));
   _fpos64_t target, curoff;
   size_t n;
 
@@ -155,7 +155,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, w
 	curoff = fp->_offset;
       else
 	{
-	  curoff = (*seekfn) (fp->_cookie, (_fpos64_t) 0, SEEK_CUR);
+	  curoff = (*seekfn) (ptr, fp->_cookie, (_fpos64_t) 0, SEEK_CUR);
 	  if (curoff == -1L)
 	    {
 	      _funlockfile(fp);
@@ -238,7 +238,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, w
 	curoff = fp->_offset;
       else
 	{
-	  curoff = (*seekfn) (fp->_cookie, (_fpos64_t)0, SEEK_CUR);
+	  curoff = (*seekfn) (ptr, fp->_cookie, (_fpos64_t)0, SEEK_CUR);
 	  if (curoff == POS_ERR)
 	    goto dumb;
 	}
@@ -299,7 +299,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, w
    */
 
   curoff = target & ~((_fpos64_t)(fp->_blksize - 1));
-  if ((*seekfn) (fp->_cookie, curoff, SEEK_SET) == POS_ERR)
+  if ((*seekfn) (ptr, fp->_cookie, curoff, SEEK_SET) == POS_ERR)
     goto dumb;
   fp->_r = 0;
   fp->_p = fp->_bf._base;
@@ -323,7 +323,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, w
    */
 
 dumb:
-  if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR)
+  if (fflush (fp) || (*seekfn) (ptr, fp->_cookie, offset, whence) == POS_ERR)
     {
       _funlockfile(fp);
       return EOF;
Index: libc/stdio64/ftello64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/ftello64.c,v
retrieving revision 1.6
diff -u -p -r1.6 ftello64.c
--- libc/stdio64/ftello64.c	1 May 2007 23:03:36 -0000	1.6
+++ libc/stdio64/ftello64.c	16 May 2007 12:51:52 -0000
@@ -111,7 +111,7 @@ _DEFUN (_ftello64_r, (ptr, fp),
     pos = fp->_offset;
   else
     {
-      pos = (*fp->_seek64) (fp->_cookie, (_fpos64_t) 0, SEEK_CUR);
+      pos = (*fp->_seek64) (ptr, fp->_cookie, (_fpos64_t) 0, SEEK_CUR);
       if (pos == -1L)
         {
           _funlockfile(fp);
Index: libc/stdio64/stdio64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/stdio64.c,v
retrieving revision 1.2
diff -u -p -r1.2 stdio64.c
--- libc/stdio64/stdio64.c	22 Aug 2003 18:52:25 -0000	1.2
+++ libc/stdio64/stdio64.c	16 May 2007 12:51:52 -0000
@@ -26,11 +26,11 @@
 
 #ifdef __LARGE64_FILES
 _fpos64_t
-__sseek64_r (ptr, cookie, offset, whence)
-     struct _reent *ptr;
-     _PTR cookie;
-     _fpos64_t offset;
-     int whence;
+_DEFUN(__sseek64, (ptr, cookie, offset, whence),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       _fpos64_t offset _AND
+       int whence)
 {
   register FILE *fp = (FILE *) cookie;
   register _off64_t ret;
@@ -47,11 +47,11 @@ __sseek64_r (ptr, cookie, offset, whence
 }
 
 _READ_WRITE_RETURN_TYPE
-__swrite64_r (ptr, cookie, buf, n)
-     struct _reent *ptr;
-     _PTR cookie;
-     char _CONST *buf;
-     int n;
+_DEFUN(__swrite64, (ptr, cookie, buf, n),
+       struct _reent *ptr _AND
+       void *cookie _AND
+       char const *buf _AND
+       int n)
 {
   register FILE *fp = (FILE *) cookie;
   int w;
@@ -78,26 +78,4 @@ __swrite64_r (ptr, cookie, buf, n)
   return w;
 }
 
-#ifndef _REENT_ONLY
-_fpos64_t
-__sseek64 (cookie, offset, whence)
-     _PTR cookie;
-     _fpos64_t offset;
-     int whence;
-{
-  return __sseek64_r (_REENT, cookie, offset, whence);
-}
-
-_READ_WRITE_RETURN_TYPE
-__swrite64 (cookie, buf, n)
-     _PTR cookie;
-     char _CONST *buf;
-     int n;
-{
-  return __swrite64_r (_REENT, cookie, buf, n);
-}
-
-#endif /* !_REENT_ONLY */
-
 #endif /* __LARGE64_FILES */
-

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]