git: bafaa70b6f90 - main - libc __sfvwrite(): roll back FILE buffer pointer on fflush error
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 06 Mar 2022 15:43:49 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=bafaa70b6f9098d83d074968c8e6747ecec1e118
commit bafaa70b6f9098d83d074968c8e6747ecec1e118
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-03-06 08:59:39 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-03-06 15:29:51 +0000
libc __sfvwrite(): roll back FILE buffer pointer on fflush error
__sfvwrite() advances the pointer before calling fflush. If fflush()
fails, it is not enough to roll back inside it, because we cannot know
how much was advanced by the caller.
Reported by: Peter <pmc@citylink.dinoex.sub.org>
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Fixes: 86a16ada1ea608408cec370171d9f59353e97c77
---
lib/libc/stdio/fvwrite.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c
index 50b32b8eca6e..2a161859afa9 100644
--- a/lib/libc/stdio/fvwrite.c
+++ b/lib/libc/stdio/fvwrite.c
@@ -54,6 +54,7 @@ int
__sfvwrite(FILE *fp, struct __suio *uio)
{
size_t len;
+ unsigned char *old_p;
char *p;
struct __siov *iov;
int w, s;
@@ -137,8 +138,12 @@ __sfvwrite(FILE *fp, struct __suio *uio)
COPY(w);
/* fp->_w -= w; */ /* unneeded */
fp->_p += w;
- if (__fflush(fp))
+ old_p = fp->_p;
+ if (__fflush(fp) == EOF) {
+ if (old_p == fp->_p)
+ fp->_p -= w;
goto err;
+ }
} else if (len >= (w = fp->_bf._size)) {
/* write directly */
w = _swrite(fp, p, w);
@@ -177,8 +182,12 @@ __sfvwrite(FILE *fp, struct __suio *uio)
COPY(w);
/* fp->_w -= w; */
fp->_p += w;
- if (__fflush(fp))
+ old_p = fp->_p;
+ if (__fflush(fp) == EOF) {
+ if (old_p == fp->_p)
+ fp->_p -= w;
goto err;
+ }
} else if (s >= (w = fp->_bf._size)) {
w = _swrite(fp, p, w);
if (w <= 0)