This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
BUG: newlib 1.17 doesn't flush all line-buffered streams on input
- From: Till Straumann <strauman at slac dot stanford dot edu>
- To: newlib at sources dot redhat dot com, "rtems-users at rtems dot org" <rtems-users at rtems dot org>
- Date: Fri, 11 Jun 2010 00:34:19 -0500
- Subject: BUG: newlib 1.17 doesn't flush all line-buffered streams on input
Per standard, when reading from an unbuffered or line-buffered input stream
then all line-buffered output streams must be flushed.
This analysis does not address the REENT_SMALL case
In newlib, streams are 'attached' to a 'reent' struct. The 3 stdio streams
stdin, stderr, stdout are managed 'per-thread' and each thread has
these three streams 'attached' to its struct reent.
Other streams that are created during the lifetime of the system (e.g.,
via fopen) are 'attached' to the GLOBAL_REENT struct.
The __srefill_r() routine, when it finds that it needs to refill a
line- or unbuffered stream, calls (see newlib/libc/stdio/refill.c)
_fwalk(_GLOBAL_REENT, lflush)
which results in all line-buffered output streams 'attached' to
GLOBAL_REENT to be flushed.
However, all the 'stdout' streams which are not attached to GLOBAL_REENT
(but to individual struct reents) are NOT flushed.
As a work-around I'd propose to at least flush the executing thread's
streams by adding a statement
if ( _GLOBAL_REENT != ptr ) {
_CAST_VOID _fwalk (ptr, lflush);
}
after _fwalk(_GLOBAL_REENT, lflush);
-- Till
PS: How to reproduce:
execute
printf("Hello"); scanf("%i", &dummy);
PPS: Under rtems-4.10 this bug is obscured by the fact that
the initialization task is actually using _GLOBAL_REENT so that
the above test case (printf/scanf) works as expected from the
initialization task.