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

View File

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