Index: /trunk/src/kmk/config.h.win
===================================================================
--- /trunk/src/kmk/config.h.win	(revision 2758)
+++ /trunk/src/kmk/config.h.win	(revision 2759)
@@ -16,4 +16,7 @@
 GNU Make; see the file COPYING.  If not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
+
+#ifndef ___config_h_win
+#define ___config_h_win
 
 /* Suppress some Visual C++ warnings.
@@ -534,6 +537,5 @@
 #define _DIRENT_HAVE_D_TYPE   1
 
-
-/* cygwin sucks to much in one end or the other. */
+/* bird: Not sure if this is necessary any more... */
 #define BATCH_MODE_ONLY_SHELL
 
@@ -557,2 +559,9 @@
 #endif
 
+/* bird: Include mscfakes.h to make sure we have all it's tricks applied. */
+#ifndef ___mscfakes_h
+# include "kmkbuiltin/mscfakes.h"
+#endif
+
+#endif /* bird */
+
Index: /trunk/src/kmk/kmkbuiltin/kDepObj.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/kDepObj.c	(revision 2758)
+++ /trunk/src/kmk/kmkbuiltin/kDepObj.c	(revision 2759)
@@ -27,4 +27,5 @@
 *   Header Files                                                               *
 *******************************************************************************/
+#define MSCFAKES_NO_WINDOWS_H
 #include "config.h"
 #include <stdio.h>
