newlib: ftello{64}: Handle appending stream without fflushing

Neither upstream FreeBSD nor glibc ever call fflush from ftell
and friends.  In border cases it has the tendency to return
wrong or unexpected values, for instance on block devices.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2017-12-18 20:17:51 +01:00
parent dc2d175721
commit 6e5b39940a
2 changed files with 26 additions and 14 deletions

View File

@ -102,13 +102,19 @@ _DEFUN(_ftello_r, (ptr, fp),
return (_off_t) -1;
}
/* Find offset of underlying I/O object, then adjust for buffered
bytes. Flush a write stream, since the offset may be altered if
the stream is appending. Do not flush a read stream, since we
must not lose the ungetc buffer. */
if (fp->_flags & __SWR)
_fflush_r (ptr, fp);
if (fp->_flags & __SOFF)
/* Find offset of underlying I/O object, then adjust for buffered bytes. */
if (!(fp->_flags & __SRD) && (fp->_flags & __SWR) &&
fp->_p != NULL && fp->_p - fp->_bf._base > 0 &&
(fp->_flags & __SAPP))
{
pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_END);
if (pos == (_fpos_t) -1)
{
_newlib_flockfile_exit (fp);
return (_off_t) -1;
}
}
else if (fp->_flags & __SOFF)
pos = fp->_offset;
else
{

View File

@ -99,13 +99,19 @@ _DEFUN (_ftello64_r, (ptr, fp),
return (_off64_t) -1;
}
/* Find offset of underlying I/O object, then adjust for buffered
bytes. Flush a write stream, since the offset may be altered if
the stream is appending. Do not flush a read stream, since we
must not lose the ungetc buffer. */
if (fp->_flags & __SWR)
_fflush_r (ptr, fp);
if (fp->_flags & __SOFF)
/* Find offset of underlying I/O object, then adjust for buffered bytes. */
if (!(fp->_flags & __SRD) && (fp->_flags & __SWR) &&
fp->_p != NULL && fp->_p - fp->_bf._base > 0 &&
(fp->_flags & __SAPP))
{
pos = fp->_seek64 (ptr, fp->_cookie, (_fpos64_t) 0, SEEK_END);
if (pos == (_fpos64_t) -1)
{
_newlib_flockfile_exit (fp);
return (_off64_t) -1;
}
}
else if (fp->_flags & __SOFF)
pos = fp->_offset;
else
{