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