Index: /trunk/src/kmk/kmkbuiltin/mscfakes.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/mscfakes.c	(revision 2758)
+++ /trunk/src/kmk/kmkbuiltin/mscfakes.c	(revision 2759)
@@ -467,24 +467,31 @@
 
 
-int writev(int fd, const struct iovec *vector, int count)
-{
-    int size = 0;
-    int i;
-    for (i = 0; i < count; i++)
-    {
-        int cb = write(fd, vector[i].iov_base, (int)vector[i].iov_len);
-        if (cb < 0)
+/* We override the libc write function (in our modules only, unfortunately) so
+   we can kludge our way around a ENOSPC problem observed on build servers
+   capturing STDOUT and STDERR via pipes.  Apparently this may happen when the
+   pipe buffer is full, even with the mscfake_init hack in place.
+
+   XXX: Probably need to hook into fwrite as well. */
+ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc)
+{
+    ssize_t cbRet;
+    if (cbSrc < UINT_MAX / 4)
+    {
+#ifndef MSC_WRITE_TEST
+        cbRet = _write(fd, pvSrc, (unsigned int)cbSrc);
+#else
+        cbRet = -1; errno = ENOSPC;
+#endif
+        if (cbRet < 0)
         {
             /* ENOSPC on pipe kludge. */
-            char  *pbCur;
-            size_t cbLeft;
-            int    cbLimit;
-            int    cSinceLastSuccess;
-            int    iErr = errno;
-
+            int cbLimit;
+            int cSinceLastSuccess;
+
+            if (cbSrc == 0)
+                return 0;
             if (errno != ENOSPC)
                 return -1;
-            if ((int)vector[i].iov_len == 0)
-                continue;
+#ifndef MSC_WRITE_TEST
             if (!isPipeFd(fd))
             {
@@ -492,10 +499,9 @@
                 return -1;
             }
+#endif
 
             /* Likely a full pipe buffer, try write smaller amounts and do some
                sleeping inbetween each unsuccessful one. */
-            pbCur = vector[i].iov_base;
-            cbLeft = vector[i].iov_len;
-            cbLimit = cbLeft / 4;
+            cbLimit = cbSrc / 4;
             if (cbLimit < 4)
                 cbLimit = 4;
@@ -503,17 +509,23 @@
                 cbLimit = 512;
             cSinceLastSuccess = 0;
-
-            while (cbLeft > 0)
+            cbRet = 0;
+#ifdef MSC_WRITE_TEST
+            cbLimit = 4;
+#endif
+
+            while (cbSrc > 0)
             {
-                int cbAttempt = cbLeft > cbLimit ? (int)cbLimit : (int)cbLeft;
-                cb = write(fd, pbCur, cbAttempt);
-                if (cb > 0)
+                unsigned int cbAttempt = cbSrc > cbLimit ? (int)cbLimit : (int)cbSrc;
+                ssize_t cbActual = _write(fd, pvSrc, cbAttempt);
+                if (cbActual > 0)
                 {
-                    assert(cb <= cbAttempt);
-                    pbCur  += cb;
-                    cbLeft -= cb;
-                    size   += cb;
+                    assert(cbActual <= (ssize_t)cbAttempt);
+                    pvSrc  = (char *)pvSrc + cbActual;
+                    cbSrc -= cbActual;
+                    cbRet += cbActual;
+#ifndef MSC_WRITE_TEST
                     if (cbLimit < 32)
                         cbLimit = 32;
+#endif
                     cSinceLastSuccess = 0;
                 }
@@ -538,6 +550,40 @@
                 }
             }
-            cb = 0;
-        }
+        }
+    }
+    else
+    {
+        /*
+         * Type limit exceeded. Split the job up.
+         */
+        cbRet = 0;
+        while (cbSrc > 0)
+        {
+            size_t  cbToWrite = cbSrc > UINT_MAX / 4 ? UINT_MAX / 4 : cbSrc;
+            ssize_t cbWritten = msc_write(fd, pvSrc, cbToWrite);
+            if (cbWritten > 0)
+            {
+                pvSrc  = (char *)pvSrc + (size_t)cbWritten;
+                cbSrc -= (size_t)cbWritten;
+                cbRet += (size_t)cbWritten;
+            }
+            else if (cbWritten == 0 || cbRet > 0)
+                break;
+            else
+                return -1;
+        }
+    }
+    return cbRet;
+}
+
+ssize_t writev(int fd, const struct iovec *vector, int count)
+{
+    int size = 0;
+    int i;
+    for (i = 0; i < count; i++)
+    {
+        int cb = msc_write(fd, vector[i].iov_base, (int)vector[i].iov_len);
+        if (cb < 0)
+            return cb;
         size += cb;
     }
@@ -626,5 +672,4 @@
 
 
-
 /**
  * This is a kludge to make pipe handles blocking.
Index: /trunk/src/kmk/kmkbuiltin/mscfakes.h
===================================================================
--- /trunk/src/kmk/kmkbuiltin/mscfakes.h	(revision 2758)
+++ /trunk/src/kmk/kmkbuiltin/mscfakes.h	(revision 2759)
@@ -28,4 +28,7 @@
 #ifdef _MSC_VER
 
+/* Include the config file (kmk's) so we don't need to duplicate stuff from it here. */
+#include "config.h"
+
 #include <io.h>
 #include <direct.h>
@@ -34,6 +37,8 @@
 #include <malloc.h>
 #include "getopt.h"
+#ifndef MSCFAKES_NO_WINDOWS_H
+# include <Windows.h>
+#endif
 
-/* Note: Duplicated it config.h.win */
 #include <sys/stat.h>
 #include <io.h>
@@ -79,10 +84,14 @@
 typedef unsigned short gid_t;
 #endif
+#if defined(_M_AMD64) || defined(_M_X64) || defined(_M_IA64) || defined(_WIN64)
+typedef __int64 ssize_t;
+#else
 typedef long ssize_t;
+#endif
 typedef unsigned long u_long;
 typedef unsigned int u_int;
 typedef unsigned short u_short;
 
-#ifndef timerisset
+#if !defined(timerisset) && defined(MSCFAKES_NO_WINDOWS_H)
 struct timeval
 {
@@ -138,7 +147,10 @@
 int symlink(const char *pszDst, const char *pszLink);
 int utimes(const char *pszPath, const struct timeval *paTimes);
-int writev(int fd, const struct iovec *vector, int count);
+ssize_t writev(int fd, const struct iovec *vector, int count);
 
-
+/* bird write ENOSPC hacks. */
+#undef write
+#define write msc_write
+ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc);
 
 /*
