123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include "local.h"
- #include "fvwrite.h"
- int
- __sfvwrite(FILE *fp, struct __suio *uio)
- {
- size_t len;
- char *p;
- struct __siov *iov;
- int w, s;
- char *nl;
- int nlknown, nldist;
- if ((len = uio->uio_resid) == 0)
- return (0);
-
- if (cantwrite(fp)) {
- errno = EBADF;
- return (EOF);
- }
- #define MIN(a, b) ((a) < (b) ? (a) : (b))
- #define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
- iov = uio->uio_iov;
- p = iov->iov_base;
- len = iov->iov_len;
- iov++;
- #define GETIOV(extra_work) \
- while (len == 0) { \
- extra_work; \
- p = iov->iov_base; \
- len = iov->iov_len; \
- iov++; \
- }
- if (fp->_flags & __SNBF) {
- goto err;
- #if 0
-
- do {
- GETIOV(;);
- w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ));
- if (w <= 0)
- goto err;
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- #endif
- } else if ((fp->_flags & __SLBF) == 0) {
-
- do {
- GETIOV(;);
- if ((fp->_flags & (__SALC | __SSTR)) ==
- (__SALC | __SSTR) && fp->_w < len) {
- size_t blen = fp->_p - fp->_bf._base;
- unsigned char *_base;
- int _size;
-
- _size = fp->_bf._size;
- do {
- _size = (_size << 1) + 1;
- } while (_size < blen + len);
- _base = realloc(fp->_bf._base, _size + 1);
- if (_base == NULL)
- goto err;
- fp->_w += _size - fp->_bf._size;
- fp->_bf._base = _base;
- fp->_bf._size = _size;
- fp->_p = _base + blen;
- }
- w = fp->_w;
- if (fp->_flags & __SSTR) {
- if (len < w)
- w = len;
- COPY(w);
- fp->_w -= w;
- fp->_p += w;
- w = len;
- } else if (fp->_p > fp->_bf._base && len > w) {
- #if 0
-
- COPY(w);
-
- fp->_p += w;
- if (__sflush(fp))
- #endif
- goto err;
- } else if (len >= (w = fp->_bf._size)) {
- #if 0
-
- w = (*fp->_write)(fp->_cookie, p, w);
- if (w <= 0)
- #endif
- goto err;
- } else {
-
- w = len;
- COPY(w);
- fp->_w -= w;
- fp->_p += w;
- }
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- } else {
-
- nlknown = 0;
- nldist = 0;
- do {
- GETIOV(nlknown = 0);
- if (!nlknown) {
- nl = memchr((void *)p, '\n', len);
- nldist = nl ? nl + 1 - p : len + 1;
- nlknown = 1;
- }
- s = MIN(len, nldist);
- w = fp->_w + fp->_bf._size;
- if (fp->_p > fp->_bf._base && s > w) {
- #if 0
- COPY(w);
-
- fp->_p += w;
- if (__sflush(fp))
- #endif
- goto err;
- } else if (s >= (w = fp->_bf._size)) {
- #if 0
- w = (*fp->_write)(fp->_cookie, p, w);
- if (w <= 0)
- #endif
- goto err;
- } else {
- w = s;
- COPY(w);
- fp->_w -= w;
- fp->_p += w;
- }
- if ((nldist -= w) == 0) {
- #if 0
-
- if (__sflush(fp))
- #endif
- goto err;
-
- }
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- }
- return (0);
- err:
- fp->_flags |= __SERR;
- return (EOF);
- }
|