Index: trunk/src/kmk/kmkbuiltin/append.c
===================================================================
--- trunk/src/kmk/kmkbuiltin/append.c	(revision 2754)
+++ trunk/src/kmk/kmkbuiltin/append.c	(revision 2756)
@@ -221,5 +221,7 @@
                 &&  memchr(pVar->value, '$', pVar->value_length))
             {
+                unsigned __int64 tsc_start = __rdtsc();
                 char *pszExpanded = allocated_variable_expand(pVar->value);
+                tsc_ref_var += __rdtsc() - tsc_start;
                 fwrite(pszExpanded, 1, strlen(pszExpanded), pFile);
                 free(pszExpanded);
Index: trunk/src/kmk/kmkbuiltin/echo.c
===================================================================
--- trunk/src/kmk/kmkbuiltin/echo.c	(revision 2754)
+++ trunk/src/kmk/kmkbuiltin/echo.c	(revision 2756)
@@ -73,4 +73,9 @@
 {
 	char *errstr = strerror(errno);
+#ifdef _MSC_VER
+	int doserrno = _doserrno;
+       char szDosErr[48];
+       sprintf(szDosErr, " (doserrno=%d)", doserrno);
+#endif
 	write(STDERR_FILENO, prog, strlen(prog));
 	write(STDERR_FILENO, ": ", 2);
@@ -78,4 +83,7 @@
 	write(STDERR_FILENO, ": ", 2);
 	write(STDERR_FILENO, errstr, strlen(errstr));
+#ifdef _MSC_VER
+	write(STDERR_FILENO, szDosErr, strlen(szDosErr));
+#endif
 	write(STDERR_FILENO, "\n", 1);
 }
Index: trunk/src/kmk/kmkbuiltin/mscfakes.c
===================================================================
--- trunk/src/kmk/kmkbuiltin/mscfakes.c	(revision 2754)
+++ trunk/src/kmk/kmkbuiltin/mscfakes.c	(revision 2756)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (c) 2005-2010 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
+ * Copyright (c) 2005-2015 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
  *
  * This file is part of kBuild.
@@ -28,4 +28,5 @@
 *******************************************************************************/
 #include "config.h"
+#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -42,4 +43,9 @@
 #include <Windows.h>
 #undef timeval
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static BOOL isPipeFd(int fd);
 
 
@@ -467,7 +473,71 @@
     for (i = 0; i < count; i++)
     {
-        int cb = (int)write(fd, vector[i].iov_base, (int)vector[i].iov_len);
+        int cb = write(fd, vector[i].iov_base, (int)vector[i].iov_len);
         if (cb < 0)
-            return -1;
+        {
+            /* ENOSPC on pipe kludge. */
+            char  *pbCur;
+            size_t cbLeft;
+            int    cbLimit;
+            int    cSinceLastSuccess;
+            int    iErr = errno;
+
+            if (errno != ENOSPC)
+                return -1;
+            if ((int)vector[i].iov_len == 0)
+                continue;
+            if (!isPipeFd(fd))
+            {
+                errno = ENOSPC;
+                return -1;
+            }
+
+            /* 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;
+            if (cbLimit < 4)
+                cbLimit = 4;
+            else if (cbLimit > 512)
+                cbLimit = 512;
+            cSinceLastSuccess = 0;
+
+            while (cbLeft > 0)
+            {
+                int cbAttempt = cbLeft > cbLimit ? (int)cbLimit : (int)cbLeft;
+                cb = write(fd, pbCur, cbAttempt);
+                if (cb > 0)
+                {
+                    assert(cb <= cbAttempt);
+                    pbCur  += cb;
+                    cbLeft -= cb;
+                    size   += cb;
+                    if (cbLimit < 32)
+                        cbLimit = 32;
+                    cSinceLastSuccess = 0;
+                }
+                else if (errno != ENOSPC)
+                    return -1;
+                else
+                {
+                    /* Delay for about 30 seconds, then just give up. */
+                    cSinceLastSuccess++;
+                    if (cSinceLastSuccess > 1860)
+                        return -1;
+                    if (cSinceLastSuccess <= 2)
+                        Sleep(0);
+                    else if (cSinceLastSuccess <= 66)
+                    {
+                        if (cbLimit >= 8)
+                            cbLimit /= 2; /* Just in case the pipe buffer is very very small. */
+                        Sleep(1);
+                    }
+                    else
+                        Sleep(16);
+                }
+            }
+            cb = 0;
+        }
         size += cb;
     }
@@ -536,4 +606,26 @@
 
 /**
+ * Checks if the given file descriptor is a pipe or not.
+ *
+ * @returns TRUE if pipe, FALSE if not.
+ * @param   fd                  The libc file descriptor number.
+ */
+static BOOL isPipeFd(int fd)
+{
+    /* Is pipe? */
+    HANDLE hFile = (HANDLE)_get_osfhandle(fd);
+    if (hFile != INVALID_HANDLE_VALUE)
+    {
+        DWORD fType = GetFileType(hFile);
+        fType &= ~FILE_TYPE_REMOTE;
+        if (fType == FILE_TYPE_PIPE)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+
+
+/**
  * This is a kludge to make pipe handles blocking.
  *
@@ -544,21 +636,15 @@
 static BOOL makePipeBlocking(int fd)
 {
-    /* Is pipe? */
-    HANDLE hFile = (HANDLE)_get_osfhandle(fd);
-    if (hFile != INVALID_HANDLE_VALUE)
-    {
-        DWORD fType = GetFileType(hFile);
-        fType &= ~FILE_TYPE_REMOTE;
-        if (fType == FILE_TYPE_PIPE)
-        {
-            /* Try fix it. */
-            DWORD fState = 0;
-            if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL,  0))
-            {
-                fState &= ~PIPE_NOWAIT;
-                fState |= PIPE_WAIT;
-                if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
-                    return TRUE;
-            }
+    if (isPipeFd(fd))
+    {
+        /* Try fix it. */
+        HANDLE hFile = (HANDLE)_get_osfhandle(fd);
+        DWORD fState = 0;
+        if (GetNamedPipeHandleState(hFile, &fState, NULL, NULL, NULL, NULL,  0))
+        {
+            fState &= ~PIPE_NOWAIT;
+            fState |= PIPE_WAIT;
+            if (SetNamedPipeHandleState(hFile, &fState, NULL, NULL))
+                return TRUE;
         }
     }
