summaryrefslogtreecommitdiffstats
path: root/newlib/libc/stdio
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2007-03-15 21:32:13 +0000
committerJeff Johnston <jjohnstn@redhat.com>2007-03-15 21:32:13 +0000
commit826b5591dd604ef68abadff7c8cb7c19e221b9af (patch)
tree1d1cd77cbe1ec91d5bc33e3879db3efdddbfc8c4 /newlib/libc/stdio
parent14ba5e14d9226cb4dd1b2a72781ee02e9f2bf8a2 (diff)
downloadcygnal-826b5591dd604ef68abadff7c8cb7c19e221b9af.tar.gz
cygnal-826b5591dd604ef68abadff7c8cb7c19e221b9af.tar.bz2
cygnal-826b5591dd604ef68abadff7c8cb7c19e221b9af.zip
2007-03-15 Jeff Johnston <jjohnstn@redhat.com>
* configure.in: Add new --enable-newlib-reent-small option. * configure: Regenerated. * acconfig.h: Add _WANT_REENT_SMALL. * newlib.hin: Regenerated minus PACKAGE macros to add _WANT_REENT_SMALL macro. * libc/include/sys/config.h[_WANT_REENT_SMALL]: Set _REENT_SMALL if not already set. * libc/stdio/fflush.c[_REENT_SMALL]: Return immediately if there is no buffer. * libc/stdio/local.h[_REENT_SMALL]: Fix CHECK_INIT macro to use reentrant pointer passed in when resetting the file pointer to one of the std streams.
Diffstat (limited to 'newlib/libc/stdio')
-rw-r--r--newlib/libc/stdio/fflush.c16
-rw-r--r--newlib/libc/stdio/local.h6
2 files changed, 19 insertions, 3 deletions
diff --git a/newlib/libc/stdio/fflush.c b/newlib/libc/stdio/fflush.c
index a8ef755c2..d46b41f94 100644
--- a/newlib/libc/stdio/fflush.c
+++ b/newlib/libc/stdio/fflush.c
@@ -67,6 +67,22 @@ _DEFUN(fflush, (fp),
if (fp == NULL)
return _fwalk (_GLOBAL_REENT, fflush);
+#ifdef _REENT_SMALL
+ /* For REENT_SMALL platforms, it is possible we are being
+ called for the first time on a std stream. This std
+ stream can belong to a reentrant struct that is not
+ _REENT. If CHECK_INIT gets called below based on _REENT,
+ we will end up changing said file pointers to the equivalent
+ std stream off of _REENT. This causes unexpected behavior if
+ there is any data to flush on the _REENT std stream. There
+ are two alternatives to fix this: 1) make a reentrant fflush
+ or 2) simply recognize that this file has nothing to flush
+ and return immediately before performing a CHECK_INIT. Choice
+ 2 is implemented here due to its simplicity. */
+ if (fp->_bf._base == NULL)
+ return 0;
+#endif /* _REENT_SMALL */
+
CHECK_INIT (_REENT, fp);
_flockfile (fp);
diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h
index 704b6be03..4263a9de6 100644
--- a/newlib/libc/stdio/local.h
+++ b/newlib/libc/stdio/local.h
@@ -55,11 +55,11 @@ struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n));
if ((ptr) && !(ptr)->__sdidinit) \
__sinit (ptr); \
if ((fp) == (FILE *)&__sf_fake_stdin) \
- (fp) = stdin; \
+ (fp) = _stdin_r(ptr); \
else if ((fp) == (FILE *)&__sf_fake_stdout) \
- (fp) = stdout; \
+ (fp) = _stdout_r(ptr); \
else if ((fp) == (FILE *)&__sf_fake_stderr) \
- (fp) = stderr; \
+ (fp) = _stderr_r(ptr); \
} \
while (0)
#else /* !_REENT_SMALL */