--- old/shf.c 2009/11/28 14:28:03 1.35 +++ new/shf.c 2010/07/19 22:41:04 1.36 @@ -636,32 +636,45 @@ shf_write(const char *buf, int nbytes, s shf->wnleft -= ncopy; } if (nbytes > 0) { - /* Flush deals with strings and sticky errors */ - if (shf_emptybuf(shf, EB_GROW) == EOF) - return (EOF); - if (nbytes > shf->wbsize) { - ncopy = nbytes; - if (shf->wbsize) - ncopy -= nbytes % shf->wbsize; - nbytes -= ncopy; - while (ncopy > 0) { - n = write(shf->fd, buf, ncopy); - if (n < 0) { - if (errno == EINTR && - !(shf->flags & SHF_INTERRUPT)) - continue; - shf->flags |= SHF_ERROR; - shf->errno_ = errno; - shf->wnleft = 0; - /* Note: fwrite(3S) returns 0 for - * errors - this doesn't */ + if (shf->flags & SHF_STRING) { + /* resize buffer until there's enough space left */ + while (nbytes > shf->wnleft) + if (shf_emptybuf(shf, EB_GROW) == EOF) return (EOF); + /* then write everything into the buffer */ + } else { + /* flush deals with sticky errors */ + if (shf_emptybuf(shf, EB_GROW) == EOF) + return (EOF); + /* write chunks larger than window size directly */ + if (nbytes > shf->wbsize) { + ncopy = nbytes; + if (shf->wbsize) + ncopy -= nbytes % shf->wbsize; + nbytes -= ncopy; + while (ncopy > 0) { + n = write(shf->fd, buf, ncopy); + if (n < 0) { + if (errno == EINTR && + !(shf->flags & SHF_INTERRUPT)) + continue; + shf->flags |= SHF_ERROR; + shf->errno_ = errno; + shf->wnleft = 0; + /* + * Note: fwrite(3) returns 0 + * for errors - this doesn't + */ + return (EOF); + } + buf += n; + ncopy -= n; } - buf += n; - ncopy -= n; } + /* ... and buffer the rest */ } if (nbytes > 0) { + /* write remaining bytes to buffer */ memcpy(shf->wp, buf, nbytes); shf->wp += nbytes; shf->wnleft -= nbytes;