This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: getchar issues


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]