OSDN Git Service

Implement funopen, fopencookie.
authorericb <ericb>
Mon, 4 Jun 2007 18:10:16 +0000 (18:10 +0000)
committerericb <ericb>
Mon, 4 Jun 2007 18:10:16 +0000 (18:10 +0000)
* 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.

25 files changed:
newlib/ChangeLog
newlib/libc/include/stdio.h
newlib/libc/include/sys/reent.h
newlib/libc/stdio/Makefile.am
newlib/libc/stdio/Makefile.in
newlib/libc/stdio/fclose.c
newlib/libc/stdio/fflush.c
newlib/libc/stdio/flags.c
newlib/libc/stdio/fopencookie.c [new file with mode: 0644]
newlib/libc/stdio/freopen.c
newlib/libc/stdio/fseek.c
newlib/libc/stdio/ftell.c
newlib/libc/stdio/funopen.c [new file with mode: 0644]
newlib/libc/stdio/fvwrite.c
newlib/libc/stdio/local.h
newlib/libc/stdio/refill.c
newlib/libc/stdio/siscanf.c
newlib/libc/stdio/sscanf.c
newlib/libc/stdio/stdio.c
newlib/libc/stdio/vsiscanf.c
newlib/libc/stdio/vsscanf.c
newlib/libc/stdio64/freopen64.c
newlib/libc/stdio64/fseeko64.c
newlib/libc/stdio64/ftello64.c
newlib/libc/stdio64/stdio64.c

index c2b9ac6..11d1b40 100644 (file)
@@ -1,3 +1,40 @@
+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.
+
 2007-05-29  Eric Blake  <ebb9@byu.net>
 
        Avoid more compiler warnings.
index 7c52470..babb1c3 100644 (file)
@@ -467,7 +467,7 @@ int     _EXFUN(_fsetpos64_r, (struct _reent *, FILE *, const _fpos64_t *));
 FILE *  _EXFUN(_tmpfile64_r, (struct _reent *));
 #endif /* !__CYGWIN__ */
 #endif /* __LARGE64_FILES */
+
 /*
  * Routines internal to the implementation.
  */
@@ -480,15 +480,47 @@ int       _EXFUN(__swbuf_r, (struct _reent *, int, FILE *));
  */
 
 #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 93c79ff..06d025b 100644 (file)
@@ -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 1e7a9bb..39617d2 100644 (file)
@@ -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 53ba0a7..27fbd9a 100644 (file)
@@ -110,6 +110,8 @@ am__objects_1 = lib_a-clearerr.$(OBJEXT) lib_a-fclose.$(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) \
@@ -139,6 +141,8 @@ am__objects_4 = clearerr.lo fclose.lo fdopen.lo feof.lo ferror.lo \
 @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) \
@@ -419,6 +423,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
 
@@ -459,6 +465,7 @@ CHEWOUT_FILES = \
        fileno.def              \
        fiprintf.def            \
        fopen.def               \
+       fopencookie.def         \
        fputc.def               \
        fputs.def               \
        fread.def               \
@@ -466,6 +473,7 @@ CHEWOUT_FILES = \
        fseek.def               \
        fsetpos.def             \
        ftell.def               \
+       funopen.def             \
        fwrite.def              \
        getc.def                \
        getchar.def             \
@@ -1130,6 +1138,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
 
@@ -1323,11 +1343,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 d7cfdaf..18cddf0 100644 (file)
@@ -33,7 +33,7 @@ TRAD_SYNOPSIS
        #include <stdio.h>
        int fclose(<[fp]>)
        FILE *<[fp]>;
-        
+
        int fclose(<[fp]>)
         struct _reent *<[reent]>
        FILE *<[fp]>;
@@ -79,7 +79,7 @@ _DEFUN(_fclose_r, (rptr, fp),
   CHECK_INIT (rptr, fp);
 
   _flockfile (fp);
-  
+
   if (fp->_flags == 0)         /* not open! */
     {
       _funlockfile (fp);
@@ -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 d46b41f..d375d95 100644 (file)
@@ -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;
@@ -139,7 +139,7 @@ _DEFUN(fflush, (fp),
               if (fp->_flags & __SOFF)
                 fp->_offset = curoff;
             }
-        } 
+        }
       _funlockfile (fp);
       return 0;
     }
