1.3.3-2: fseek fails on multiples of 1024 (binary mode)
Tue Oct 23 20:06:00 GMT 2001
On Tue, Oct 23, 2001 at 06:55:50PM -0400, J. Johnston wrote:
>Christopher Faylor wrote:
>> Again, these observations should go to the mailing list which is
>> responsible for maintaining the code that you've analyzed:
>> email@example.com .
>> I've redirected this discussion there.
>> Thanks for your in-depth analysis of the problem.
>> 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.
Is this fixed in more recent BSD code, perhaps? Or has the code diverged too far
for this to be useful?
More information about the Newlib