aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2017-12-18 20:17:51 +0100
committerCorinna Vinschen <corinna@vinschen.de>2017-12-18 20:17:51 +0100
commit6e5b39940ae95d098fb89cf80d48f6e03d3833bf (patch)
treee99b0bff83de597df69a7b24133678dd5df46e0a
parentdc2d175721df8ceb801d50581df95b49c26a6ff7 (diff)
downloadnewlib-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.c20
-rw-r--r--newlib/libc/stdio64/ftello64.c20
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
{