summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2014-08-16 01:29:49 +0000
committerpfg <pfg@FreeBSD.org>2014-08-16 01:29:49 +0000
commitae3a2a5c84fb35878449eb2fdb6c9513488e3d1a (patch)
tree382174b89213cc48a3e380247fbaeb07f568c44c /lib/libc/stdio
parent2e2e6c6d48e286cd41b478b8d163e15a56a37742 (diff)
downloadFreeBSD-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/stdio')
-rw-r--r--lib/libc/stdio/fflush.c25
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);
}
OpenPOWER on IntegriCloud