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