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.
This commit is contained in:
		| @@ -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> | 2007-05-29  Eric Blake  <ebb9@byu.net> | ||||||
|  |  | ||||||
| 	Avoid more compiler warnings. | 	Avoid more compiler warnings. | ||||||
|   | |||||||
| @@ -480,15 +480,47 @@ int	_EXFUN(__swbuf_r, (struct _reent *, int, FILE *)); | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifndef __STRICT_ANSI__ | #ifndef __STRICT_ANSI__ | ||||||
| FILE	*_EXFUN(funopen,(const _PTR _cookie, | # ifdef __LARGE64_FILES | ||||||
| 		int (*readfn)(_PTR _cookie, char *_buf, int _n), | FILE	*_EXFUN(funopen,(const _PTR __cookie, | ||||||
| 		int (*writefn)(_PTR _cookie, const char *_buf, int _n), | 		int (*__readfn)(_PTR __c, char *__buf, int __n), | ||||||
| 		fpos_t (*seekfn)(_PTR _cookie, fpos_t _off, int _whence), | 		int (*__writefn)(_PTR __c, const char *__buf, int __n), | ||||||
| 		int (*closefn)(_PTR _cookie))); | 		_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	fropen(__cookie, __fn) funopen(__cookie, __fn, (int (*)())0, \ | ||||||
| #define	fwopen(cookie, fn) funopen(cookie, (int (*)())0, fn, (fpos_t (*)())0, (int (*)())0) | 					       (fpos_t (*)())0, (int (*)())0) | ||||||
| #endif | # 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__ | #ifndef __CUSTOM_FILE_IO__ | ||||||
| /* | /* | ||||||
|   | |||||||
| @@ -34,6 +34,8 @@ typedef unsigned __Long __ULong; | |||||||
| typedef __uint32_t __ULong; | typedef __uint32_t __ULong; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | struct _reent; | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * If _REENT_SMALL is defined, we make struct _reent as small as possible, |  * If _REENT_SMALL is defined, we make struct _reent as small as possible, | ||||||
|  * by having nearly everything possible allocated at first use. |  * by having nearly everything possible allocated at first use. | ||||||
| @@ -181,11 +183,12 @@ struct __sFILE { | |||||||
|   /* operations */ |   /* operations */ | ||||||
|   _PTR	_cookie;	/* cookie passed to io functions */ |   _PTR	_cookie;	/* cookie passed to io functions */ | ||||||
|  |  | ||||||
|   _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); |   _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(struct _reent *, _PTR, | ||||||
|   _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, | 					   char *, int)); | ||||||
| 					    int _n)); |   _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *, _PTR, | ||||||
|   _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); | 					    const char *, int)); | ||||||
|   int	_EXFUN((*_close),(_PTR _cookie)); |   _fpos_t _EXFUN((*_seek),(struct _reent *, _PTR, _fpos_t, int)); | ||||||
|  |   int _EXFUN((*_close),(struct _reent *, _PTR)); | ||||||
|  |  | ||||||
|   /* separate buffer for long sequences of ungetc() */ |   /* separate buffer for long sequences of ungetc() */ | ||||||
|   struct __sbuf _ub;	/* ungetc buffer */ |   struct __sbuf _ub;	/* ungetc buffer */ | ||||||
| @@ -233,11 +236,12 @@ struct __sFILE64 { | |||||||
|   /* operations */ |   /* operations */ | ||||||
|   _PTR	_cookie;	/* cookie passed to io functions */ |   _PTR	_cookie;	/* cookie passed to io functions */ | ||||||
|  |  | ||||||
|   _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); |   _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(struct _reent *, _PTR, | ||||||
|   _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, | 					   char *, int)); | ||||||
| 					    int _n)); |   _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *, _PTR, | ||||||
|   _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); | 					    const char *, int)); | ||||||
|   int	_EXFUN((*_close),(_PTR _cookie)); |   _fpos_t _EXFUN((*_seek),(struct _reent *, _PTR, _fpos_t, int)); | ||||||
|  |   int _EXFUN((*_close),(struct _reent *, _PTR)); | ||||||
|  |  | ||||||
|   /* separate buffer for long sequences of ungetc() */ |   /* separate buffer for long sequences of ungetc() */ | ||||||
|   struct __sbuf _ub;	/* ungetc buffer */ |   struct __sbuf _ub;	/* ungetc buffer */ | ||||||
| @@ -256,7 +260,7 @@ struct __sFILE64 { | |||||||
|   int   _flags2;        /* for future use */ |   int   _flags2;        /* for future use */ | ||||||
|  |  | ||||||
|   _off64_t _offset;     /* current lseek offset */ |   _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__ | #ifndef __SINGLE_THREAD__ | ||||||
|   _flock_t _lock;	/* for thread-safety locking */ |   _flock_t _lock;	/* for thread-safety locking */ | ||||||
|   | |||||||
| @@ -117,6 +117,8 @@ ELIX_4_SOURCES = \ | |||||||
| 	asnprintf.c		\ | 	asnprintf.c		\ | ||||||
| 	diprintf.c		\ | 	diprintf.c		\ | ||||||
| 	dprintf.c		\ | 	dprintf.c		\ | ||||||
|  | 	fopencookie.c		\ | ||||||
|  | 	funopen.c		\ | ||||||
| 	vasniprintf.c		\ | 	vasniprintf.c		\ | ||||||
| 	vasnprintf.c | 	vasnprintf.c | ||||||
| endif !ELIX_LEVEL_3 | endif !ELIX_LEVEL_3 | ||||||
| @@ -179,6 +181,7 @@ CHEWOUT_FILES = \ | |||||||
| 	fileno.def		\ | 	fileno.def		\ | ||||||
| 	fiprintf.def		\ | 	fiprintf.def		\ | ||||||
| 	fopen.def		\ | 	fopen.def		\ | ||||||
|  | 	fopencookie.def		\ | ||||||
| 	fputc.def		\ | 	fputc.def		\ | ||||||
| 	fputs.def		\ | 	fputs.def		\ | ||||||
| 	fread.def		\ | 	fread.def		\ | ||||||
| @@ -186,6 +189,7 @@ CHEWOUT_FILES = \ | |||||||
| 	fseek.def		\ | 	fseek.def		\ | ||||||
| 	fsetpos.def		\ | 	fsetpos.def		\ | ||||||
| 	ftell.def		\ | 	ftell.def		\ | ||||||
|  | 	funopen.def		\ | ||||||
| 	fwrite.def		\ | 	fwrite.def		\ | ||||||
| 	getc.def		\ | 	getc.def		\ | ||||||
| 	getchar.def		\ | 	getchar.def		\ | ||||||
| @@ -241,11 +245,13 @@ $(lpfx)fdopen.$(oext): local.h | |||||||
| $(lpfx)fflush.$(oext): local.h | $(lpfx)fflush.$(oext): local.h | ||||||
| $(lpfx)findfp.$(oext): local.h | $(lpfx)findfp.$(oext): local.h | ||||||
| $(lpfx)fopen.$(oext): local.h | $(lpfx)fopen.$(oext): local.h | ||||||
|  | $(lpfx)fopencookie.$(oext): local.h | ||||||
| $(lpfx)fputs.$(oext): fvwrite.h | $(lpfx)fputs.$(oext): fvwrite.h | ||||||
| $(lpfx)fread.$(oext): local.h | $(lpfx)fread.$(oext): local.h | ||||||
| $(lpfx)freopen.$(oext): local.h | $(lpfx)freopen.$(oext): local.h | ||||||
| $(lpfx)fseek.$(oext): local.h | $(lpfx)fseek.$(oext): local.h | ||||||
| $(lpfx)ftell.$(oext): local.h | $(lpfx)ftell.$(oext): local.h | ||||||
|  | $(lpfx)funopen.$(oext): local.h | ||||||
| $(lpfx)fvwrite.$(oext): local.h fvwrite.h | $(lpfx)fvwrite.$(oext): local.h fvwrite.h | ||||||
| $(lpfx)fwalk.$(oext): local.h | $(lpfx)fwalk.$(oext): local.h | ||||||
| $(lpfx)fwrite.$(oext): local.h fvwrite.h | $(lpfx)fwrite.$(oext): local.h fvwrite.h | ||||||
|   | |||||||
| @@ -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-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-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-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-vasniprintf.$(OBJEXT) \ | ||||||
| @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	lib_a-vasnprintf.$(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) \ | @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@	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@	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@	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@	vasniprintf.lo \ | ||||||
| @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	vasnprintf.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) \ | @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@	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@	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@	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@	vasniprintf.c		\ | ||||||
| @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	vasnprintf.c | @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	vasnprintf.c | ||||||
|  |  | ||||||
| @@ -459,6 +465,7 @@ CHEWOUT_FILES = \ | |||||||
| 	fileno.def		\ | 	fileno.def		\ | ||||||
| 	fiprintf.def		\ | 	fiprintf.def		\ | ||||||
| 	fopen.def		\ | 	fopen.def		\ | ||||||
|  | 	fopencookie.def		\ | ||||||
| 	fputc.def		\ | 	fputc.def		\ | ||||||
| 	fputs.def		\ | 	fputs.def		\ | ||||||
| 	fread.def		\ | 	fread.def		\ | ||||||
| @@ -466,6 +473,7 @@ CHEWOUT_FILES = \ | |||||||
| 	fseek.def		\ | 	fseek.def		\ | ||||||
| 	fsetpos.def		\ | 	fsetpos.def		\ | ||||||
| 	ftell.def		\ | 	ftell.def		\ | ||||||
|  | 	funopen.def		\ | ||||||
| 	fwrite.def		\ | 	fwrite.def		\ | ||||||
| 	getc.def		\ | 	getc.def		\ | ||||||
| 	getchar.def		\ | 	getchar.def		\ | ||||||
| @@ -1130,6 +1138,18 @@ lib_a-dprintf.o: dprintf.c | |||||||
| lib_a-dprintf.obj: 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` | 	$(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 | 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 | 	$(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)fflush.$(oext): local.h | ||||||
| $(lpfx)findfp.$(oext): local.h | $(lpfx)findfp.$(oext): local.h | ||||||
| $(lpfx)fopen.$(oext): local.h | $(lpfx)fopen.$(oext): local.h | ||||||
|  | $(lpfx)fopencookie.$(oext): local.h | ||||||
| $(lpfx)fputs.$(oext): fvwrite.h | $(lpfx)fputs.$(oext): fvwrite.h | ||||||
| $(lpfx)fread.$(oext): local.h | $(lpfx)fread.$(oext): local.h | ||||||
| $(lpfx)freopen.$(oext): local.h | $(lpfx)freopen.$(oext): local.h | ||||||
| $(lpfx)fseek.$(oext): local.h | $(lpfx)fseek.$(oext): local.h | ||||||
| $(lpfx)ftell.$(oext): local.h | $(lpfx)ftell.$(oext): local.h | ||||||
|  | $(lpfx)funopen.$(oext): local.h | ||||||
| $(lpfx)fvwrite.$(oext): local.h fvwrite.h | $(lpfx)fvwrite.$(oext): local.h fvwrite.h | ||||||
| $(lpfx)fwalk.$(oext): local.h | $(lpfx)fwalk.$(oext): local.h | ||||||
| $(lpfx)fwrite.$(oext): local.h fvwrite.h | $(lpfx)fwrite.$(oext): local.h fvwrite.h | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ _DEFUN(_fclose_r, (rptr, fp), | |||||||
|      files to reposition file to last byte processed as opposed to |      files to reposition file to last byte processed as opposed to | ||||||
|      last byte read ahead into the buffer.  */ |      last byte read ahead into the buffer.  */ | ||||||
|   r = fflush (fp); |   r = fflush (fp); | ||||||
|   if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0) |   if (fp->_close != NULL && fp->_close (rptr, fp->_cookie) < 0) | ||||||
|     r = EOF; |     r = EOF; | ||||||
|   if (fp->_flags & __SMBF) |   if (fp->_flags & __SMBF) | ||||||
|     _free_r (rptr, (char *) fp->_bf._base); |     _free_r (rptr, (char *) fp->_bf._base); | ||||||
|   | |||||||
| @@ -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. |  * All rights reserved. | ||||||
|  * |  * | ||||||
|  * Redistribution and use in source and binary forms are permitted |  * Redistribution and use in source and binary forms are permitted | ||||||
| @@ -90,7 +90,7 @@ _DEFUN(fflush, (fp), | |||||||
|   t = fp->_flags; |   t = fp->_flags; | ||||||
|   if ((t & __SWR) == 0) |   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 |       /* For a read stream, an fflush causes the next seek to be | ||||||
|          unoptimized (i.e. forces a system-level seek).  This conforms |          unoptimized (i.e. forces a system-level seek).  This conforms | ||||||
| @@ -114,7 +114,7 @@ _DEFUN(fflush, (fp), | |||||||
|           else |           else | ||||||
|             { |             { | ||||||
|               /* We don't know current physical offset, so ask for it.  */ |               /* 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) |               if (curoff == -1L) | ||||||
|                 { |                 { | ||||||
|                   _funlockfile (fp); |                   _funlockfile (fp); | ||||||
| @@ -130,7 +130,7 @@ _DEFUN(fflush, (fp), | |||||||
|                 curoff -= fp->_ur; |                 curoff -= fp->_ur; | ||||||
|             } |             } | ||||||
|           /* Now physically seek to after byte last read.  */ |           /* 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.  */ |               /* Seek successful.  We can clear read buffer now.  */ | ||||||
|               fp->_flags &= ~__SNPT; |               fp->_flags &= ~__SNPT; | ||||||
| @@ -161,7 +161,7 @@ _DEFUN(fflush, (fp), | |||||||
|  |  | ||||||
|   while (n > 0) |   while (n > 0) | ||||||
|     { |     { | ||||||
|       t = (*fp->_write) (fp->_cookie, (char *) p, n); |       t = fp->_write (_REENT, fp->_cookie, (char *) p, n); | ||||||
|       if (t <= 0) |       if (t <= 0) | ||||||
| 	{ | 	{ | ||||||
|           fp->_flags |= __SERR; |           fp->_flags |= __SERR; | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ _DEFUN(__sflags, (ptr, mode, optr), | |||||||
|     } |     } | ||||||
|   if (mode[1] && (mode[1] == '+' || mode[2] == '+')) |   if (mode[1] && (mode[1] == '+' || mode[2] == '+')) | ||||||
|     { |     { | ||||||
|       ret = __SRW; |       ret = (ret & ~(__SRD | __SWR)) | __SRW; | ||||||
|       m = O_RDWR; |       m = O_RDWR; | ||||||
|     } |     } | ||||||
|   if (mode[1] && (mode[1] == 'b' || mode[2] == 'b')) |   if (mode[1] && (mode[1] == 'b' || mode[2] == 'b')) | ||||||
|   | |||||||
							
								
								
									
										258
									
								
								newlib/libc/stdio/fopencookie.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								newlib/libc/stdio/fopencookie.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 */ | ||||||
| @@ -89,8 +89,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, | |||||||
| FILE * | FILE * | ||||||
| _DEFUN(_freopen_r, (ptr, file, mode, fp), | _DEFUN(_freopen_r, (ptr, file, mode, fp), | ||||||
|        struct _reent *ptr _AND |        struct _reent *ptr _AND | ||||||
|        _CONST char *file _AND |        const char *file _AND | ||||||
|        _CONST char *mode _AND |        const char *mode _AND | ||||||
|        register FILE *fp) |        register FILE *fp) | ||||||
| { | { | ||||||
|   register int f; |   register int f; | ||||||
| @@ -106,7 +106,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), | |||||||
|   if ((flags = __sflags (ptr, mode, &oflags)) == 0) |   if ((flags = __sflags (ptr, mode, &oflags)) == 0) | ||||||
|     { |     { | ||||||
|       _funlockfile (fp); |       _funlockfile (fp); | ||||||
|       _CAST_VOID _fclose_r (ptr, fp); |       _fclose_r (ptr, fp); | ||||||
|       __sfp_lock_release (); |       __sfp_lock_release (); | ||||||
|       return NULL; |       return NULL; | ||||||
|     } |     } | ||||||
| @@ -124,13 +124,13 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), | |||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       if (fp->_flags & __SWR) |       if (fp->_flags & __SWR) | ||||||
| 	_CAST_VOID fflush (fp); | 	fflush (fp); | ||||||
|       /* |       /* | ||||||
|        * If close is NULL, closing is a no-op, hence pointless. |        * If close is NULL, closing is a no-op, hence pointless. | ||||||
|        * If file is NULL, the file should not be closed. |        * If file is NULL, the file should not be closed. | ||||||
|        */ |        */ | ||||||
|       if (fp->_close != NULL && file != NULL) |       if (fp->_close != NULL && file != NULL) | ||||||
| 	_CAST_VOID (*fp->_close) (fp->_cookie); | 	fp->_close (ptr, fp->_cookie); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
| @@ -176,7 +176,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), | |||||||
| 	{ | 	{ | ||||||
| 	  e = EBADF; | 	  e = EBADF; | ||||||
| 	  if (fp->_close != NULL) | 	  if (fp->_close != NULL) | ||||||
|             _CAST_VOID (*fp->_close) (fp->_cookie); | 	    fp->_close (ptr, fp->_cookie); | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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. |  * All rights reserved. | ||||||
|  * |  * | ||||||
|  * Redistribution and use in source and binary forms are permitted |  * Redistribution and use in source and binary forms are permitted | ||||||
| @@ -122,7 +122,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), | |||||||
|        long offset        _AND |        long offset        _AND | ||||||
|        int whence) |        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 target; | ||||||
|   _fpos_t curoff = 0; |   _fpos_t curoff = 0; | ||||||
|   size_t n; |   size_t n; | ||||||
| @@ -175,7 +175,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), | |||||||
| 	curoff = fp->_offset; | 	curoff = fp->_offset; | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
| 	  curoff = (*seekfn) (fp->_cookie, (_fpos_t) 0, SEEK_CUR); | 	  curoff = seekfn (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR); | ||||||
| 	  if (curoff == -1L) | 	  if (curoff == -1L) | ||||||
| 	    { | 	    { | ||||||
| 	      _funlockfile (fp); | 	      _funlockfile (fp); | ||||||
| @@ -259,6 +259,11 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), | |||||||
| 	goto dumb; | 	goto dumb; | ||||||
|       target = st.st_size + offset; |       target = st.st_size + offset; | ||||||
|     } |     } | ||||||
|  |   if ((long)target != target) | ||||||
|  |     { | ||||||
|  |       ptr->_errno = EOVERFLOW; | ||||||
|  |       return EOF; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   if (!havepos) |   if (!havepos) | ||||||
|     { |     { | ||||||
| @@ -266,7 +271,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), | |||||||
| 	curoff = fp->_offset; | 	curoff = fp->_offset; | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
| 	  curoff = (*seekfn) (fp->_cookie, 0L, SEEK_CUR); | 	  curoff = seekfn (ptr, fp->_cookie, 0L, SEEK_CUR); | ||||||
| 	  if (curoff == POS_ERR) | 	  if (curoff == POS_ERR) | ||||||
| 	    goto dumb; | 	    goto dumb; | ||||||
| 	} | 	} | ||||||
| @@ -327,7 +332,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), | |||||||
|    */ |    */ | ||||||
|  |  | ||||||
|   curoff = target & ~(fp->_blksize - 1); |   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; |     goto dumb; | ||||||
|   fp->_r = 0; |   fp->_r = 0; | ||||||
|   fp->_p = fp->_bf._base; |   fp->_p = fp->_bf._base; | ||||||
| @@ -351,7 +356,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), | |||||||
|    */ |    */ | ||||||
|  |  | ||||||
| dumb: | dumb: | ||||||
|   if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR) |   if (fflush (fp) || seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR) | ||||||
|     { |     { | ||||||
|       _funlockfile (fp); |       _funlockfile (fp); | ||||||
|       return EOF; |       return EOF; | ||||||
|   | |||||||
| @@ -125,7 +125,7 @@ _DEFUN(_ftell_r, (ptr, fp), | |||||||
|     pos = fp->_offset; |     pos = fp->_offset; | ||||||
|   else |   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) |       if (pos == -1L) | ||||||
|         { |         { | ||||||
|           _funlockfile (fp); |           _funlockfile (fp); | ||||||
| @@ -154,6 +154,11 @@ _DEFUN(_ftell_r, (ptr, fp), | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   _funlockfile (fp); |   _funlockfile (fp); | ||||||
|  |   if ((long)pos != pos) | ||||||
|  |     { | ||||||
|  |       pos = -1; | ||||||
|  |       ptr->_errno = EOVERFLOW; | ||||||
|  |     } | ||||||
|   return pos; |   return pos; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										278
									
								
								newlib/libc/stdio/funopen.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								newlib/libc/stdio/funopen.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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 */ | ||||||
| @@ -98,7 +98,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio), | |||||||
|       do |       do | ||||||
| 	{ | 	{ | ||||||
| 	  GETIOV (;); | 	  GETIOV (;); | ||||||
| 	  w = (*fp->_write) (fp->_cookie, p, MIN (len, BUFSIZ)); | 	  w = fp->_write (ptr, fp->_cookie, p, MIN (len, BUFSIZ)); | ||||||
| 	  if (w <= 0) | 	  if (w <= 0) | ||||||
| 	    goto err; | 	    goto err; | ||||||
| 	  p += w; | 	  p += w; | ||||||
| @@ -191,7 +191,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio), | |||||||
| 	  else if (len >= (w = fp->_bf._size)) | 	  else if (len >= (w = fp->_bf._size)) | ||||||
| 	    { | 	    { | ||||||
| 	      /* write directly */ | 	      /* write directly */ | ||||||
| 	      w = (*fp->_write) (fp->_cookie, p, w); | 	      w = fp->_write (ptr, fp->_cookie, p, w); | ||||||
| 	      if (w <= 0) | 	      if (w <= 0) | ||||||
| 		goto err; | 		goto err; | ||||||
| 	    } | 	    } | ||||||
| @@ -240,7 +240,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio), | |||||||
| 	    } | 	    } | ||||||
| 	  else if (s >= (w = fp->_bf._size)) | 	  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) | 	      if (w <= 0) | ||||||
| 		goto err; | 		goto err; | ||||||
| 	    } | 	    } | ||||||
|   | |||||||
| @@ -25,19 +25,25 @@ | |||||||
| #include <_ansi.h> | #include <_ansi.h> | ||||||
| #include <reent.h> | #include <reent.h> | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| #include <reent.h> |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <unistd.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(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); | ||||||
| extern int    _EXFUN(__svfiscanf_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 FILE  *_EXFUN(__sfp,(struct _reent *)); | ||||||
| extern int    _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); | extern int    _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); | ||||||
| extern int    _EXFUN(__srefill_r,(struct _reent *,FILE *)); | extern int    _EXFUN(__srefill_r,(struct _reent *,FILE *)); | ||||||
| extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(_PTR, char *, int)); | extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *, | ||||||
| extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(_PTR, char _CONST *, int)); | 					       int)); | ||||||
| extern _fpos_t _EXFUN(__sseek,(_PTR, _fpos_t, int)); | extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, void *, | ||||||
| extern int    _EXFUN(__sclose,(_PTR)); | 						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 int    _EXFUN(__stextmode,(int)); | ||||||
| extern _VOID   _EXFUN(__sinit,(struct _reent *)); | extern _VOID   _EXFUN(__sinit,(struct _reent *)); | ||||||
| extern _VOID   _EXFUN(_cleanup_r,(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)); | struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n)); | ||||||
|  |  | ||||||
| #ifdef __LARGE64_FILES | #ifdef __LARGE64_FILES | ||||||
| extern _fpos64_t _EXFUN(__sseek64,(void *, _fpos64_t, int)); | extern _fpos64_t _EXFUN(__sseek64,(struct _reent *, void *, _fpos64_t, int)); | ||||||
| extern _fpos64_t _EXFUN(__sseek64_r,(struct _reent *, void *, _fpos64_t, int)); | extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *, | ||||||
| extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(void *, char const *, int)); | 						  const char *, int)); | ||||||
| extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64_r,(struct _reent *, void *, |  | ||||||
|                                       char const *, int)); |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* Called by the main entry point fns to ensure stdio has been initialized.  */ | /* Called by the main entry point fns to ensure stdio has been initialized.  */ | ||||||
|   | |||||||
| @@ -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. |  * All rights reserved. | ||||||
|  * |  * | ||||||
|  * Redistribution and use in source and binary forms are permitted |  * Redistribution and use in source and binary forms are permitted | ||||||
| @@ -104,7 +104,7 @@ _DEFUN(__srefill_r, (ptr, fp), | |||||||
|   if (fp->_flags & (__SLBF | __SNBF)) |   if (fp->_flags & (__SLBF | __SNBF)) | ||||||
|     _CAST_VOID _fwalk (_GLOBAL_REENT, lflush); |     _CAST_VOID _fwalk (_GLOBAL_REENT, lflush); | ||||||
|   fp->_p = fp->_bf._base; |   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 */ |   fp->_flags &= ~__SMOD;	/* buffer contents are again pristine */ | ||||||
| #ifndef __CYGWIN__ | #ifndef __CYGWIN__ | ||||||
|   if (fp->_r <= 0) |   if (fp->_r <= 0) | ||||||
|   | |||||||
| @@ -112,7 +112,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, | |||||||
| /* | ARGSUSED */ | /* | ARGSUSED */ | ||||||
| /*SUPPRESS 590*/ | /*SUPPRESS 590*/ | ||||||
| static _READ_WRITE_RETURN_TYPE | static _READ_WRITE_RETURN_TYPE | ||||||
| _DEFUN(eofread, (cookie, buf, len), | _DEFUN(eofread, (ptr, cookie, buf, len), | ||||||
|  |        struct _reent *ptr _AND | ||||||
|        _PTR cookie _AND |        _PTR cookie _AND | ||||||
|        char *buf   _AND |        char *buf   _AND | ||||||
|        int len) |        int len) | ||||||
|   | |||||||
| @@ -393,7 +393,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, | |||||||
| /* | ARGSUSED */ | /* | ARGSUSED */ | ||||||
| /*SUPPRESS 590*/ | /*SUPPRESS 590*/ | ||||||
| static _READ_WRITE_RETURN_TYPE | static _READ_WRITE_RETURN_TYPE | ||||||
| _DEFUN(eofread, (cookie, buf, len), | _DEFUN(eofread, (ptr, cookie, buf, len), | ||||||
|  |        struct _reent *ptr _AND | ||||||
|        _PTR cookie _AND |        _PTR cookie _AND | ||||||
|        char *buf   _AND |        char *buf   _AND | ||||||
|        int len) |        int len) | ||||||
|   | |||||||
| @@ -30,8 +30,9 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| _READ_WRITE_RETURN_TYPE | _READ_WRITE_RETURN_TYPE | ||||||
| _DEFUN(__sread, (cookie, buf, n), | _DEFUN(__sread, (ptr, cookie, buf, n), | ||||||
|        _PTR cookie _AND |        struct _reent *ptr _AND | ||||||
|  |        void *cookie _AND | ||||||
|        char *buf _AND |        char *buf _AND | ||||||
|        int n) |        int n) | ||||||
| { | { | ||||||
| @@ -44,7 +45,7 @@ _DEFUN(__sread, (cookie, buf, n), | |||||||
|     oldmode = setmode (fp->_file, O_BINARY); |     oldmode = setmode (fp->_file, O_BINARY); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   ret = _read_r (_REENT, fp->_file, buf, n); |   ret = _read_r (ptr, fp->_file, buf, n); | ||||||
|  |  | ||||||
| #ifdef __SCLE | #ifdef __SCLE | ||||||
|   if (oldmode) |   if (oldmode) | ||||||
| @@ -61,9 +62,10 @@ _DEFUN(__sread, (cookie, buf, n), | |||||||
| } | } | ||||||
|  |  | ||||||
| _READ_WRITE_RETURN_TYPE | _READ_WRITE_RETURN_TYPE | ||||||
| _DEFUN(__swrite, (cookie, buf, n), | _DEFUN(__swrite, (ptr, cookie, buf, n), | ||||||
|        _PTR cookie      _AND |        struct _reent *ptr _AND | ||||||
|        char _CONST *buf _AND |        void *cookie _AND | ||||||
|  |        char const *buf _AND | ||||||
|        int n) |        int n) | ||||||
| { | { | ||||||
|   register FILE *fp = (FILE *) cookie; |   register FILE *fp = (FILE *) cookie; | ||||||
| @@ -73,7 +75,7 @@ _DEFUN(__swrite, (cookie, buf, n), | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   if (fp->_flags & __SAPP) |   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 */ |   fp->_flags &= ~__SOFF;	/* in case O_APPEND mode is set */ | ||||||
|  |  | ||||||
| #ifdef __SCLE | #ifdef __SCLE | ||||||
| @@ -81,7 +83,7 @@ _DEFUN(__swrite, (cookie, buf, n), | |||||||
|     oldmode = setmode (fp->_file, O_BINARY); |     oldmode = setmode (fp->_file, O_BINARY); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   w = _write_r (_REENT, fp->_file, buf, n); |   w = _write_r (ptr, fp->_file, buf, n); | ||||||
|  |  | ||||||
| #ifdef __SCLE | #ifdef __SCLE | ||||||
|   if (oldmode) |   if (oldmode) | ||||||
| @@ -92,15 +94,16 @@ _DEFUN(__swrite, (cookie, buf, n), | |||||||
| } | } | ||||||
|  |  | ||||||
| _fpos_t | _fpos_t | ||||||
| _DEFUN(__sseek, (cookie, offset, whence), | _DEFUN(__sseek, (ptr, cookie, offset, whence), | ||||||
|        _PTR cookie    _AND |        struct _reent *ptr _AND | ||||||
|  |        void *cookie _AND | ||||||
|        _fpos_t offset _AND |        _fpos_t offset _AND | ||||||
|        int whence) |        int whence) | ||||||
| { | { | ||||||
|   register FILE *fp = (FILE *) cookie; |   register FILE *fp = (FILE *) cookie; | ||||||
|   register _off_t ret; |   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) |   if (ret == -1L) | ||||||
|     fp->_flags &= ~__SOFF; |     fp->_flags &= ~__SOFF; | ||||||
|   else |   else | ||||||
| @@ -112,12 +115,13 @@ _DEFUN(__sseek, (cookie, offset, whence), | |||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| _DEFUN(__sclose, (cookie), | _DEFUN(__sclose, (ptr, cookie), | ||||||
|        _PTR cookie) |        struct _reent *ptr _AND | ||||||
|  |        void *cookie) | ||||||
| { | { | ||||||
|   FILE *fp = (FILE *) cookie; |   FILE *fp = (FILE *) cookie; | ||||||
|  |  | ||||||
|   return _close_r (_REENT, fp->_file); |   return _close_r (ptr, fp->_file); | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifdef __SCLE | #ifdef __SCLE | ||||||
| @@ -126,6 +130,7 @@ _DEFUN(__stextmode, (fd), | |||||||
|        int fd) |        int fd) | ||||||
| { | { | ||||||
| #ifdef __CYGWIN__ | #ifdef __CYGWIN__ | ||||||
|  |   extern int _cygwin_istext_for_stdio (int); | ||||||
|   return _cygwin_istext_for_stdio (fd); |   return _cygwin_istext_for_stdio (fd); | ||||||
| #else | #else | ||||||
|   return 0; |   return 0; | ||||||
|   | |||||||
| @@ -29,7 +29,8 @@ | |||||||
| #include "local.h" | #include "local.h" | ||||||
|  |  | ||||||
| static _READ_WRITE_RETURN_TYPE | static _READ_WRITE_RETURN_TYPE | ||||||
| _DEFUN(eofread1, (cookie, buf, len), | _DEFUN(eofread1, (ptr, cookie, buf, len), | ||||||
|  |        struct _reent *ptr _AND | ||||||
|        _PTR cookie _AND |        _PTR cookie _AND | ||||||
|        char *buf   _AND |        char *buf   _AND | ||||||
|        int len) |        int len) | ||||||
|   | |||||||
| @@ -29,7 +29,8 @@ | |||||||
| #include "local.h" | #include "local.h" | ||||||
|  |  | ||||||
| static _READ_WRITE_RETURN_TYPE | static _READ_WRITE_RETURN_TYPE | ||||||
| _DEFUN(eofread1, (cookie, buf, len), | _DEFUN(eofread1, (ptr, cookie, buf, len), | ||||||
|  |        struct _reent *_ptr _AND | ||||||
|        _PTR cookie _AND |        _PTR cookie _AND | ||||||
|        char *buf   _AND |        char *buf   _AND | ||||||
|        int len) |        int len) | ||||||
|   | |||||||
| @@ -106,7 +106,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), | |||||||
|   if ((flags = __sflags (ptr, mode, &oflags)) == 0) |   if ((flags = __sflags (ptr, mode, &oflags)) == 0) | ||||||
|     { |     { | ||||||
|       _funlockfile(fp); |       _funlockfile(fp); | ||||||
|       (void) _fclose_r (ptr, fp); |       _fclose_r (ptr, fp); | ||||||
|       __sfp_lock_release (); |       __sfp_lock_release (); | ||||||
|       return NULL; |       return NULL; | ||||||
|     } |     } | ||||||
| @@ -124,13 +124,13 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), | |||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       if (fp->_flags & __SWR) |       if (fp->_flags & __SWR) | ||||||
| 	(void) fflush (fp); | 	 fflush (fp); | ||||||
|       /* |       /* | ||||||
|        * If close is NULL, closing is a no-op, hence pointless. |        * If close is NULL, closing is a no-op, hence pointless. | ||||||
|        * If file is NULL, the file should not be closed. |        * If file is NULL, the file should not be closed. | ||||||
|        */ |        */ | ||||||
|       if (fp->_close != NULL && file != NULL) |       if (fp->_close != NULL && file != NULL) | ||||||
| 	(void) (*fp->_close) (fp->_cookie); | 	fp->_close (ptr, fp->_cookie); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
| @@ -176,7 +176,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), | |||||||
| 	{ | 	{ | ||||||
| 	  e = EBADF; | 	  e = EBADF; | ||||||
| 	  if (fp->_close != NULL) | 	  if (fp->_close != NULL) | ||||||
|             (void) (*fp->_close) (fp->_cookie); | 	    fp->_close (ptr, fp->_cookie); | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -104,7 +104,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), | |||||||
|      _off64_t offset _AND |      _off64_t offset _AND | ||||||
|      int whence) |      int whence) | ||||||
| { | { | ||||||
|   _fpos64_t _EXFUN ((*seekfn), (void *, _fpos64_t, int)); |   _fpos64_t _EXFUN ((*seekfn), (struct _reent *, void *, _fpos64_t, int)); | ||||||
|   _fpos64_t target, curoff; |   _fpos64_t target, curoff; | ||||||
|   size_t n; |   size_t n; | ||||||
|  |  | ||||||
| @@ -155,7 +155,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), | |||||||
| 	curoff = fp->_offset; | 	curoff = fp->_offset; | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
| 	  curoff = (*seekfn) (fp->_cookie, (_fpos64_t) 0, SEEK_CUR); | 	  curoff = seekfn (ptr, fp->_cookie, (_fpos64_t) 0, SEEK_CUR); | ||||||
| 	  if (curoff == -1L) | 	  if (curoff == -1L) | ||||||
| 	    { | 	    { | ||||||
| 	      _funlockfile(fp); | 	      _funlockfile(fp); | ||||||
| @@ -238,7 +238,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), | |||||||
| 	curoff = fp->_offset; | 	curoff = fp->_offset; | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
| 	  curoff = (*seekfn) (fp->_cookie, (_fpos64_t)0, SEEK_CUR); | 	  curoff = seekfn (ptr, fp->_cookie, (_fpos64_t)0, SEEK_CUR); | ||||||
| 	  if (curoff == POS_ERR) | 	  if (curoff == POS_ERR) | ||||||
| 	    goto dumb; | 	    goto dumb; | ||||||
| 	} | 	} | ||||||
| @@ -299,7 +299,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), | |||||||
|    */ |    */ | ||||||
|  |  | ||||||
|   curoff = target & ~((_fpos64_t)(fp->_blksize - 1)); |   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; |     goto dumb; | ||||||
|   fp->_r = 0; |   fp->_r = 0; | ||||||
|   fp->_p = fp->_bf._base; |   fp->_p = fp->_bf._base; | ||||||
| @@ -323,7 +323,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), | |||||||
|    */ |    */ | ||||||
|  |  | ||||||
| dumb: | dumb: | ||||||
|   if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR) |   if (fflush (fp) || seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR) | ||||||
|     { |     { | ||||||
|       _funlockfile(fp); |       _funlockfile(fp); | ||||||
|       return EOF; |       return EOF; | ||||||
|   | |||||||
| @@ -111,7 +111,7 @@ _DEFUN (_ftello64_r, (ptr, fp), | |||||||
|     pos = fp->_offset; |     pos = fp->_offset; | ||||||
|   else |   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) |       if (pos == -1L) | ||||||
|         { |         { | ||||||
|           _funlockfile(fp); |           _funlockfile(fp); | ||||||
|   | |||||||
| @@ -26,11 +26,11 @@ | |||||||
|  |  | ||||||
| #ifdef __LARGE64_FILES | #ifdef __LARGE64_FILES | ||||||
| _fpos64_t | _fpos64_t | ||||||
| __sseek64_r (ptr, cookie, offset, whence) | _DEFUN(__sseek64, (ptr, cookie, offset, whence), | ||||||
|      struct _reent *ptr; |        struct _reent *ptr _AND | ||||||
|      _PTR cookie; |        void *cookie _AND | ||||||
|      _fpos64_t offset; |        _fpos64_t offset _AND | ||||||
|      int whence; |        int whence) | ||||||
| { | { | ||||||
|   register FILE *fp = (FILE *) cookie; |   register FILE *fp = (FILE *) cookie; | ||||||
|   register _off64_t ret; |   register _off64_t ret; | ||||||
| @@ -47,11 +47,11 @@ __sseek64_r (ptr, cookie, offset, whence) | |||||||
| } | } | ||||||
|  |  | ||||||
| _READ_WRITE_RETURN_TYPE | _READ_WRITE_RETURN_TYPE | ||||||
| __swrite64_r (ptr, cookie, buf, n) | _DEFUN(__swrite64, (ptr, cookie, buf, n), | ||||||
|      struct _reent *ptr; |        struct _reent *ptr _AND | ||||||
|      _PTR cookie; |        void *cookie _AND | ||||||
|      char _CONST *buf; |        char const *buf _AND | ||||||
|      int n; |        int n) | ||||||
| { | { | ||||||
|   register FILE *fp = (FILE *) cookie; |   register FILE *fp = (FILE *) cookie; | ||||||
|   int w; |   int w; | ||||||
| @@ -78,26 +78,4 @@ __swrite64_r (ptr, cookie, buf, n) | |||||||
|   return w; |   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 */ | #endif /* __LARGE64_FILES */ | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user