@@ -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 d7bf52b..26d2f82 100644 (file)
@@ -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'))
diff --git a/newlib/libc/stdio/fopencookie.c b/newlib/libc/stdio/fopencookie.c
new file mode 100644 (file)
index 0000000..581441b
--- /dev/null
@@ -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 6d885db..f6d658c 100644 (file)
@@ -28,8 +28,8 @@ ANSI_SYNOPSIS
        #include <stdio.h>
        FILE *freopen(const char *<[file]>, const char *<[mode]>,
                      FILE *<[fp]>);
-       FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>, 
-                     const char *<[mode]>, FILE *<[fp]>);
+       FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>,
+                     const char *<[mode]>, FILE *<[fp]>);
 
 TRAD_SYNOPSIS
        #include <stdio.h>
@@ -89,8 +89,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 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);
     }
 
   /*
@@ -154,10 +154,10 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
        */
       f = fp->_file;
       if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1
-          || ! ((oldflags & O_ACCMODE) == O_RDWR
-                || ((oldflags ^ oflags) & O_ACCMODE) == 0)
-          || _fcntl_r (ptr, f, F_SETFL, oflags) == -1)
-        f = -1;
+         || ! ((oldflags & O_ACCMODE) == O_RDWR
+               || ((oldflags ^ oflags) & O_ACCMODE) == 0)
+         || _fcntl_r (ptr, f, F_SETFL, oflags) == -1)
+       f = -1;
 #else
       /* We cannot modify without fcntl support.  */
       f = -1;
@@ -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 e1670e1..028c62a 100644 (file)
@@ -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, whence),
        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, whence),
        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, whence),
        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, whence),
        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, whence),
    */
 
   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, whence),
    */
 
 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 de5d55d..b77879d 100644 (file)
@@ -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;
 }
 
diff --git a/newlib/libc/stdio/funopen.c b/newlib/libc/stdio/funopen.c
new file mode 100644 (file)
index 0000000..35a274f
--- /dev/null
@@ -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 031624d..75fc834 100644 (file)
@@ -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 0dba774..f02f91d 100644 (file)
 #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,(struct _reent *, int (*)(struct _reent *, FIL
 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 71a1e56..f4644ce 100644 (file)
@@ -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 694750d..2c69921 100644 (file)
@@ -112,7 +112,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 /* | 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 b74dd3e..a1987c5 100644 (file)
@@ -393,7 +393,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 /* | 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 8bc7360..3cf3ea7 100644 (file)
  */
 
 _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 c620184..ffbf22e 100644 (file)
@@ -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 22ed9cd..9bb7c0c 100644 (file)
@@ -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 10a45e4..0362407 100644 (file)
@@ -106,7 +106,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
   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, fp),
   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);
     }
 
   /*
@@ -154,10 +154,10 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
        */
       f = fp->_file;
       if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1
-          || ! ((oldflags & O_ACCMODE) == O_RDWR
-                || ((oldflags ^ oflags) & O_ACCMODE) == 0)
-          || _fcntl_r (ptr, f, F_SETFL, oflags) == -1)
-        f = -1;
+         || ! ((oldflags & O_ACCMODE) == O_RDWR
+               || ((oldflags ^ oflags) & O_ACCMODE) == 0)
+         || _fcntl_r (ptr, f, F_SETFL, oflags) == -1)
+       f = -1;
 #else
       /* We cannot modify without fcntl support.  */
       f = -1;
@@ -168,16 +168,16 @@ _DEFUN (_freopen64_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)
-            (void) (*fp->_close) (fp->_cookie);
-        }
+       {
+         e = EBADF;
+         if (fp->_close != NULL)
+           fp->_close (ptr, fp->_cookie);
+       }
     }
 
   /*
index 33e22dc..fe07bfe 100644 (file)
@@ -104,7 +104,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence),
      _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, whence),
        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, whence),
        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, whence),
    */
 
   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, whence),
    */
 
 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 cad175b..b596d32 100644 (file)
@@ -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 35967ad..f33a394 100644 (file)
 
 #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 */
-