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