diff options
author | ache <ache@FreeBSD.org> | 2001-09-02 19:10:10 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2001-09-02 19:10:10 +0000 |
commit | 245c459c3f4dcbc6da4c66aebc8879251e9af682 (patch) | |
tree | be15c0be354e09f766522b411a1ad2af5d566a99 /lib/libc/stdio/fvwrite.c | |
parent | b3ac07522908287b53a4f7e77f2e5205c4f72fb7 (diff) | |
download | FreeBSD-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.c | 27 |
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; |