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

Pavel Tsekov ptsekov@syntrex.com
Wed Oct 24 03:38:00 GMT 2001

Christopher Faylor wrote:
> On Tue, Oct 23, 2001 at 11:07:03PM -0400, Christopher Faylor wrote:
> >Is this fixed in more recent BSD code, perhaps?  Or has the code diverged too far
> >for this to be useful?
> Answering my own question: No, the code hasn't changed that much and
> there seems to be one minor change in it, which is below.
> Is it my imagination or does this actually fix the problem?  I haven't
> studied the code that much but, from context, the patch makes sense.
> cgf
> Index: libc/stdio/fseek.c
> ===================================================================
> RCS file: /cvs/uberbaum/newlib/libc/stdio/fseek.c,v
> retrieving revision
> diff -p -r1.1.1.1 fseek.c
> *** fseek.c     2000/02/17 19:39:47
> --- fseek.c     2001/10/24 03:20:13
> *************** fseek (fp, offset, whence)
> *** 278,283 ****
> --- 278,284 ----
>     if ((*seekfn) (fp->_cookie, curoff, SEEK_SET) == POS_ERR)
>       goto dumb;
>     fp->_r = 0;
> +   fp->_p = fp->_bf._base;
>     if (HASUB (fp))
>       FREEUB (fp);
>     fp->_flags &= ~__SEOF;

Digging more today I've found who introduced this patch originally into
the freebsd tree and a comment he left along with his patch:

Date: Wed, 26 Oct 1994 15:44:49 -0600
From: Chris Torek <torek@bsdi.com>
Here is a semi-official patch (apply to /usr/src/lib/libc/stdio/fseek.c,
rebuild libc, install).  The current code fails when the seek:

  - is optimized, and
  - is to just past the end of the block currently in the buffer, and
  - is followed by another seek with no intervening read operation, and
  - the destination of subsequent seek is within the block left in the
    buffer (seeking to the beginning of a block does not force a read,
    so the buffer still contains the previous block)

so it is indeed rather obscure.

I may have a different `final' fix, as this one `loses' the buffer
contents on a seek that goes just past the end of the current block.

[Footnote: seeks are optimized only on read-only opens of regular
files that are buffered by the file's optimal I/O size.  This is
what you get with fopen(path, "r") and no call to setvbuf().]

Obtained from: [ BSDI mailing list ]

Having this information you can understand why I was stuck to just the
part of the sourcecode upto the check if the requested offset is into
the buffered range, and also why I was talking about introducing a new 
member to the FILE (__sFILE) structure which is to hold the last read
position. I thought that the optimisation is to work even if we moved
past the current block and then return in another fseek to it without a
read between the two operations.

Again the question is does this optimization actually do something which
worth to have it in the source three ? :)

More information about the Newlib mailing list