From 1d638d9700dbf454f40c66499f6fc0471f177aab Mon Sep 17 00:00:00 2001 From: zrj Date: Sat, 23 Dec 2017 10:29:47 +0200 Subject: [PATCH] fflush(3): Return success on a read-only stream. Loosen up the requirements for opened streams. It is needed to support c++ runtime lib after ext/basic_file_stdio.c s/this->sync()/fflush()/ change. It likely needed for libc++ too. Adjust the manpage for behaviour change and only set _w to 0 when stream is not currently reading in fpurge(4) to avoid failures in fflush(4). Taken-from: FreeBSD --- lib/libc/stdio/fflush.3 | 14 ++++++++------ lib/libc/stdio/fflush.c | 25 +++++++++++++++---------- lib/libc/stdio/fpurge.c | 2 +- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lib/libc/stdio/fflush.3 b/lib/libc/stdio/fflush.3 index 42e8e17fbf..ffbe40f7ae 100644 --- a/lib/libc/stdio/fflush.3 +++ b/lib/libc/stdio/fflush.3 @@ -31,9 +31,8 @@ .\" .\" @(#)fflush.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.11 2007/01/09 00:28:06 imp Exp $ -.\" $DragonFly: src/lib/libc/stdio/fflush.3,v 1.3 2004/06/08 00:29:47 hmp Exp $ .\" -.Dd June 4, 1993 +.Dd December 23, 2017 .Dt FFLUSH 3 .Os .Sh NAME @@ -88,9 +87,7 @@ is set to indicate the error. The .Fa stream argument -is not an open stream, or, in the case of -.Fn fflush , -not a stream open for writing. +is not an open stream. .El .Pp The function @@ -98,7 +95,12 @@ The function may also fail and set .Va errno for any of the errors specified for the routine -.Xr write 2 . +.Xr write 2 , +except that in case of +.Fa stream +being a read-only descriptor, +.Fn fflush +returns 0. .Sh SEE ALSO .Xr write 2 , .Xr fclose 3 , diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index 9905662d55..93e2ff7bce 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -66,13 +66,12 @@ 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. + * But for c++ compatibility do not enforce it and match FreeBSD. */ - if ((fp->pub._flags & (__SWR | __SRW)) == 0) { - errno = EBADF; - retval = EOF; - } else { + if ((fp->pub._flags & (__SWR | __SRW)) == 0) + retval = 0; + else retval = __sflush(fp); - } FUNLOCKFILE(fp); return (retval); } @@ -88,12 +87,10 @@ __fflush(FILE *fp) if (fp == NULL) return (_fwalk(sflush_locked)); - if ((fp->pub._flags & (__SWR | __SRW)) == 0) { - errno = EBADF; - retval = EOF; - } else { + if ((fp->pub._flags & (__SWR | __SRW)) == 0) + retval = 0; + else retval = __sflush(fp); - } return (retval); } @@ -122,6 +119,14 @@ __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->pub._p) { + /* Some was written. */ + memmove(fp->pub._p, p, n); + fp->pub._p += n; + if ((fp->pub._flags & (__SLBF | __SNBF)) == 0) + fp->pub._w -= n; + } fp->pub._flags |= __SERR; return (EOF); } diff --git a/lib/libc/stdio/fpurge.c b/lib/libc/stdio/fpurge.c index c9d4b7be21..08ae2b5b18 100644 --- a/lib/libc/stdio/fpurge.c +++ b/lib/libc/stdio/fpurge.c @@ -58,7 +58,7 @@ fpurge(FILE *fp) FREEUB(fp); fp->pub._p = fp->_bf._base; fp->pub._r = 0; - fp->pub._w = fp->pub._flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + fp->pub._w = fp->pub._flags & (__SLBF|__SNBF|__SRD) ? 0 : fp->_bf._size; retval = 0; } FUNLOCKFILE(fp); -- 2.11.4.GIT