implement funopen, fopencookie

Eric Blake ebb9@byu.net
Tue Jun 5 17:58:00 GMT 2007


Jeff Johnston <jjohnstn <at> redhat.com> writes:

> 
> Eric, ok, assuming you have built and tested this patch for cygwin (I 
> verified it for x86-linux).  One small change requested.  The 
> declaration of funopen should use double-underscored argument names 
> (e.g. __readfn instead of readfn).  The same goes for the fropen and 
> fwopen macros; the argument names should be double-underscored.  I 
> realize this was done long prior to your change, but please rectify this 
> when you check in your patch.
> 

After testing on cygwin, here's what I'm actually committing.  In addition to 
cleaning up parameter names in stdio.h, this patch also includes a fix for 
fopencookie(NULL, "a+", functions) to actually operate in append mode.

2007-06-04  Eric Blake  <ebb9@byu.net>

	Implement funopen, fopencookie.
	* libc/include/sys/reent.h (struct __sFILE, struct __sFILE64):
	Switch to reentrant callbacks.
	* libc/include/stdio.h (funopen): Fix declaration.
	(fopencookie): Declare.
	* libc/stdio/local.h (__sread, __swrite, __sseek, __sclose)
	(__sseek64, __swrite64): Fix prototypes.
	[__SCLE]: Pull in setmode declaration.
	* 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/fseek.c (_fseek_r): Account for overflow, and fix
	reentrancy.
	* libc/stdio/ftell.c (_ftell_r): Likewise.
	* libc/stdio/flags.c (__sflags): Don't lose __SAPP on "a+".
	* 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/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.in: Regenerate.

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	4 Jun 2007 17:54:54 -0000
@@ -480,15 +480,47 @@ int	_EXFUN(__swbuf_r, (struct _reent *, 
  */
 
 #ifndef __STRICT_ANSI__
-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)));
-
-#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
+# ifdef __LARGE64_FILES
+FILE	*_EXFUN(funopen,(const _PTR __cookie,
+		int (*__readfn)(_PTR __c, char *__buf, int __n),
+		int (*__writefn)(_PTR __c, const char *__buf, int __n),
+		_fpos64_t (*__seekfn)(_PTR __c, _fpos64_t __off, int __whence),
+		int (*__closefn)(_PTR __c)));
+# 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)
+
+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	4 Jun 2007 17:54:54 -0000
@@ -34,6 +34,8 @@ typedef unsigned __Long __ULong;
 typedef __uint32_t __ULong;
 #endif
 
+struct _reent;
+
 /*
  * If _REENT_SMALL is defined, we make struct _reent as small as possible,
  * by having nearly everything possible allocated at first use.
@@ -181,11 +183,12 @@ 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 *, _PTR,
+					   char *, int));
+  _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *, _PTR,
+					    const char *, int));
+  _fpos_t _EXFUN((*_seek),(struct _reent *, _PTR, _fpos_t, int));
+  int _EXFUN((*_close),(struct _reent *, _PTR));
 
   /* separate buffer for long sequences of ungetc() */
   struct __sbuf _ub;	/* ungetc buffer */
@@ -233,11 +236,12 @@ 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 *, _PTR,
+					   char *, int));
+  _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *, _PTR,
+					    const char *, int));
+  _fpos_t _EXFUN((*_seek),(struct _reent *, _PTR, _fpos_t, int));
+  int _EXFUN((*_close),(struct _reent *, _PTR));
 
   /* separate buffer for long sequences of ungetc() */
   struct __sbuf _ub;	/* ungetc buffer */
@@ -256,7 +260,7 @@ 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 *, _PTR, _fpos64_t, int));
 
 #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	4 Jun 2007 17:54:54 -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/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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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/flags.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/flags.c,v
