Question on fseek optimization in newlib

Can Finner
Tue Jun 19 13:56:00 GMT 2012

On Wed, Jun 6, 2012 at 8:51 PM, Eric Blake <> wrote:
> On 06/06/2012 12:47 AM, Can Finner wrote:
>> Hi,
>> In function _fseek_r, it seems for buffered file(opened for writing),
>> newlib always decrease "curoff" by n(=fp->_p - fp->_bf._base).
>> The variable “curoff” is returned by “seekfn (ptr, fp->_cookie, 0L,
>> SEEK_CUR)”, which should be __seek.
>> My question is why should we decrease “curoff” by “n”, in my
>> understanding, the file position returned by __seek/lseek does
>> not include bytes in writing buffer.
> The file position returned by lseek() and the stream position returned
> by ftell (and manipulated by fseek) are independent.  POSIX requires
> that they be synchronized at certain points, but that they can be
> independent most other times.
>>     fwrite("hello world\n", 1, 10, pfile);
>>     p1 = lseek (fd, 0, SEEK_CUR);
> This is a point where POSIX says the lseek() is undefined in relation to
> the stream position.
>>     fflush (pfile);
>>     p2 = lseek (fd, 0, SEEK_CUR);
> And thanks to the fflush(), this is a point where POSIX requires the
> lseek() to match the ftell() position.
>> So, did I miss something important? Please help.
> I'm hoping I answered your question, although it wasn't really obvious
> to me why you think something was wrong.  As far as I have tested (and I
> have tested quite extensively, since some of the stdio behavior in
> newlib is due to my patching as a result of my testing), the current
> newlib behavior complies with the POSIX requirements for the points
> where lseek() must match stream position, without penalizing things to
> always require the correspondence in the cases where POSIX permits
> optimizations by treating the two positions independently.
Hi Eric,
Thanks very much for your clarification.

For a stream IO with writing buffer as described by following line:

                   ^1              ^0                 ^2
"^0" (at least could)stands for the curoff returned by "lseek";
"^2" stands for the writing buffered position, here we have "n=^2-^0"
"^1" stands for "^0 - n";

Back to _fseek_r, it decrease "curoff" by "n", which points to "^1".
If "target" falls in [^0,^2], the check "target >= curoff && target <
curoff + n"
fails; If "target" falls in [^1,^0], the check succeeds. I think both of them
should work in the other way, right?

Hoping I have described it clearly. As you clarified, given there is no defined
relation between stream position and lseek here, _fseek_r is NOT wrong.

Thanks again.

More information about the Newlib mailing list