From 7a7e4d4d95e878c62ea5b642da864018b50aae21 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 17 Jan 2014 10:55:32 +0000 Subject: Introduce _STDIO_BSD_SEMANTICS flag to switch fclose/exit file flushing semantics from POSIX to BSD. * libc/stdio/fclose.c (_fclose_r): Conditionalize file flushing on _STDIO_BSD_SEMANTICS. Call __sflush_r rather than _fflush_r. Add comment. * libc/stdio/fflush.c (__sflushw_r): New function, only available if _STDIO_BSD_SEMANTICS is defined. * libc/stdio/findfp.c (_cleanup_r): Call _fwalk_reent rather than _fwalk. Conditionalize cleanup function call on _STDIO_BSD_SEMANTICS. Add comments. Add FIXME. * libc/stdio/local.h (__sflushw_r): Declare if _STDIO_BSD_SEMANTICS is defined. --- newlib/ChangeLog | 15 +++++++++++++++ newlib/libc/stdio/fclose.c | 13 +++++++++---- newlib/libc/stdio/fflush.c | 13 +++++++++++++ newlib/libc/stdio/findfp.c | 13 +++++++++++-- newlib/libc/stdio/local.h | 3 +++ 5 files changed, 51 insertions(+), 6 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 97e4f2ac6..526717f85 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,18 @@ +2014-01-17 Corinna Vinschen + + Introduce _STDIO_BSD_SEMANTICS flag to switch fclose/exit file flushing + semantics from POSIX to BSD. + * libc/stdio/fclose.c (_fclose_r): Conditionalize file flushing on + _STDIO_BSD_SEMANTICS. Call __sflush_r rather than _fflush_r. Add + comment. + * libc/stdio/fflush.c (__sflushw_r): New function, only available + if _STDIO_BSD_SEMANTICS is defined. + * libc/stdio/findfp.c (_cleanup_r): Call _fwalk_reent rather than + _fwalk. Conditionalize cleanup function call on _STDIO_BSD_SEMANTICS. + Add comments. Add FIXME. + * libc/stdio/local.h (__sflushw_r): Declare if _STDIO_BSD_SEMANTICS is + defined. + 2014-01-06 Sebastian Huber * libc/include/sys/_default_fcntl.h (AT_FDCWD): Define according diff --git a/newlib/libc/stdio/fclose.c b/newlib/libc/stdio/fclose.c index fd054feaa..cd271c490 100644 --- a/newlib/libc/stdio/fclose.c +++ b/newlib/libc/stdio/fclose.c @@ -92,10 +92,15 @@ _DEFUN(_fclose_r, (rptr, fp), #endif return (0); } - /* Unconditionally flush to allow special handling for seekable read - files to reposition file to last byte processed as opposed to - last byte read ahead into the buffer. */ - r = _fflush_r (rptr, fp); +#ifdef _STDIO_BSD_SEMANTICS + /* BSD and Glibc systems only flush streams which have been written to. */ + r = (fp->_flags & __SWR) ? __sflush_r (rptr, fp) : 0; +#else + /* Follow POSIX semantics exactly. Unconditionally flush to allow + special handling for seekable read files to reposition file to last + byte processed as opposed to last byte read ahead into the buffer. */ + r = __sflush_r (rptr, fp); +#endif if (fp->_close != NULL && fp->_close (rptr, fp->_cookie) < 0) r = EOF; if (fp->_flags & __SMBF) diff --git a/newlib/libc/stdio/fflush.c b/newlib/libc/stdio/fflush.c index ea48b0126..2286e3878 100644 --- a/newlib/libc/stdio/fflush.c +++ b/newlib/libc/stdio/fflush.c @@ -204,6 +204,19 @@ _DEFUN(__sflush_r, (ptr, fp), return 0; } +#ifdef _STDIO_BSD_SEMANTICS +/* Called from _cleanup_r. At exit time, we don't need file locking, + and we don't want to move the underlying file pointer unless we're + writing. */ +int +_DEFUN(__sflushw_r, (ptr, fp), + struct _reent *ptr _AND + register FILE *fp) +{ + return (fp->_flags & __SWR) ? __sflush_r (ptr, fp) : 0; +} +#endif + int _DEFUN(_fflush_r, (ptr, fp), struct _reent *ptr _AND diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c index e40500a07..f5a35a162 100644 --- a/newlib/libc/stdio/findfp.c +++ b/newlib/libc/stdio/findfp.c @@ -170,8 +170,17 @@ _VOID _DEFUN(_cleanup_r, (ptr), struct _reent *ptr) { - _CAST_VOID _fwalk(ptr, fclose); - /* _CAST_VOID _fwalk (ptr, fflush); */ /* `cheating' */ +#ifdef _STDIO_BSD_SEMANTICS + /* BSD and Glibc systems only flush streams which have been written to + at exit time. Calling flush rather than close for speed, as on + the aforementioned systems. */ + _CAST_VOID _fwalk_reent (ptr, __sflushw_r); +#else + /* Otherwise close files and flush read streams, too. + FIXME: Do we really have to call fclose rather than fflush for + RTOS compatibility? */ + _CAST_VOID _fwalk_reent (ptr, _fclose_r); +#endif } #ifndef _REENT_ONLY diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h index 0bd47a46a..ad477485b 100644 --- a/newlib/libc/stdio/local.h +++ b/newlib/libc/stdio/local.h @@ -147,6 +147,9 @@ int _EXFUN(_svfiwprintf_r,(struct _reent *, FILE *, const wchar_t *, extern FILE *_EXFUN(__sfp,(struct _reent *)); extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); extern int _EXFUN(__sflush_r,(struct _reent *,FILE *)); +#ifdef _STDIO_BSD_SEMANTICS +extern int _EXFUN(__sflushw_r,(struct _reent *,FILE *)); +#endif extern int _EXFUN(__srefill_r,(struct _reent *,FILE *)); extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *, _READ_WRITE_BUFSIZE_TYPE)); -- cgit v1.2.3