retrieving revision 1.3
diff -u -p -r1.3 flags.c
--- libc/stdio/flags.c	23 Apr 2004 20:01:55 -0000	1.3
+++ libc/stdio/flags.c	4 Jun 2007 17:54:54 -0000
@@ -62,7 +62,7 @@ _DEFUN(__sflags, (ptr, mode, optr),
     }
   if (mode[1] && (mode[1] == '+' || mode[2] == '+'))
     {
-      ret = __SRW;
+      ret = (ret & ~(__SRD | __SWR)) | __SRW;
       m = O_RDWR;
     }
   if (mode[1] && (mode[1] == 'b' || mode[2] == 'b'))
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	4 Jun 2007 17:54:54 -0000
@@ -0,0 +1,258 @@
+/* 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;
+  FILE *fp;
+  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;
+  if (c->fp->_flags & __SAPP && c->fp->_seek)
+    {
+#ifdef __LARGE64_FILES
+      c->fp->_seek64 (ptr, c->fp->_cookie, 0, SEEK_END);
+#else
+      c->fp->_seek (ptr, c->fp->_cookie, 0, SEEK_END);
+#endif
+    }
+  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;
+  c->fp = fp;
+  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	4 Jun 2007 17:54:54 -0000
@@ -89,8 +89,8 @@ Supporting OS subroutines required: <<cl
 FILE *
 _DEFUN(_freopen_r, (ptr, file, mode, fp),
        struct _reent *ptr _AND
-       _CONST char *file _AND
-       _CONST char *mode _AND
+       const char *file _AND
+       const char *mode _AND
        register FILE *fp)
 {
   register int f;
@@ -106,7 +106,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp)
   if ((flags = __sflags (ptr, mode, &oflags)) == 0)
     {
       _funlockfile (fp);
-      _CAST_VOID _fclose_r (ptr, fp);
+      _fclose_r (ptr, fp);
       __sfp_lock_release ();
       return NULL;
     }
@@ -124,13 +124,13 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp)
   else
     {
       if (fp->_flags & __SWR)
-	_CAST_VOID fflush (fp);
+	fflush (fp);
       /*
        * If close is NULL, closing is a no-op, hence pointless.
        * If file is NULL, the file should not be closed.
        */
       if (fp->_close != NULL && file != NULL)
-	_CAST_VOID (*fp->_close) (fp->_cookie);
+	fp->_close (ptr, fp->_cookie);
     }
 
   /*
@@ -168,16 +168,16 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp)
        * F_SETFL doesn't change textmode.  Don't mess with modes of ttys.
        */
       if (0 <= f && ! isatty (f)
-          && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1)
-        f = -1;
+	  && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1)
+	f = -1;
 #endif
 
       if (f < 0)
-        {
-          e = EBADF;
-          if (fp->_close != NULL)
-            _CAST_VOID (*fp->_close) (fp->_cookie);
-        }
+	{
+	  e = EBADF;
+	  if (fp->_close != NULL)
+	    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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -0000
@@ -25,19 +25,25 @@
 #include <_ansi.h>
 #include <reent.h>
 #include <stdarg.h>
-#include <reent.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <stdio.h>
+#ifdef __SCLE
+# include <io.h>
+#endif
+
 
 extern int    _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char 
*,va_list));
 extern int    _EXFUN(__svfiscanf_r,(struct _reent *,FILE *, _CONST char 
*,va_list));
 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 *, void *, char *,
+					       int));
+extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, void *,
+						const char *, int));
+extern _fpos_t _EXFUN(__sseek,(struct _reent *, void *, _fpos_t, int));
+extern int    _EXFUN(__sclose,(struct _reent *, void *));
 extern int    _EXFUN(__stextmode,(int));
 extern _VOID   _EXFUN(__sinit,(struct _reent *));
 extern _VOID   _EXFUN(_cleanup_r,(struct _reent *));
@@ -47,11 +53,9 @@ 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 *,
-                                      char const *, int));
+extern _fpos64_t _EXFUN(__sseek64,(struct _reent *, void *, _fpos64_t, int));
+extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
+						  const char *, int));
 #endif
 
 /* Called by the main entry point fns to ensure stdio has been initialized.  */
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	4 Jun 2007 17:54:54 -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
@@ -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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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);
+    _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,20 +115,22 @@ _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__
+  extern int _cygwin_istext_for_stdio (int);
   return _cygwin_istext_for_stdio (fd);
 #else
   return 0;
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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -0000
@@ -106,7 +106,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, 
   if ((flags = __sflags (ptr, mode, &oflags)) == 0)
     {
       _funlockfile(fp);
-      (void) _fclose_r (ptr, fp);
+      _fclose_r (ptr, fp);
       __sfp_lock_release ();
       return NULL;
     }
@@ -124,13 +124,13 @@ _DEFUN (_freopen64_r, (ptr, file, mode, 
   else
     {
       if (fp->_flags & __SWR)
-	(void) fflush (fp);
+	 fflush (fp);
       /*
        * If close is NULL, closing is a no-op, hence pointless.
        * If file is NULL, the file should not be closed.
        */
       if (fp->_close != NULL && file != NULL)
-	(void) (*fp->_close) (fp->_cookie);
+	fp->_close (ptr, fp->_cookie);
     }
 
   /*
@@ -168,16 +168,16 @@ _DEFUN (_freopen64_r, (ptr, file, mode, 
        * F_SETFL doesn't change textmode.  Don't mess with modes of ttys.
        */
       if (0 <= f && ! isatty (f)
-          && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1)
-        f = -1;
+	  && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1)
+	f = -1;
 #endif
 
       if (f < 0)
-        {
-          e = EBADF;
-          if (fp->_close != NULL)
-            (void) (*fp->_close) (fp->_cookie);
-        }
+	{
+	  e = EBADF;
+	  if (fp->_close != NULL)
+	    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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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	4 Jun 2007 17:54:54 -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 */
-




More information about the Newlib mailing list