1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00

Don't flush write buffer for ftell

[BZ #5298]
Use write pointer state along with the file offset and/or the read
pointers to get the current file position.
This commit is contained in:
Siddhesh Poyarekar
2012-09-28 18:37:23 +05:30
parent 4573c6b098
commit adb26faefe
4 changed files with 126 additions and 31 deletions

View File

@ -978,6 +978,9 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
&& fp->_IO_write_base == fp->_IO_write_ptr);
bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
|| _IO_in_put_mode (fp));
if (mode == 0)
dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
@ -988,10 +991,8 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
which assumes file_ptr() is eGptr. Anyway, since we probably
end up flushing when we close(), it doesn't make much difference.)
FIXME: simulate mem-mapped files. */
if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
if (_IO_switch_to_get_mode (fp))
return EOF;
else if (was_writing && _IO_switch_to_get_mode (fp))
return EOF;
if (fp->_IO_buf_base == NULL)
{
@ -1010,7 +1011,17 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
{
case _IO_seek_cur:
/* Adjust for read-ahead (bytes is buffer). */
offset -= fp->_IO_read_end - fp->_IO_read_ptr;
if (mode != 0 || !was_writing)
offset -= fp->_IO_read_end - fp->_IO_read_ptr;
else
{
/* _IO_read_end coincides with fp._offset, so the actual file position
is fp._offset - (_IO_read_end - new_write_ptr). This is fine
even if fp._offset is not set, since fp->_IO_read_end is then at
_IO_buf_base and this adjustment is for unbuffered output. */
offset -= fp->_IO_read_end - fp->_IO_write_ptr;
}
if (fp->_offset == _IO_pos_BAD)
{
if (mode != 0)