diff options
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/include/sys/config.h | 8 | ||||
-rw-r--r-- | newlib/libc/stdio/fflush.c | 16 | ||||
-rw-r--r-- | newlib/libc/stdio/local.h | 6 |
3 files changed, 27 insertions, 3 deletions
diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h index 58305d4a8..0ac2b4ec8 100644 --- a/newlib/libc/include/sys/config.h +++ b/newlib/libc/include/sys/config.h @@ -202,4 +202,12 @@ #endif #endif +/* See if small reent asked for at configuration time and + is not chosen by the platform by default. */ +#ifdef _WANT_REENT_SMALL +#ifndef _REENT_SMALL +#define _REENT_SMALL +#endif +#endif + #endif /* __SYS_CONFIG_H__ */ 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 */ |