git: afa9a1f5ec99 - stable/13 - __sflush(): on write error, if nothing was written, reset FILE state back

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 01 Feb 2022 03:29:44 UTC
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=afa9a1f5ec9974793a8744c55036ef5c4d08903d

commit afa9a1f5ec9974793a8744c55036ef5c4d08903d
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-01-23 06:52:59 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-02-01 03:29:15 +0000

    __sflush(): on write error, if nothing was written, reset FILE state back
    
    PR:     76398
    
    (cherry picked from commit 86a16ada1ea608408cec370171d9f59353e97c77)
---
 lib/libc/stdio/fflush.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c
index f7d2fbdc28e5..decc974907f4 100644
--- a/lib/libc/stdio/fflush.c
+++ b/lib/libc/stdio/fflush.c
@@ -105,8 +105,8 @@ __weak_reference(__fflush, fflush_unlocked);
 int
 __sflush(FILE *fp)
 {
-	unsigned char *p;
-	int n, t;
+	unsigned char *p, *old_p;
+	int n, t, old_w;
 
 	t = fp->_flags;
 	if ((t & __SWR) == 0)
@@ -121,7 +121,9 @@ __sflush(FILE *fp)
 	 * Set these immediately to avoid problems with longjmp and to allow
 	 * exchange buffering (via setvbuf) in user write function.
 	 */
+	old_p = fp->_p;
 	fp->_p = p;
+	old_w = fp->_w;
 	fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
 
 	for (; n > 0; n -= t, p += t) {
@@ -134,6 +136,9 @@ __sflush(FILE *fp)
 				fp->_p += n;
 				if ((fp->_flags & (__SLBF | __SNBF)) == 0)
 					fp->_w -= n;
+			} else if (p == fp->_p) { /* cond. to handle setvbuf */
+				fp->_p = old_p;
+				fp->_w = old_w;
 			}
 			fp->_flags |= __SERR;
 			return (EOF);