This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


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

Re: 1.3.3-2: fseek fails on multiples of 1024 (binary mode)


Christopher Faylor wrote:
> 
> 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:
> >> 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.
> 
> Is this fixed in more recent BSD code, perhaps?  Or has the code diverged too far
> for this to be useful?

I posted yesterday to OpenBSD, NetBSD and FreeBSD mailing lists Derek's
testcase 
along with my observations - none of them experience the problem
anymore. However
the FreeBSD people pointed me to something useful which might help fix
the problem
in the newlib code. Here is what they say:

> > http://www.cygwin.com/ml/cygwin/2001-10/msg01211.html
> > http://www.cygwin.com/ml/cygwin/2001-10/msg01298.html
> 
> The bug is fixed in FreeBSD-current stdio.c v1.19, two-lines fix setting 
> __SMOD of non-zero seek.

Very short lived and just backed out. It is not neccessary on FreeBSD, 
because FreeBSD's fseek clears internal read buffer on each seek outside 
of it.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


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