diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2017-12-18 20:17:51 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2017-12-18 20:17:51 +0100 |
commit | 6e5b39940ae95d098fb89cf80d48f6e03d3833bf (patch) | |
tree | e99b0bff83de597df69a7b24133678dd5df46e0a | |
parent | dc2d175721df8ceb801d50581df95b49c26a6ff7 (diff) | |
download | newlib-6e5b39940ae95d098fb89cf80d48f6e03d3833bf.zip newlib-6e5b39940ae95d098fb89cf80d48f6e03d3833bf.tar.gz newlib-6e5b39940ae95d098fb89cf80d48f6e03d3833bf.tar.bz2 |
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>
-rw-r--r-- | newlib/libc/stdio/ftello.c | 20 | ||||
-rw-r--r-- | newlib/libc/stdio64/ftello64.c | 20 |
2 files changed, 26 insertions, 14 deletions
diff --git a/newlib/libc/stdio/ftello.c b/newlib/libc/stdio/ftello.c index 0a9bb7b..90c4d32 100644 --- a/newlib/libc/stdio/ftello.c +++ b/newlib/libc/stdio/ftello.c @@ -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 { diff --git a/newlib/libc/stdio64/ftello64.c b/newlib/libc/stdio64/ftello64.c index 9aca231..2441d4c 100644 --- a/newlib/libc/stdio64/ftello64.c +++ b/newlib/libc/stdio64/ftello64.c @@ -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 { |