diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 174f0bbcf..b1a026f0b 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,17 @@ +2004-04-08 Artem B. Bityuckiy + + * libc/stdio/fclose.c (_fclose_r): New function. + * libc/stdio/freopen.c (_freopen_r): Call _fclose_r. + * libc/stdio/fcloseall.c (_fcloseall_r): Call _fwalk_reent. + * libc/stdio64/freopen64.c (_freopen64_r): Use _fclose_r. + * libc/include/stdio.h (_fclose_r): New prototype. + * libc/stdio/fopen.c: Fix typo in comment. + +2004-04-08 Jeff Johnston + + * libc/stdio/fwalk.c (_fwalk_reent): New version of _fwalk + to handle _r reentrant functions. + 2004-04-08 Eric Christopher * libc/include/machine/setjmp.h: Fix endif locations. diff --git a/newlib/libc/include/stdio.h b/newlib/libc/include/stdio.h index f1ee3ee4f..eb9f21c21 100644 --- a/newlib/libc/include/stdio.h +++ b/newlib/libc/include/stdio.h @@ -275,6 +275,7 @@ int _EXFUN(_asprintf_r, (struct _reent *, char **, const char *, ...)); int _EXFUN(_fcloseall_r, (struct _reent *)); FILE * _EXFUN(_fdopen_r, (struct _reent *, int, const char *)); FILE * _EXFUN(_fopen_r, (struct _reent *, const char *, const char *)); +int _EXFUN(_fclose_r, (struct _reent *, FILE *)); int _EXFUN(_fscanf_r, (struct _reent *, FILE *, const char *, ...)); int _EXFUN(_getchar_r, (struct _reent *)); char * _EXFUN(_gets_r, (struct _reent *, char *)); diff --git a/newlib/libc/stdio/fclose.c b/newlib/libc/stdio/fclose.c index a125f16ef..0f92e0777 100644 --- a/newlib/libc/stdio/fclose.c +++ b/newlib/libc/stdio/fclose.c @@ -4,21 +4,31 @@ FUNCTION INDEX fclose +INDEX + _fclose_r ANSI_SYNOPSIS #include int fclose(FILE *<[fp]>); + int _fclose_r(void *<[reent]>, FILE *<[fp]>); TRAD_SYNOPSIS #include int fclose(<[fp]>) FILE *<[fp]>; + + int fclose(<[fp]>) + void *<[reent]> + FILE *<[fp]>; DESCRIPTION If the file or stream identified by <[fp]> is open, <> closes it, after first ensuring that any pending data is written (by calling <)>>). +The alternate function <<_fclose_r>> is a reentrant version. +The extra argument <[reent]> is a pointer to a reentrancy structure. + RETURNS <> returns <<0>> if successful (including when <[fp]> is <> or not an open file); otherwise, it returns <>. @@ -47,6 +57,7 @@ Required OS subroutines: <>, <>, <>, <>, * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#include #include #include #include "local.h" @@ -57,8 +68,9 @@ Required OS subroutines: <>, <>, <>, <>, */ int -_DEFUN (fclose, (fp), - register FILE * fp) +_DEFUN (_fclose_r, (rptr, fp), + struct _reent *rptr _AND + register FILE * fp) { int r; @@ -81,7 +93,7 @@ _DEFUN (fclose, (fp), if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0) r = EOF; if (fp->_flags & __SMBF) - _free_r (_REENT, (char *) fp->_bf._base); + _free_r (rptr, (char *) fp->_bf._base); if (HASUB (fp)) FREEUB (fp); if (HASLB (fp)) @@ -96,3 +108,15 @@ _DEFUN (fclose, (fp), return (r); } + +#ifndef _REENT_ONLY + +int +_DEFUN (fclose, (fp), + register FILE * fp) +{ + return _fclose_r(_REENT, fp); +} + +#endif + diff --git a/newlib/libc/stdio/fcloseall.c b/newlib/libc/stdio/fcloseall.c index e5a3af277..58e61e4d0 100644 --- a/newlib/libc/stdio/fcloseall.c +++ b/newlib/libc/stdio/fcloseall.c @@ -66,7 +66,7 @@ int _fcloseall_r (ptr) struct _reent *ptr; { - return _fwalk (ptr, fclose); + return _fwalk_reent (ptr, _fclose_r); } #ifndef _REENT_ONLY diff --git a/newlib/libc/stdio/fopen.c b/newlib/libc/stdio/fopen.c index 844e6dc05..4e55129fc 100644 --- a/newlib/libc/stdio/fopen.c +++ b/newlib/libc/stdio/fopen.c @@ -38,7 +38,7 @@ TRAD_SYNOPSIS char *<[mode]>; FILE *_fopen_r(<[reent]>, <[file]>, <[mode]>) - char *<[reent]>; + void *<[reent]>; char *<[file]>; char *<[mode]>; diff --git a/newlib/libc/stdio/freopen.c b/newlib/libc/stdio/freopen.c index dd42aaae1..b0372b57c 100644 --- a/newlib/libc/stdio/freopen.c +++ b/newlib/libc/stdio/freopen.c @@ -96,7 +96,7 @@ _DEFUN (_freopen_r, (ptr, file, mode, fp), if ((flags = __sflags (ptr, mode, &oflags)) == 0) { _funlockfile(fp); - (void) fclose (fp); + (void) _fclose_r (ptr, fp); __sfp_lock_release (); return NULL; } diff --git a/newlib/libc/stdio/fwalk.c b/newlib/libc/stdio/fwalk.c index 566fa4af8..02a897094 100644 --- a/newlib/libc/stdio/fwalk.c +++ b/newlib/libc/stdio/fwalk.c @@ -48,6 +48,30 @@ __fwalk (ptr, function) return ret; } +/* Special version of __fwalk where the function pointer is a reentrant + I/O function (e.g. _fclose_r). */ +static int +__fwalk_reent (ptr, reent_function) + struct _reent *ptr; + register int (*reent_function) (); +{ + register FILE *fp; + register int n, ret = 0; + register struct _glue *g; + + for (g = &ptr->__sglue; g != NULL; g = g->_next) + for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) + if (fp->_flags != 0) + { + _flockfile (fp); + if (fp->_flags != 0 && fp->_file != -1) + ret |= (*reent_function) (ptr, fp); + _funlockfile (fp); + } + + return ret; +} + int _fwalk (ptr, function) struct _reent *ptr; @@ -68,3 +92,26 @@ _fwalk (ptr, function) return ret; } + +/* Special version of _fwalk which handles a function pointer to a + reentrant I/O function (e.g. _fclose_r). */ +int +_fwalk_reent (ptr, reent_function) + struct _reent *ptr; + register int (*reent_function) (); +{ + register int ret = 0; + + __sfp_lock_acquire (); + + /* Must traverse given list for std streams. */ + if (ptr != _GLOBAL_REENT) + ret |= __fwalk_reent (ptr, reent_function); + + /* Must traverse global list for all other streams. */ + ret |= __fwalk_reent (_GLOBAL_REENT, reent_function); + + __sfp_lock_release (); + + return ret; +} diff --git a/newlib/libc/stdio64/freopen64.c b/newlib/libc/stdio64/freopen64.c index c28cbeee2..42fe6fb22 100644 --- a/newlib/libc/stdio64/freopen64.c +++ b/newlib/libc/stdio64/freopen64.c @@ -98,7 +98,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), if ((flags = __sflags (ptr, mode, &oflags)) == 0) { _funlockfile(fp); - (void) fclose (fp); + (void) _fclose_r (ptr, fp); __sfp_lock_release (); return NULL; }