Index: /trunk/src/kmk/output.c
===================================================================
--- /trunk/src/kmk/output.c	(revision 3190)
+++ /trunk/src/kmk/output.c	(revision 3191)
@@ -67,4 +67,6 @@
                                - offsetof (struct output_segment, runs) \
                                - sizeof (struct output_run))
+# define MEMBUF_MAX_TOTAL     (  sizeof (void *) <= 4 \
+                               ? (size_t)512*1024 : (size_t)16*1024*1024 )
 
 static void *acquire_semaphore (void);
@@ -220,6 +222,7 @@
 }
 
-/* Helper for membuf_new_segment_write that figures out now much data needs to
-   be moved from the previous run in order to make it end with a newline.  */
+/* Helper for membuf_write_new_segment and membuf_dump_most that figures out
+   now much data needs to be moved from the previous run in order to make it
+   end with a newline.  */
 static size_t membuf_calc_move_len (struct output_run *tail_run)
 {
@@ -242,5 +245,5 @@
    a newline so that we pass whole lines to fwrite when dumping. */
 static size_t
-membuf_new_segment_write (struct output_membuf *membuf, const char *src,
+membuf_write_new_segment (struct output_membuf *membuf, const char *src,
                           size_t len, unsigned int *pseqno)
 {
@@ -280,5 +283,5 @@
   membuf->tail_run = &new_seg->runs[0];
   membuf->total += segsize;
-  membuf->left = segsize - sizeof (struct output_run);
+  membuf->left = segsize - sizeof (struct output_run) - offset_runs;
 
   /* Initialize and write data to the first run. */
@@ -314,11 +317,55 @@
 }
 
-/* Worker for output_write that will try dump as much as possible of the
-   output, but making sure to try leave unfinished lines. */
+/* Worker for output_write that will dump most of the output when we hit
+   MEMBUF_MAX_TOTAL on either of the two membuf structures, then free all the
+   output segments.  Incomplete lines will be held over to the next buffers
+   and copied into new segments. */
 static void
 membuf_dump_most (struct output *out)
 {
-  /** @todo check last segment and make local copies.   */
-  membuf_dump (out);
+  size_t out_to_move = membuf_calc_move_len (out->out.tail_run);
+  size_t err_to_move = membuf_calc_move_len (out->err.tail_run);
+  if (!out_to_move && !err_to_move)
+    membuf_dump (out);
+  else
+    {
+      /* Allocate a stack buffer for holding incomplete lines.  This should be
+         fine since we're only talking about max 2 * MEMBUF_MAX_MOVE_LEN.
+         The -1 on the sequence numbers, ise because membuf_write_new_segment
+         will increment them before use. */
+      unsigned int out_seqno = out_to_move ? out->out.tail_run->seqno - 1 : 0;
+      unsigned int err_seqno = err_to_move ? out->err.tail_run->seqno - 1 : 0;
+      char *tmp = alloca (out_to_move + err_to_move);
+      if (out_to_move)
+        {
+          out->out.tail_run->len -= out_to_move;
+          memcpy (tmp,
+                  (char *)(out->out.tail_run + 1) + out->out.tail_run->len,
+                  out_to_move);
+        }
+      if (err_to_move)
+        {
+          out->err.tail_run->len -= err_to_move;
+          memcpy (tmp + out_to_move,
+                  (char *)(out->err.tail_run + 1) + out->err.tail_run->len,
+                  err_to_move);
+        }
+
+      membuf_dump (out);
+
+      if (out_to_move)
+        {
+          size_t written = membuf_write_new_segment (&out->out, tmp,
+                                                     out_to_move, &out_seqno);
+          assert (written == out_to_move); (void)written;
+        }
+      if (err_to_move)
+        {
+          size_t written = membuf_write_new_segment (&out->err,
+                                                     tmp + out_to_move,
+                                                     err_to_move, &err_seqno);
+          assert (written == err_to_move); (void)written;
+        }
+    }
 }
 
@@ -353,7 +400,6 @@
           if (!runlen)
             {
-              size_t max_total = sizeof (membuf) <= 4 ? 512*1024 : 16*1024*1024;
-              if (membuf->total < max_total)
-                runlen = membuf_new_segment_write (membuf, src, len, &out->seqno);
+              if (membuf->total < MEMBUF_MAX_TOTAL)
+                runlen = membuf_write_new_segment (membuf, src, len, &out->seqno);
               else
                 membuf_dump_most (out);
Index: /trunk/src/kmk/w32/winchildren.c
===================================================================
--- /trunk/src/kmk/w32/winchildren.c	(revision 3190)
+++ /trunk/src/kmk/w32/winchildren.c	(revision 3191)
@@ -677,5 +677,5 @@
         /* Move offPendingRead ahead by cbRead. */
         pPipe->offPendingRead += cbNewData;
-        assert(pPipe->offPendingRead < pPipe->cbBuffer);
+        assert(pPipe->offPendingRead <= pPipe->cbBuffer);
         if (pPipe->offPendingRead > pPipe->cbBuffer)
             pPipe->offPendingRead = pPipe->cbBuffer;
