1.3.3-2: fseek fails on multiples of 1024 (binary mode)
J. Johnston
jjohnstn@cygnus.com
Tue Oct 23 15:55:00 GMT 2001
Christopher Faylor wrote:
>
> Again, these observations should go to the mailing list which is
> responsible for maintaining the code that you've analyzed:
> newlib@sources.redhat.com .
>
> I've redirected this discussion there.
>
> Thanks for your in-depth analysis of the problem.
>
> cgf
>
> On Tue, Oct 23, 2001 at 06:21:40PM +0200, Pavel Tsekov wrote:
> >Upon further investigation this problem seems to be much bigger than
> >I've initially thought and there is no easy patch to it (at least I
> >think so) so I'll describe what've found about it. I started a patch
> >though and will would like to know if you like my approach or will
> >suggest another one.
> >
> >
> >Let me show you with some digits whats going on:
> >
> >We have 2048 bytes file. We have bufsize 1024. We fread 1024 bytes -
> >this fills exactly the internal buffer thus 'n' will become 1024,
> >fp->_r will become 0. We request then file position 0 from the end of
> >file. ftell reports 2048. Now we want to go back to 1024 and read 8
> >bytes. fseek tries to optiomize since we are in read only mode ... it
> >does this
I believe the problem lies with the seek to end. In particular:
curoff = target & ~(fp->_blksize - 1);
if ((*seekfn) (fp->_cookie, curoff, SEEK_SET) == POS_ERR)
goto dumb;
fp->_r = 0;
if (HASUB (fp))
FREEUB (fp);
fp->_flags &= ~__SEOF;
n = target - curoff;
if (n)
{
if (__srefill (fp) || fp->_r < n)
goto dumb;
fp->_p += n;
fp->_r -= n;
}
Notice the check for if (n) to do the refill. We have already determined that
the offset is not in the current block. The fact that we are seeking to a block
boundary causes curoff = target. Thus, n ends up being 0. We don't do the refill
and the fp->p value is pointing to the end. Hence the problems afterwards.
If we always do the __srefill I think this cures the problem. Offhand, I cannot
think of any scenario where we don't want the refill to occur.
-- Jeff J.
More information about the Newlib
mailing list