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: 86a16ada1e
This commit is contained in:
parent
1fb00c8f10
commit
bafaa70b6f
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user