Re: new bug in fgetc_unlocked ?

Felix von Leitner <[email protected]>
Newsgroups gmane.linux.lib.dietlibc
Message-ID <[email protected]>
> Commenting the 2 following lines fixes my bug but I don't understand
> why :

> if (__likely(stream->bm<stream->bs))
>   return stream->buf[stream->bm++];

Those two lines are an optimization I put in recently.
Here's a little test I did:

  FILE* f=fopen("testfile","r");
  char buf[1024];
  printf("%d\n",fread(buf,1,sizeof(buf),f));
  printf("%d\n",fread(buf,1,sizeof(buf),f));
  printf("%d\n",fread(buf,1,sizeof(buf),f));

Testfile is 1108 bytes, and I get 1024, 84, and 0.  For both glibc and
dietlibc.  So the code works in principle.

> There is however something that look very strange then:

>   if (__fflush4(stream,BUFINPUT)) return EOF;
>   if (__unlikely(stream->bm>=stream->bs)) {

> __fflush4 will ensure that  stream->bm == stream->bs == 0, so __unlikely
> is strange, and actually I think that full test is useless.

The code is a little unclear, sorry.

The problem is: we have one buffer in the FILE struct, but some files
can be opened for reading and writing.  So in the case that the last
operation was a write and the current one is a read (or vice versa) we
have to flush the buffer, which means clearing it.

fflush4 when called with BUFINPUT only actually does anything if the
last operation was a write.  The normal case is that you call fgetc
several times in a row, and in that case bm (the "current" offset in the
buffer) will be different than bs (how many bytes are in the buffer).
That __unlinkely check triggers only if there is nothing to read in the
buffer.  Which does happen if __fflush4 flushed the buffer, you are
right.

Can you provide a test case based on the code that reads terminfo in
Mandriva so I can reproduce your problem?

Felix
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.