diff --git a/newlib/ChangeLog b/newlib/ChangeLog index c2b9ac63f..11d1b40c2 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,40 @@ +2007-06-04 Eric Blake + + 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 Avoid more compiler warnings. diff --git a/newlib/libc/include/stdio.h b/newlib/libc/include/stdio.h index 7c5247021..babb1c3c5 100644 --- a/newlib/libc/include/stdio.h +++ b/newlib/libc/include/stdio.h @@ -467,7 +467,7 @@ int _EXFUN(_fsetpos64_r, (struct _reent *, FILE *, const _fpos64_t *)); FILE * _EXFUN(_tmpfile64_r, (struct _reent *)); #endif /* !__CYGWIN__ */ #endif /* __LARGE64_FILES */ - + /* * Routines internal to the implementation. */ @@ -480,15 +480,47 @@ int _EXFUN(__swbuf_r, (struct _reent *, int, FILE *)); */ #ifndef __STRICT_ANSI__ -FILE *_EXFUN(funopen,(const _PTR _cookie, - int (*readfn)(_PTR _cookie, char *_buf, int _n), - int (*writefn)(_PTR _cookie, const char *_buf, int _n), - fpos_t (*seekfn)(_PTR _cookie, fpos_t _off, int _whence), - int (*closefn)(_PTR _cookie))); +# ifdef __LARGE64_FILES +FILE *_EXFUN(funopen,(const _PTR __cookie, + int (*__readfn)(_PTR __c, char *__buf, int __n), + int (*__writefn)(_PTR __c, const char *__buf, int __n), + _fpos64_t (*__seekfn)(_PTR __c, _fpos64_t __off, int __whence), + int (*__closefn)(_PTR __c))); +# else +FILE *_EXFUN(funopen,(const _PTR __cookie, + int (*__readfn)(_PTR __cookie, char *__buf, int __n), + int (*__writefn)(_PTR __cookie, const char *__buf, int __n), + fpos_t (*__seekfn)(_PTR __cookie, fpos_t __off, int __whence), + int (*__closefn)(_PTR __cookie))); +# endif /* !__LARGE64_FILES */ -#define fropen(cookie, fn) funopen(cookie, fn, (int (*)())0, (fpos_t (*)())0, (int (*)())0) -#define fwopen(cookie, fn) funopen(cookie, (int (*)())0, fn, (fpos_t (*)())0, (int (*)())0) -#endif +# define fropen(__cookie, __fn) funopen(__cookie, __fn, (int (*)())0, \ + (fpos_t (*)())0, (int (*)())0) +# define fwopen(__cookie, __fn) funopen(__cookie, (int (*)())0, __fn, \ + (fpos_t (*)())0, (int (*)())0) + +typedef ssize_t cookie_read_function_t(void *__cookie, char *__buf, size_t __n); +typedef ssize_t cookie_write_function_t(void *__cookie, const char *__buf, + size_t __n); +# ifdef __LARGE64_FILES +typedef int cookie_seek_function_t(void *__cookie, _off64_t *__off, + int __whence); +# else +typedef int cookie_seek_function_t(void *__cookie, off_t *__off, int __whence); +# endif /* !__LARGE64_FILES */ +typedef int cookie_close_function_t(void *__cookie); +typedef struct +{ + /* These four struct member names are dictated by Linux; hopefully, + they don't conflict with any macros. */ + cookie_read_function_t *read; + cookie_write_function_t *write; + cookie_seek_function_t *seek; + cookie_close_function_t *close; +} cookie_io_functions_t; +FILE *_EXFUN(fopencookie,(void *__cookie, const char *__mode, + cookie_io_functions_t __functions)); +#endif /* ! __STRICT_ANSI__ */ #ifndef __CUSTOM_FILE_IO__ /* diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h index 93c79ffc7..06d025bb5 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -34,6 +34,8 @@ typedef unsigned __Long __ULong; typedef __uint32_t __ULong; #endif +struct _reent; + /* * If _REENT_SMALL is defined, we make struct _reent as small as possible, * by having nearly everything possible allocated at first use. @@ -181,11 +183,12 @@ struct __sFILE { /* operations */ _PTR _cookie; /* cookie passed to io functions */ - _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); - _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, - int _n)); - _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); - int _EXFUN((*_close),(_PTR _cookie)); + _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(struct _reent *, _PTR, + char *, int)); + _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *, _PTR, + const char *, int)); + _fpos_t _EXFUN((*_seek),(struct _reent *, _PTR, _fpos_t, int)); + int _EXFUN((*_close),(struct _reent *, _PTR)); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ @@ -233,11 +236,12 @@ struct __sFILE64 { /* operations */ _PTR _cookie; /* cookie passed to io functions */ - _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); - _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, - int _n)); - _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); - int _EXFUN((*_close),(_PTR _cookie)); + _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(struct _reent *, _PTR, + char *, int)); + _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(struct _reent *, _PTR, + const char *, int)); + _fpos_t _EXFUN((*_seek),(struct _reent *, _PTR, _fpos_t, int)); + int _EXFUN((*_close),(struct _reent *, _PTR)); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ @@ -256,7 +260,7 @@ struct __sFILE64 { int _flags2; /* for future use */ _off64_t _offset; /* current lseek offset */ - _fpos64_t _EXFUN((*_seek64),(_PTR _cookie, _fpos64_t _offset, int _whence)); + _fpos64_t _EXFUN((*_seek64),(struct _reent *, _PTR, _fpos64_t, int)); #ifndef __SINGLE_THREAD__ _flock_t _lock; /* for thread-safety locking */ diff --git a/newlib/libc/stdio/Makefile.am b/newlib/libc/stdio/Makefile.am index 1e7a9bb5a..39617d2bd 100644 --- a/newlib/libc/stdio/Makefile.am +++ b/newlib/libc/stdio/Makefile.am @@ -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 diff --git a/newlib/libc/stdio/Makefile.in b/newlib/libc/stdio/Makefile.in index 53ba0a794..27fbd9a68 100644 --- a/newlib/libc/stdio/Makefile.in +++ b/newlib/libc/stdio/Makefile.in @@ -110,6 +110,8 @@ am__objects_1 = lib_a-clearerr.$(OBJEXT) lib_a-fclose.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-asnprintf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-diprintf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-dprintf.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fopencookie.$(OBJEXT) \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-funopen.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vasniprintf.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-vasnprintf.$(OBJEXT) @USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) \ @@ -139,6 +141,8 @@ am__objects_4 = clearerr.lo fclose.lo fdopen.lo feof.lo ferror.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ asnprintf.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ diprintf.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ dprintf.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fopencookie.lo \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ funopen.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasniprintf.lo \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasnprintf.lo @USE_LIBTOOL_TRUE@am_libstdio_la_OBJECTS = $(am__objects_4) \ @@ -419,6 +423,8 @@ GENERAL_SOURCES = \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ asnprintf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ diprintf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ dprintf.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fopencookie.c \ +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ funopen.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasniprintf.c \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ vasnprintf.c @@ -459,6 +465,7 @@ CHEWOUT_FILES = \ fileno.def \ fiprintf.def \ fopen.def \ + fopencookie.def \ fputc.def \ fputs.def \ fread.def \ @@ -466,6 +473,7 @@ CHEWOUT_FILES = \ fseek.def \ fsetpos.def \ ftell.def \ + funopen.def \ fwrite.def \ getc.def \ getchar.def \ @@ -1130,6 +1138,18 @@ lib_a-dprintf.o: dprintf.c lib_a-dprintf.obj: dprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dprintf.obj `if test -f 'dprintf.c'; then $(CYGPATH_W) 'dprintf.c'; else $(CYGPATH_W) '$(srcdir)/dprintf.c'; fi` +lib_a-fopencookie.o: fopencookie.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fopencookie.o `test -f 'fopencookie.c' || echo '$(srcdir)/'`fopencookie.c + +lib_a-fopencookie.obj: fopencookie.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fopencookie.obj `if test -f 'fopencookie.c'; then $(CYGPATH_W) 'fopencookie.c'; else $(CYGPATH_W) '$(srcdir)/fopencookie.c'; fi` + +lib_a-funopen.o: funopen.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-funopen.o `test -f 'funopen.c' || echo '$(srcdir)/'`funopen.c + +lib_a-funopen.obj: funopen.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-funopen.obj `if test -f 'funopen.c'; then $(CYGPATH_W) 'funopen.c'; else $(CYGPATH_W) '$(srcdir)/funopen.c'; fi` + lib_a-vasniprintf.o: vasniprintf.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-vasniprintf.o `test -f 'vasniprintf.c' || echo '$(srcdir)/'`vasniprintf.c @@ -1323,11 +1343,13 @@ $(lpfx)fdopen.$(oext): local.h $(lpfx)fflush.$(oext): local.h $(lpfx)findfp.$(oext): local.h $(lpfx)fopen.$(oext): local.h +$(lpfx)fopencookie.$(oext): local.h $(lpfx)fputs.$(oext): fvwrite.h $(lpfx)fread.$(oext): local.h $(lpfx)freopen.$(oext): local.h $(lpfx)fseek.$(oext): local.h $(lpfx)ftell.$(oext): local.h +$(lpfx)funopen.$(oext): local.h $(lpfx)fvwrite.$(oext): local.h fvwrite.h $(lpfx)fwalk.$(oext): local.h $(lpfx)fwrite.$(oext): local.h fvwrite.h diff --git a/newlib/libc/stdio/fclose.c b/newlib/libc/stdio/fclose.c index d7cfdafa5..18cddf0c8 100644 --- a/newlib/libc/stdio/fclose.c +++ b/newlib/libc/stdio/fclose.c @@ -33,7 +33,7 @@ TRAD_SYNOPSIS #include int fclose(<[fp]>) FILE *<[fp]>; - + int fclose(<[fp]>) struct _reent *<[reent]> FILE *<[fp]>; @@ -79,7 +79,7 @@ _DEFUN(_fclose_r, (rptr, fp), CHECK_INIT (rptr, fp); _flockfile (fp); - + if (fp->_flags == 0) /* not open! */ { _funlockfile (fp); @@ -90,7 +90,7 @@ _DEFUN(_fclose_r, (rptr, fp), files to reposition file to last byte processed as opposed to last byte read ahead into the buffer. */ r = fflush (fp); - if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0) + if (fp->_close != NULL && fp->_close (rptr, fp->_cookie) < 0) r = EOF; if (fp->_flags & __SMBF) _free_r (rptr, (char *) fp->_bf._base); diff --git a/newlib/libc/stdio/fflush.c b/newlib/libc/stdio/fflush.c index d46b41f94..d375d9509 100644 --- a/newlib/libc/stdio/fflush.c +++ b/newlib/libc/stdio/fflush.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1990, 2006 The Regents of the University of California. + * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted @@ -90,7 +90,7 @@ _DEFUN(fflush, (fp), t = fp->_flags; if ((t & __SWR) == 0) { - _fpos_t _EXFUN((*seekfn), (_PTR, _fpos_t, int)); + _fpos_t _EXFUN((*seekfn), (struct _reent *, _PTR, _fpos_t, int)); /* For a read stream, an fflush causes the next seek to be unoptimized (i.e. forces a system-level seek). This conforms @@ -114,7 +114,7 @@ _DEFUN(fflush, (fp), else { /* We don't know current physical offset, so ask for it. */ - curoff = (*seekfn) (fp->_cookie, (_fpos_t) 0, SEEK_CUR); + curoff = seekfn (_REENT, fp->_cookie, (_fpos_t) 0, SEEK_CUR); if (curoff == -1L) { _funlockfile (fp); @@ -130,7 +130,7 @@ _DEFUN(fflush, (fp), curoff -= fp->_ur; } /* Now physically seek to after byte last read. */ - if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) != -1) + if (seekfn (_REENT, fp->_cookie, curoff, SEEK_SET) != -1) { /* Seek successful. We can clear read buffer now. */ fp->_flags &= ~__SNPT; @@ -139,7 +139,7 @@ _DEFUN(fflush, (fp), if (fp->_flags & __SOFF) fp->_offset = curoff; } - } + } _funlockfile (fp); return 0; } @@ -161,7 +161,7 @@ _DEFUN(fflush, (fp), while (n > 0) { - t = (*fp->_write) (fp->_cookie, (char *) p, n); + t = fp->_write (_REENT, fp->_cookie, (char *) p, n); if (t <= 0) { fp->_flags |= __SERR; diff --git a/newlib/libc/stdio/flags.c b/newlib/libc/stdio/flags.c index d7bf52b97..26d2f82fd 100644 --- a/newlib/libc/stdio/flags.c +++ b/newlib/libc/stdio/flags.c @@ -62,7 +62,7 @@ _DEFUN(__sflags, (ptr, mode, optr), } if (mode[1] && (mode[1] == '+' || mode[2] == '+')) { - ret = __SRW; + ret = (ret & ~(__SRD | __SWR)) | __SRW; m = O_RDWR; } if (mode[1] && (mode[1] == 'b' || mode[2] == 'b')) diff --git a/newlib/libc/stdio/fopencookie.c b/newlib/libc/stdio/fopencookie.c new file mode 100644 index 000000000..581441be0 --- /dev/null +++ b/newlib/libc/stdio/fopencookie.c @@ -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 +<>---open a stream with custom callbacks + +INDEX + fopencookie + +ANSI_SYNOPSIS + #include + 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 +<> creates a <> stream where I/O is performed using +custom callbacks. The stream is opened with <[mode]> treated as in +<>. 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 <>, 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 <>, 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 +<> and <>, 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 <>, except that <[cookie]> will be passed as the +first argument. A NULL <[functions.close]> merely flushes all data +then lets <> 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 +<>. 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, +<> is returned, and <> 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 <> interface from BSD. + +Supporting OS subroutines required: <>. +*/ + +#include +#include +#include +#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 */ diff --git a/newlib/libc/stdio/freopen.c b/newlib/libc/stdio/freopen.c index 6d885db2c..f6d658c63 100644 --- a/newlib/libc/stdio/freopen.c +++ b/newlib/libc/stdio/freopen.c @@ -28,8 +28,8 @@ ANSI_SYNOPSIS #include FILE *freopen(const char *<[file]>, const char *<[mode]>, FILE *<[fp]>); - FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>, - const char *<[mode]>, FILE *<[fp]>); + FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>, + const char *<[mode]>, FILE *<[fp]>); TRAD_SYNOPSIS #include @@ -89,8 +89,8 @@ Supporting OS subroutines required: <>, <>, <>, FILE * _DEFUN(_freopen_r, (ptr, file, mode, fp), struct _reent *ptr _AND - _CONST char *file _AND - _CONST char *mode _AND + const char *file _AND + const char *mode _AND register FILE *fp) { register int f; @@ -106,7 +106,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), if ((flags = __sflags (ptr, mode, &oflags)) == 0) { _funlockfile (fp); - _CAST_VOID _fclose_r (ptr, fp); + _fclose_r (ptr, fp); __sfp_lock_release (); return NULL; } @@ -124,13 +124,13 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), else { if (fp->_flags & __SWR) - _CAST_VOID fflush (fp); + fflush (fp); /* * If close is NULL, closing is a no-op, hence pointless. * If file is NULL, the file should not be closed. */ if (fp->_close != NULL && file != NULL) - _CAST_VOID (*fp->_close) (fp->_cookie); + fp->_close (ptr, fp->_cookie); } /* @@ -154,10 +154,10 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), */ f = fp->_file; if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1 - || ! ((oldflags & O_ACCMODE) == O_RDWR - || ((oldflags ^ oflags) & O_ACCMODE) == 0) - || _fcntl_r (ptr, f, F_SETFL, oflags) == -1) - f = -1; + || ! ((oldflags & O_ACCMODE) == O_RDWR + || ((oldflags ^ oflags) & O_ACCMODE) == 0) + || _fcntl_r (ptr, f, F_SETFL, oflags) == -1) + f = -1; #else /* We cannot modify without fcntl support. */ f = -1; @@ -168,16 +168,16 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp), * F_SETFL doesn't change textmode. Don't mess with modes of ttys. */ if (0 <= f && ! isatty (f) - && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1) - f = -1; + && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1) + f = -1; #endif if (f < 0) - { - e = EBADF; - if (fp->_close != NULL) - _CAST_VOID (*fp->_close) (fp->_cookie); - } + { + e = EBADF; + if (fp->_close != NULL) + fp->_close (ptr, fp->_cookie); + } } /* diff --git a/newlib/libc/stdio/fseek.c b/newlib/libc/stdio/fseek.c index e1670e1a1..028c62a3f 100644 --- a/newlib/libc/stdio/fseek.c +++ b/newlib/libc/stdio/fseek.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1990, 2007 The Regents of the University of California. + * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted @@ -122,7 +122,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), long offset _AND int whence) { - _fpos_t _EXFUN((*seekfn), (_PTR, _fpos_t, int)); + _fpos_t _EXFUN((*seekfn), (struct _reent *, _PTR, _fpos_t, int)); _fpos_t target; _fpos_t curoff = 0; size_t n; @@ -175,7 +175,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), curoff = fp->_offset; else { - curoff = (*seekfn) (fp->_cookie, (_fpos_t) 0, SEEK_CUR); + curoff = seekfn (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR); if (curoff == -1L) { _funlockfile (fp); @@ -259,6 +259,11 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), goto dumb; target = st.st_size + offset; } + if ((long)target != target) + { + ptr->_errno = EOVERFLOW; + return EOF; + } if (!havepos) { @@ -266,7 +271,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), curoff = fp->_offset; else { - curoff = (*seekfn) (fp->_cookie, 0L, SEEK_CUR); + curoff = seekfn (ptr, fp->_cookie, 0L, SEEK_CUR); if (curoff == POS_ERR) goto dumb; } @@ -327,7 +332,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), */ curoff = target & ~(fp->_blksize - 1); - if ((*seekfn) (fp->_cookie, curoff, SEEK_SET) == POS_ERR) + if (seekfn (ptr, fp->_cookie, curoff, SEEK_SET) == POS_ERR) goto dumb; fp->_r = 0; fp->_p = fp->_bf._base; @@ -351,7 +356,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence), */ dumb: - if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR) + if (fflush (fp) || seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR) { _funlockfile (fp); return EOF; diff --git a/newlib/libc/stdio/ftell.c b/newlib/libc/stdio/ftell.c index de5d55d44..b77879d73 100644 --- a/newlib/libc/stdio/ftell.c +++ b/newlib/libc/stdio/ftell.c @@ -125,7 +125,7 @@ _DEFUN(_ftell_r, (ptr, fp), pos = fp->_offset; else { - pos = (*fp->_seek) (fp->_cookie, (_fpos_t) 0, SEEK_CUR); + pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR); if (pos == -1L) { _funlockfile (fp); @@ -154,6 +154,11 @@ _DEFUN(_ftell_r, (ptr, fp), } _funlockfile (fp); + if ((long)pos != pos) + { + pos = -1; + ptr->_errno = EOVERFLOW; + } return pos; } diff --git a/newlib/libc/stdio/funopen.c b/newlib/libc/stdio/funopen.c new file mode 100644 index 000000000..35a274f7b --- /dev/null +++ b/newlib/libc/stdio/funopen.c @@ -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 +<>, <>, <>---open a stream with custom callbacks + +INDEX + funopen +INDEX + fropen +INDEX + fwopen + +ANSI_SYNOPSIS + #include + 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 +<> creates a <> 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 <>, except that rather +than 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 <>, except that rather than + 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 <>, 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 <>, except that <[cookie]> will be passed as the +first argument. A NULL <[closefn]> merely flushes all data then lets +<> 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 +<>. 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 <> and <> are convenience macros around +<> that only use the specified callback. + +RETURNS +The return value is an open FILE pointer on success. On error, +<> is returned, and <> 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 <> interface from Linux. + +Supporting OS subroutines required: <>. +*/ + +#include +#include +#include +#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 */ diff --git a/newlib/libc/stdio/fvwrite.c b/newlib/libc/stdio/fvwrite.c index 031624d92..75fc8347b 100644 --- a/newlib/libc/stdio/fvwrite.c +++ b/newlib/libc/stdio/fvwrite.c @@ -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; } diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h index 0dba774ae..f02f91d57 100644 --- a/newlib/libc/stdio/local.h +++ b/newlib/libc/stdio/local.h @@ -25,19 +25,25 @@ #include <_ansi.h> #include #include -#include #include #include +#include +#ifdef __SCLE +# include +#endif + extern int _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); extern int _EXFUN(__svfiscanf_r,(struct _reent *,FILE *, _CONST char *,va_list)); extern FILE *_EXFUN(__sfp,(struct _reent *)); extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); extern int _EXFUN(__srefill_r,(struct _reent *,FILE *)); -extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(_PTR, char *, int)); -extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(_PTR, char _CONST *, int)); -extern _fpos_t _EXFUN(__sseek,(_PTR, _fpos_t, int)); -extern int _EXFUN(__sclose,(_PTR)); +extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *, + int)); +extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite,(struct _reent *, void *, + const char *, int)); +extern _fpos_t _EXFUN(__sseek,(struct _reent *, void *, _fpos_t, int)); +extern int _EXFUN(__sclose,(struct _reent *, void *)); extern int _EXFUN(__stextmode,(int)); extern _VOID _EXFUN(__sinit,(struct _reent *)); extern _VOID _EXFUN(_cleanup_r,(struct _reent *)); @@ -47,11 +53,9 @@ extern int _EXFUN(_fwalk_reent,(struct _reent *, int (*)(struct _reent *, FIL struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n)); #ifdef __LARGE64_FILES -extern _fpos64_t _EXFUN(__sseek64,(void *, _fpos64_t, int)); -extern _fpos64_t _EXFUN(__sseek64_r,(struct _reent *, void *, _fpos64_t, int)); -extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(void *, char const *, int)); -extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64_r,(struct _reent *, void *, - char const *, int)); +extern _fpos64_t _EXFUN(__sseek64,(struct _reent *, void *, _fpos64_t, int)); +extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *, + const char *, int)); #endif /* Called by the main entry point fns to ensure stdio has been initialized. */ diff --git a/newlib/libc/stdio/refill.c b/newlib/libc/stdio/refill.c index 71a1e565f..f4644ce96 100644 --- a/newlib/libc/stdio/refill.c +++ b/newlib/libc/stdio/refill.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1990, 2007 The Regents of the University of California. + * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted @@ -104,7 +104,7 @@ _DEFUN(__srefill_r, (ptr, fp), if (fp->_flags & (__SLBF | __SNBF)) _CAST_VOID _fwalk (_GLOBAL_REENT, lflush); fp->_p = fp->_bf._base; - fp->_r = (*fp->_read) (fp->_cookie, (char *) fp->_p, fp->_bf._size); + fp->_r = fp->_read (ptr, fp->_cookie, (char *) fp->_p, fp->_bf._size); fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ #ifndef __CYGWIN__ if (fp->_r <= 0) diff --git a/newlib/libc/stdio/siscanf.c b/newlib/libc/stdio/siscanf.c index 694750dae..2c69921ff 100644 --- a/newlib/libc/stdio/siscanf.c +++ b/newlib/libc/stdio/siscanf.c @@ -112,7 +112,8 @@ Supporting OS subroutines required: <>, <>, <>, /* | 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) diff --git a/newlib/libc/stdio/sscanf.c b/newlib/libc/stdio/sscanf.c index b74dd3ebe..a1987c58d 100644 --- a/newlib/libc/stdio/sscanf.c +++ b/newlib/libc/stdio/sscanf.c @@ -393,7 +393,8 @@ Supporting OS subroutines required: <>, <>, <>, /* | 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) diff --git a/newlib/libc/stdio/stdio.c b/newlib/libc/stdio/stdio.c index 8bc736088..3cf3ea728 100644 --- a/newlib/libc/stdio/stdio.c +++ b/newlib/libc/stdio/stdio.c @@ -30,9 +30,10 @@ */ _READ_WRITE_RETURN_TYPE -_DEFUN(__sread, (cookie, buf, n), - _PTR cookie _AND - char *buf _AND +_DEFUN(__sread, (ptr, cookie, buf, n), + struct _reent *ptr _AND + void *cookie _AND + char *buf _AND int n) { register FILE *fp = (FILE *) cookie; @@ -44,7 +45,7 @@ _DEFUN(__sread, (cookie, buf, n), oldmode = setmode (fp->_file, O_BINARY); #endif - ret = _read_r (_REENT, fp->_file, buf, n); + ret = _read_r (ptr, fp->_file, buf, n); #ifdef __SCLE if (oldmode) @@ -61,9 +62,10 @@ _DEFUN(__sread, (cookie, buf, n), } _READ_WRITE_RETURN_TYPE -_DEFUN(__swrite, (cookie, buf, n), - _PTR cookie _AND - char _CONST *buf _AND +_DEFUN(__swrite, (ptr, cookie, buf, n), + struct _reent *ptr _AND + void *cookie _AND + char const *buf _AND int n) { register FILE *fp = (FILE *) cookie; @@ -73,7 +75,7 @@ _DEFUN(__swrite, (cookie, buf, n), #endif if (fp->_flags & __SAPP) - _CAST_VOID _lseek_r (_REENT, fp->_file, (_off_t) 0, SEEK_END); + _lseek_r (ptr, fp->_file, (_off_t) 0, SEEK_END); fp->_flags &= ~__SOFF; /* in case O_APPEND mode is set */ #ifdef __SCLE @@ -81,7 +83,7 @@ _DEFUN(__swrite, (cookie, buf, n), oldmode = setmode (fp->_file, O_BINARY); #endif - w = _write_r (_REENT, fp->_file, buf, n); + w = _write_r (ptr, fp->_file, buf, n); #ifdef __SCLE if (oldmode) @@ -92,15 +94,16 @@ _DEFUN(__swrite, (cookie, buf, n), } _fpos_t -_DEFUN(__sseek, (cookie, offset, whence), - _PTR cookie _AND +_DEFUN(__sseek, (ptr, cookie, offset, whence), + struct _reent *ptr _AND + void *cookie _AND _fpos_t offset _AND int whence) { register FILE *fp = (FILE *) cookie; register _off_t ret; - ret = _lseek_r (_REENT, fp->_file, (_off_t) offset, whence); + ret = _lseek_r (ptr, fp->_file, (_off_t) offset, whence); if (ret == -1L) fp->_flags &= ~__SOFF; else @@ -112,20 +115,22 @@ _DEFUN(__sseek, (cookie, offset, whence), } int -_DEFUN(__sclose, (cookie), - _PTR cookie) +_DEFUN(__sclose, (ptr, cookie), + struct _reent *ptr _AND + void *cookie) { FILE *fp = (FILE *) cookie; - return _close_r (_REENT, fp->_file); + return _close_r (ptr, fp->_file); } #ifdef __SCLE int -_DEFUN(__stextmode, (fd), +_DEFUN(__stextmode, (fd), int fd) { #ifdef __CYGWIN__ + extern int _cygwin_istext_for_stdio (int); return _cygwin_istext_for_stdio (fd); #else return 0; diff --git a/newlib/libc/stdio/vsiscanf.c b/newlib/libc/stdio/vsiscanf.c index c6201847a..ffbf22e97 100644 --- a/newlib/libc/stdio/vsiscanf.c +++ b/newlib/libc/stdio/vsiscanf.c @@ -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) diff --git a/newlib/libc/stdio/vsscanf.c b/newlib/libc/stdio/vsscanf.c index 22ed9cdf7..9bb7c0c3e 100644 --- a/newlib/libc/stdio/vsscanf.c +++ b/newlib/libc/stdio/vsscanf.c @@ -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) diff --git a/newlib/libc/stdio64/freopen64.c b/newlib/libc/stdio64/freopen64.c index 10a45e4ed..0362407e9 100644 --- a/newlib/libc/stdio64/freopen64.c +++ b/newlib/libc/stdio64/freopen64.c @@ -106,7 +106,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), if ((flags = __sflags (ptr, mode, &oflags)) == 0) { _funlockfile(fp); - (void) _fclose_r (ptr, fp); + _fclose_r (ptr, fp); __sfp_lock_release (); return NULL; } @@ -124,13 +124,13 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), else { if (fp->_flags & __SWR) - (void) fflush (fp); + fflush (fp); /* * If close is NULL, closing is a no-op, hence pointless. * If file is NULL, the file should not be closed. */ if (fp->_close != NULL && file != NULL) - (void) (*fp->_close) (fp->_cookie); + fp->_close (ptr, fp->_cookie); } /* @@ -154,10 +154,10 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), */ f = fp->_file; if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1 - || ! ((oldflags & O_ACCMODE) == O_RDWR - || ((oldflags ^ oflags) & O_ACCMODE) == 0) - || _fcntl_r (ptr, f, F_SETFL, oflags) == -1) - f = -1; + || ! ((oldflags & O_ACCMODE) == O_RDWR + || ((oldflags ^ oflags) & O_ACCMODE) == 0) + || _fcntl_r (ptr, f, F_SETFL, oflags) == -1) + f = -1; #else /* We cannot modify without fcntl support. */ f = -1; @@ -168,16 +168,16 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), * F_SETFL doesn't change textmode. Don't mess with modes of ttys. */ if (0 <= f && ! isatty (f) - && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1) - f = -1; + && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1) + f = -1; #endif if (f < 0) - { - e = EBADF; - if (fp->_close != NULL) - (void) (*fp->_close) (fp->_cookie); - } + { + e = EBADF; + if (fp->_close != NULL) + fp->_close (ptr, fp->_cookie); + } } /* diff --git a/newlib/libc/stdio64/fseeko64.c b/newlib/libc/stdio64/fseeko64.c index 33e22dcc5..fe07bfe2d 100644 --- a/newlib/libc/stdio64/fseeko64.c +++ b/newlib/libc/stdio64/fseeko64.c @@ -104,7 +104,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), _off64_t offset _AND int whence) { - _fpos64_t _EXFUN ((*seekfn), (void *, _fpos64_t, int)); + _fpos64_t _EXFUN ((*seekfn), (struct _reent *, void *, _fpos64_t, int)); _fpos64_t target, curoff; size_t n; @@ -155,7 +155,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), curoff = fp->_offset; else { - curoff = (*seekfn) (fp->_cookie, (_fpos64_t) 0, SEEK_CUR); + curoff = seekfn (ptr, fp->_cookie, (_fpos64_t) 0, SEEK_CUR); if (curoff == -1L) { _funlockfile(fp); @@ -238,7 +238,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), curoff = fp->_offset; else { - curoff = (*seekfn) (fp->_cookie, (_fpos64_t)0, SEEK_CUR); + curoff = seekfn (ptr, fp->_cookie, (_fpos64_t)0, SEEK_CUR); if (curoff == POS_ERR) goto dumb; } @@ -299,7 +299,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), */ curoff = target & ~((_fpos64_t)(fp->_blksize - 1)); - if ((*seekfn) (fp->_cookie, curoff, SEEK_SET) == POS_ERR) + if (seekfn (ptr, fp->_cookie, curoff, SEEK_SET) == POS_ERR) goto dumb; fp->_r = 0; fp->_p = fp->_bf._base; @@ -323,7 +323,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence), */ dumb: - if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR) + if (fflush (fp) || seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR) { _funlockfile(fp); return EOF; diff --git a/newlib/libc/stdio64/ftello64.c b/newlib/libc/stdio64/ftello64.c index cad175b87..b596d3234 100644 --- a/newlib/libc/stdio64/ftello64.c +++ b/newlib/libc/stdio64/ftello64.c @@ -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); diff --git a/newlib/libc/stdio64/stdio64.c b/newlib/libc/stdio64/stdio64.c index 35967ad99..f33a394a7 100644 --- a/newlib/libc/stdio64/stdio64.c +++ b/newlib/libc/stdio64/stdio64.c @@ -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 */ -