diff options
author | pfg <pfg@FreeBSD.org> | 2014-08-16 01:29:49 +0000 |
---|---|---|
committer | pfg <pfg@FreeBSD.org> | 2014-08-16 01:29:49 +0000 |
commit | ae3a2a5c84fb35878449eb2fdb6c9513488e3d1a (patch) | |
tree | 382174b89213cc48a3e380247fbaeb07f568c44c /lib/libc | |
parent | 2e2e6c6d48e286cd41b478b8d163e15a56a37742 (diff) | |
download | FreeBSD-src-ae3a2a5c84fb35878449eb2fdb6c9513488e3d1a.zip FreeBSD-src-ae3a2a5c84fb35878449eb2fdb6c9513488e3d1a.tar.gz |
MFC r268924:
Update fflush(3) to return success on a read-only stream.
This is done for compliance with SUSv3. The changes cause
no secondary effects in the gnulib tests (we pass them).
Obtained from: Apple Inc. (Libc 997.90.3 with changes)
Reviewed by: bde
Phabric: D440
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/stdio/fflush.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index 456b031..ef9b45b 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -60,7 +60,7 @@ fflush(FILE *fp) /* * There is disagreement about the correct behaviour of fflush() - * when passed a file which is not open for reading. According to + * when passed a file which is not open for writing. According to * the ISO C standard, the behaviour is undefined. * Under linux, such an fflush returns success and has no effect; * under Windows, such an fflush is documented as behaving instead @@ -68,11 +68,13 @@ fflush(FILE *fp) * Given that applications may be written with the expectation of * either of these two behaviours, the only safe (non-astonishing) * option is to return EBADF and ask that applications be fixed. + * SUSv3 now requires that fflush() returns success on a read-only + * stream. + * */ - if ((fp->_flags & (__SWR | __SRW)) == 0) { - errno = EBADF; - retval = EOF; - } else + if ((fp->_flags & (__SWR | __SRW)) == 0) + retval = 0; + else retval = __sflush(fp); FUNLOCKFILE(fp); return (retval); @@ -89,10 +91,9 @@ __fflush(FILE *fp) if (fp == NULL) return (_fwalk(sflush_locked)); - if ((fp->_flags & (__SWR | __SRW)) == 0) { - errno = EBADF; - retval = EOF; - } else + if ((fp->_flags & (__SWR | __SRW)) == 0) + retval = 0; + else retval = __sflush(fp); return (retval); } @@ -122,6 +123,12 @@ __sflush(FILE *fp) for (; n > 0; n -= t, p += t) { t = _swrite(fp, (char *)p, n); if (t <= 0) { + /* Reset _p and _w. */ + if (p > fp->_p) /* Some was written. */ + memmove(fp->_p, p, n); + fp->_p += n; + if ((fp->_flags & (__SLBF | __SNBF)) == 0) + fp->_w -= n; fp->_flags |= __SERR; return (EOF); } |