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