From 6e5b39940ae95d098fb89cf80d48f6e03d3833bf Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Dec 2017 20:17:51 +0100 Subject: [PATCH] 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 --- newlib/libc/stdio/ftello.c | 20 +++++++++++++------- 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 0a9bb7bd6..90c4d321e 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 9aca231ef..2441d4c1f 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 {