getchar issues
Jeff Johnston
jjohnstn@redhat.com
Tue Mar 11 19:32:00 GMT 2008
Matt,
Thanks for the analysis. The solution is that __srget must call
CHECK_INIT prior
to calling __srefill_r. This resolves fake stdin to stdin before
accessing the read buffer.
I have checked in a fix. Please try it out.
-- Jeff J.
Matt Lee wrote:
> On Mon, Mar 10, 2008 at 12:20 PM, Matt Lee <reachmatt.lee@gmail.com> wrote:
>
>> Hi,
>>
>> I am using the following small test program linked against
>> newlib-1.14.0 on my embedded PowerPC target.
>>
>> 1 #include "stdio.h"
>> 2
>> 3 int main (void)
>> 4 {
>> 5 char c;
>> 6
>> 7 //printf("Enter a character:\r\n");
>> 8 while (1) {
>> 9 c = getchar();
>> 10 printf("Char: %c. Hex:0x%x.\r\n", c, c);
>> 11 }
>> 12 }
>>
>> In the above program the first character returned by getchar() in the
>> loop seems to be some random junk and not the character typed on the
>> console. That is, I always get a "H" before getting the correct
>> characters typed in sequence.
>> If line 7 is *not* commented out, then getchar returns the character
>> typed correctly without any extraneous incorrect characters.
>>
>> I have verified that my read() implementation is not the one returning
>> the crud. A wild theory from me is that the program flow through
>> printf() is enabling or initializing some structure that the program
>> flow through getchar() is not.
>>
>> I am using -DSMALL_MEMORY -D_REENT_SMALL in the newlib C flags during
>> build and also have _REENT_SMALL defined in sys/config.h for my
>> architecture. I have also backported and applied two bug fixes
>> (below) related to _REENT_SMALL -
>>
>> http://sourceware.org/ml/newlib/2006/msg00037.html
>> http://sourceware.org/ml/newlib/2006/msg00796.html
>>
>> I will debug this further, but are there any obvious things I should
>> be checking? Any help is much appreciated.
>>
>>
>
> Ok, so the problem seems to be with the use of __sf_fake_std* and the
> fact that CHECK_INIT() re-assigns the passed in fp to the real __std*
> pointers. This is the scenario:
>
> 1. Program calls getchar()
> 2. stdio.h defines getchar() as getc(stdin) (stdin at this point is
> __sf_fake_stdin)
> 3. In rget.c, __srget calls __srefill with __sf_fake_stdin as the pointer.
> 4. Internally, __srefill realizes that the file pointer is fake and
> re-assigns it to the real stdin pointer and does the rest of its usual
> actions, including getting the actual input.
> 5. However, when __srefill returns, __srget still thinks fp is
> __sf_fake_stdin and reads a character from fp->_p (which is NULL) and
> returns it back. This is the junk character that I see.
>
> I checked the latest sources in CVS and though some things have
> changed around __srget and __srefill, it seems that the core issue
> still remains.
>
> The workaround for this is to first invoke a call such as printf()
> which initializes stdin so that any subsequent usage of getchar() and
> friends uses the right file pointer to start with.
>
> Ideally, this problem should be fixed in __srget (and similiar
> functions). But I am not clear on how to do this. Any suggestions?
>
> thanks,
> Matt
>
More information about the Newlib
mailing list