diff options
| author | christos <christos@NetBSD.org> | 2021-07-16 12:34:10 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2021-07-16 12:34:10 +0000 |
| commit | e1270e10c8431707f8974dd7315ddc653f94b4a9 (patch) | |
| tree | d25efa281b92bb150377ca681f0b00de87e3b785 /lib | |
| parent | ad25d6503daa341060843b44f7d469e362deaac8 (diff) | |
When fflush fails, adjust pointers and the io vectors. From RVP. Fixes
core-dump at cvs(1) exit(3).
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/stdio/fvwrite.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c index 3e09e02b118..87e8bb628b0 100644 --- a/lib/libc/stdio/fvwrite.c +++ b/lib/libc/stdio/fvwrite.c @@ -1,4 +1,4 @@ -/* $NetBSD: fvwrite.c,v 1.27 2021/07/08 09:06:51 christos Exp $ */ +/* $NetBSD: fvwrite.c,v 1.28 2021/07/16 12:34:10 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: fvwrite.c,v 1.27 2021/07/08 09:06:51 christos Exp $"); +__RCSID("$NetBSD: fvwrite.c,v 1.28 2021/07/16 12:34:10 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -51,6 +51,40 @@ __RCSID("$NetBSD: fvwrite.c,v 1.27 2021/07/08 09:06:51 christos Exp $"); #include "local.h" #include "fvwrite.h" +static int +flush_adj(FILE *fp, struct __suio *uio, struct __siov *iov, ssize_t w) +{ + int rc; + + _DIAGASSERT(w >= 0); + _DIAGASSERT(fp->_w >= 0); + + if ((rc = fflush(fp)) == 0) + return 0; + + /* + * If we have to return without writing the whole buffer, + * adjust for how much fflush() has written for us. + * `w' is the amt. of new user data just copied into our + * internal buffer in _this_ fwrite() call. + */ + if (fp->_w < w) { + /* some new data was also written */ + ssize_t i = w - fp->_w; + + /* adjust amt. written */ + uio->uio_resid -= i; + iov->iov_len -= i; + } else { + /* only old stuff was written */ + + /* adjust _p and _w so user can retry */ + fp->_p -= w; + fp->_w += w; + } + return rc; +} + /* * Write some memory regions. Return zero on success, EOF on error. * @@ -102,10 +136,8 @@ __sfvwrite(FILE *fp, struct __suio *uio) if (w <= 0) \ goto err #define FLUSH(nw) \ - if (fflush(fp)) { \ - fp->_p -= nw; /* rewind unwritten */ \ - goto err; \ - } + if (flush_adj(fp, uio, iov - 1, nw)) \ + goto err if (fp->_flags & __SNBF) { /* |
