summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/fvwrite.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2001-09-02 19:10:10 +0000
committerache <ache@FreeBSD.org>2001-09-02 19:10:10 +0000
commit245c459c3f4dcbc6da4c66aebc8879251e9af682 (patch)
treebe15c0be354e09f766522b411a1ad2af5d566a99 /lib/libc/stdio/fvwrite.c
parentb3ac07522908287b53a4f7e77f2e5205c4f72fb7 (diff)
downloadFreeBSD-src-245c459c3f4dcbc6da4c66aebc8879251e9af682.zip
FreeBSD-src-245c459c3f4dcbc6da4c66aebc8879251e9af682.tar.gz
Move all stdio internal flags processing and setting out of __sread(),
__swrite() and __sseek() to higher level. According to funopen(3) they all are just wrappers to something like standard read(2), write(2) and lseek(2), i.e. must not touch stdio internals because they are replaceable with any other functions knows nothing about stdio internals. See example of funopen(3) usage in sendmail sources f.e. NOTE: this is original stdio bug, not result of my range checkin added.
Diffstat (limited to 'lib/libc/stdio/fvwrite.c')
-rw-r--r--lib/libc/stdio/fvwrite.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c
index 82a49cb..efcfffb 100644
--- a/lib/libc/stdio/fvwrite.c
+++ b/lib/libc/stdio/fvwrite.c
@@ -64,7 +64,7 @@ __sfvwrite(fp, uio)
register struct __siov *iov;
register int w, s;
char *nl;
- int nlknown, nldist;
+ int nlknown, nldist, firsttime;
if ((len = uio->uio_resid) == 0)
return (0);
@@ -86,12 +86,21 @@ __sfvwrite(fp, uio)
len = iov->iov_len; \
iov++; \
}
+ firsttime = 1;
if (fp->_flags & __SNBF) {
/*
* Unbuffered: write up to BUFSIZ bytes at a time.
*/
do {
GETIOV(;);
+ if (firsttime) {
+ if ((fp->_flags & __SAPP) &&
+ _sseek(fp, (fpos_t)0, SEEK_END) == -1)
+ goto err;
+ /* In case FAPPEND mode is set. */
+ fp->_flags &= ~__SOFF;
+ firsttime = 0;
+ }
w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ));
if (w <= 0)
goto err;
@@ -147,6 +156,14 @@ __sfvwrite(fp, uio)
goto err;
} else if (len >= (w = fp->_bf._size)) {
/* write directly */
+ if (firsttime) {
+ if ((fp->_flags & __SAPP) &&
+ _sseek(fp, (fpos_t)0, SEEK_END) == -1)
+ goto err;
+ /* In case FAPPEND mode is set. */
+ fp->_flags &= ~__SOFF;
+ firsttime = 0;
+ }
w = (*fp->_write)(fp->_cookie, p, w);
if (w <= 0)
goto err;
@@ -186,6 +203,14 @@ __sfvwrite(fp, uio)
if (__fflush(fp))
goto err;
} else if (s >= (w = fp->_bf._size)) {
+ if (firsttime) {
+ if ((fp->_flags & __SAPP) &&
+ _sseek(fp, (fpos_t)0, SEEK_END) == -1)
+ goto err;
+ /* In case FAPPEND mode is set. */
+ fp->_flags &= ~__SOFF;
+ firsttime = 0;
+ }
w = (*fp->_write)(fp->_cookie, p, w);
if (w <= 0)
goto err;
OpenPOWER on IntegriCloud