git: 3ca78fba9653 - releng/13.1 - libc: Restore fp state upon flush error in fputc

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 31 Mar 2022 15:57:02 UTC
The branch releng/13.1 has been updated by markj:

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

commit 3ca78fba965377cce04935ee762f1d91e54efeb1
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-03-25 14:46:24 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-03-31 15:56:37 +0000

    libc: Restore fp state upon flush error in fputc
    
    This is akin to commit bafaa70b6f9098d83d074968c8e6747ecec1e118.
    
    Approved by:    re (gjb)
    Reported by:    Guy Yur <guyyur@gmail.com>
    Fixes:          86a16ada1ea6
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 6e13794fbe6e82c21365d0fd66769bf8b19c0197)
    (cherry picked from commit 7be0c792c46c5a1faf46b611058953aa85b192d6)
---
 lib/libc/stdio/wbuf.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/libc/stdio/wbuf.c b/lib/libc/stdio/wbuf.c
index e1aa70243e94..6cd75145a271 100644
--- a/lib/libc/stdio/wbuf.c
+++ b/lib/libc/stdio/wbuf.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 int
 __swbuf(int c, FILE *fp)
 {
+	unsigned char *old_p;
 	int n;
 
 	/*
@@ -87,8 +88,15 @@ __swbuf(int c, FILE *fp)
 	}
 	fp->_w--;
 	*fp->_p++ = c;
-	if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
-		if (__fflush(fp))
+	old_p = fp->_p;
+	if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) {
+		if (__fflush(fp)) {
+			if (fp->_p == old_p) {
+				fp->_p--;
+				fp->_w++;
+			}
 			return (EOF);
+		}
+	}
 	return (c);
 }