Index: /trunk/src/kmk/w32/winchildren.c
===================================================================
--- /trunk/src/kmk/w32/winchildren.c	(revision 3195)
+++ /trunk/src/kmk/w32/winchildren.c	(revision 3196)
@@ -172,4 +172,7 @@
     /** Set if core was dumped. */
     int                     fCoreDumped;
+    /** Set if the a child process is a candidate for cl.exe where we supress
+     * annoying source name output. */
+    BOOL                    fProbableClExe;
 
     /** Type specific data. */
@@ -268,4 +271,8 @@
     /** Set if we've got a read pending already. */
     BOOL                fReadPending;
+    /** Indicator that we've written out something.  This is cleared before
+     * we start catching output from a new child and use in the CL.exe
+     * supression heuristics. */
+    BOOL                fHaveWrittenOut;
     /** Number of bytes at the start of the buffer that we've already
      * written out.  We try write out whole lines. */
@@ -641,5 +648,7 @@
 static void mkWinChildcareWorkerFlushUnwritten(PWINCHILD pChild, PWINCCWPIPE pPipe)
 {
-    DWORD cbUnwritten = pPipe->cbWritten - pPipe->offPendingRead;
+    DWORD cbUnwritten = pPipe->offPendingRead - pPipe->cbWritten;
+    assert(pPipe->cbWritten      <= pPipe->cbBuffer - 16);
+    assert(pPipe->offPendingRead <= pPipe->cbBuffer - 16);
     if (cbUnwritten)
     {
@@ -658,5 +667,38 @@
                 pPipe->cbWritten += cbWritten <= cbUnwritten ? cbWritten : cbUnwritten; /* paranoia */
         }
-    }
+        pPipe->fHaveWrittenOut = TRUE;
+    }
+}
+
+/**
+ * This logic mirrors kwSandboxConsoleFlushAll.
+ *
+ * @returns TRUE if it looks like a CL.EXE source line, otherwise FALSE.
+ * @param   pPipe               The pipe.
+ * @param   offStart            The start of the output in the pipe buffer.
+ * @param   offEnd              The end of the output in the pipe buffer.
+ */
+static BOOL mkWinChildcareWorkerIsClExeSourceLine(PWINCCWPIPE pPipe, DWORD offStart, DWORD offEnd)
+{
+    if (offEnd < offStart + 2)
+        return FALSE;
+    if (offEnd - offStart > 80)
+        return FALSE;
+
+    if (   pPipe->pbBuffer[offEnd - 2] != '\r'
+        || pPipe->pbBuffer[offEnd - 1] != '\n')
+        return FALSE;
+
+    offEnd -= 2;
+    while (offEnd-- > offStart)
+    {
+        char ch = pPipe->pbBuffer[offEnd];
+        if (isalnum(ch) || ch == '.' || ch == ' ' || ch == '_' || ch == '-')
+        { /* likely */ }
+        else
+            return FALSE;
+    }
+
+    return TRUE;
 }
 
@@ -675,4 +717,6 @@
     DWORD offStart = pPipe->cbWritten;
     assert(offStart <= pPipe->offPendingRead);
+    assert(offStart <= pPipe->cbBuffer - 16);
+    assert(pPipe->offPendingRead <= pPipe->cbBuffer - 16);
     if (cbNewData > 0)
     {
@@ -692,8 +736,6 @@
         /* If none were found and we've less than 16 bytes left in the buffer, try
            find a word boundrary to flush on instead. */
-        if (   offRest > offStart
-            || pPipe->cbBuffer - pPipe->offPendingRead + offStart > 16)
-        { /* likely */ }
-        else
+        if (   offRest <= offStart
+            && pPipe->cbBuffer - pPipe->offPendingRead + offStart < 16)
         {
             offRest = pPipe->offPendingRead;
@@ -704,4 +746,12 @@
                 offRest = pPipe->offPendingRead;
         }
+        /* If this is a potential CL.EXE process, we will keep the source
+           filename unflushed and maybe discard it at the end. */
+        else if (   pChild->fProbableClExe
+                 && pPipe->iWhich == 1
+                 && offRest == pPipe->offPendingRead
+                 && mkWinChildcareWorkerIsClExeSourceLine(pPipe, offStart, offRest))
+            offRest = offStart;
+
         if (offRest > offStart)
         {
@@ -726,4 +776,5 @@
                 }
             }
+            pPipe->fHaveWrittenOut = TRUE;
         }
     }
@@ -745,8 +796,8 @@
  * @param   pChild          The child.
  * @param   pPipe           The pipe.
- * @param   fFlushing       Set if we're flushing the pipe after the process
+ * @param   fDraining       Set if we're draining the pipe after the process
  *                          terminated.
  */
-static void mkWinChildcareWorkerCatchOutput(PWINCHILD pChild, PWINCCWPIPE pPipe, BOOL fFlushing)
+static void mkWinChildcareWorkerCatchOutput(PWINCHILD pChild, PWINCCWPIPE pPipe, BOOL fDraining)
 {
     /*
@@ -756,20 +807,16 @@
     {
         DWORD cbRead = 0;
-        if (GetOverlappedResult(pPipe->hPipeMine, &pPipe->Overlapped, &cbRead, !fFlushing))
+        if (GetOverlappedResult(pPipe->hPipeMine, &pPipe->Overlapped, &cbRead, !fDraining))
         {
             mkWinChildcareWorkerCaughtMoreOutput(pChild, pPipe, cbRead);
             pPipe->fReadPending = FALSE;
         }
-        else if (fFlushing && GetLastError() == ERROR_IO_INCOMPLETE)
-        {
-            if (pPipe->offPendingRead > pPipe->cbWritten)
-                mkWinChildcareWorkerFlushUnwritten(pChild, pPipe);
+        else if (fDraining && GetLastError() == ERROR_IO_INCOMPLETE)
             return;
-        }
         else
         {
             fprintf(stderr, "warning: GetOverlappedResult failed: %u\n", GetLastError());
             pPipe->fReadPending = FALSE;
-            if (fFlushing)
+            if (fDraining)
                 return;
         }
@@ -807,4 +854,35 @@
 
 /**
+ * Makes sure the output pipes are drained and pushed to output.
+ *
+ * @param   pWorker             The worker.
+ * @param   pChild              The child.
+ */
+static void mkWinChildcareWorkerDrainPipes(PWINCHILDCAREWORKER pWorker, PWINCHILD pChild)
+{
+    mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdOut, TRUE /*fDraining*/);
+    mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdErr, TRUE /*fDraining*/);
+
+    /* Drop lone 'source.c' line from CL.exe, but only if no other output at all. */
+    if (   pChild->fProbableClExe
+        && !pWorker->StdOut.fHaveWrittenOut
+        && !pWorker->StdErr.fHaveWrittenOut
+        && pWorker->StdErr.cbWritten == pWorker->StdErr.offPendingRead
+        && pWorker->StdOut.cbWritten < pWorker->StdOut.offPendingRead
+        && mkWinChildcareWorkerIsClExeSourceLine(&pWorker->StdOut, pWorker->StdOut.cbWritten, pWorker->StdOut.offPendingRead))
+    {
+        if (!pWorker->StdOut.fReadPending)
+            pWorker->StdOut.cbWritten = pWorker->StdOut.offPendingRead = 0;
+        else
+            pWorker->StdOut.cbWritten = pWorker->StdOut.offPendingRead;
+    }
+    else
+    {
+        mkWinChildcareWorkerFlushUnwritten(pChild, &pWorker->StdOut);
+        mkWinChildcareWorkerFlushUnwritten(pChild, &pWorker->StdErr);
+    }
+}
+
+/**
  * Commmon worker for waiting on a child process and retrieving the exit code.
  *
@@ -822,4 +900,9 @@
     DWORD const msStart = GetTickCount();
     DWORD       msNextMsg = msStart + 15000;
+
+    /* Reset the written indicators on the pipes before we start loop. */
+    pWorker->StdOut.fHaveWrittenOut = FALSE;
+    pWorker->StdErr.fHaveWrittenOut = FALSE;
+
     for (;;)
     {
@@ -835,7 +918,7 @@
             dwStatus = WaitForMultipleObjects(3, ahHandles, FALSE /*fWaitAll*/, 1000 /*ms*/);
             if (dwStatus == WAIT_OBJECT_0 + 1)
-                mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdOut, FALSE /*fFlushing*/);
+                mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdOut, FALSE /*fDraining*/);
             else if (dwStatus == WAIT_OBJECT_0 + 2)
-                mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdErr, FALSE /*fFlushing*/);
+                mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdErr, FALSE /*fDraining*/);
         }
         assert(dwStatus != WAIT_FAILED);
@@ -850,9 +933,6 @@
             {
                 pChild->iExitCode = (int)dwExitCode;
-                if (!fCatchOutput)
-                {
-                    mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdOut, TRUE /*fFlushing*/);
-                    mkWinChildcareWorkerCatchOutput(pChild, &pWorker->StdErr, TRUE /*fFlushing*/);
-                }
+                if (fCatchOutput)
+                    mkWinChildcareWorkerDrainPipes(pWorker, pChild);
                 return dwExitCode;
             }
@@ -1464,4 +1544,23 @@
 }
 
+/**
+ * Checks if the image path looks like microsoft CL.exe.
+ *
+ * @returns TRUE / FALSE.
+ * @param   pwszImagePath   The executable image path to evalutate.
+ * @param   cwcImagePath    The length of the image path.
+ */
+static BOOL mkWinChildIsProbableClExe(WCHAR const *pwszImagePath, size_t cwcImagePath)
+{
+    assert(pwszImagePath[cwcImagePath] == '\0');
+    return cwcImagePath > 7
+        && (pwszImagePath[cwcImagePath - 7] == L'/' || pwszImagePath[cwcImagePath - 7] == L'\\')
+        && (pwszImagePath[cwcImagePath - 6] == L'c' || pwszImagePath[cwcImagePath - 6] == L'C')
+        && (pwszImagePath[cwcImagePath - 5] == L'l' || pwszImagePath[cwcImagePath - 5] == L'L')
+        &&  pwszImagePath[cwcImagePath - 4] == L'.'
+        && (pwszImagePath[cwcImagePath - 3] == L'e' || pwszImagePath[cwcImagePath - 3] == L'E')
+        && (pwszImagePath[cwcImagePath - 2] == L'x' || pwszImagePath[cwcImagePath - 2] == L'X')
+        && (pwszImagePath[cwcImagePath - 1] == L'e' || pwszImagePath[cwcImagePath - 1] == L'E');
+}
 
 /**
@@ -1483,7 +1582,8 @@
  *                          could be the shell.
  * @param   pfNeedShell     Where to return shell vs direct execution indicator.
+ * @param   pfProbableClExe Where to return an indicator of probably CL.EXE.
  */
 static int mkWinChildcareWorkerFindImage(char const *pszArg0, WCHAR *pwszSearchPath, WCHAR const *pwszzEnv,
-                                         const char *pszShell, WCHAR **ppwszImagePath, BOOL *pfNeedShell)
+                                         const char *pszShell, WCHAR **ppwszImagePath, BOOL *pfNeedShell, BOOL *pfProbableClExe)
 {
     /** @todo Slap a cache on this code. We usually end up executing the same
@@ -1528,6 +1628,7 @@
             *pwc++ = L'\\';
 
-        /* Don't need to set this all the time... */
+        /* Don't need to set these all the time... */
         *pfNeedShell = FALSE;
+        *pfProbableClExe = FALSE;
 
         /*
@@ -1572,5 +1673,8 @@
             if (GetFileAttributesW(pwszPath) != INVALID_FILE_ATTRIBUTES)
 #endif
+            {
+                *pfProbableClExe = mkWinChildIsProbableClExe(pwszPath, cwcPath + 4 - 1);
                 return mkWinChildDuplicateUtf16String(pwszPath, cwcPath + 4, ppwszImagePath);
+            }
 
             /*
@@ -1592,5 +1696,8 @@
                         CloseHandle(hFile);
                         if (!*pfNeedShell)
+                        {
+                            *pfProbableClExe = mkWinChildIsProbableClExe(pwszPath, cwcPath - 1);
                             return mkWinChildDuplicateUtf16String(pwszPath, cwcPath, ppwszImagePath);
+                        }
                     }
                 }
@@ -1714,5 +1821,8 @@
                         && !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
 #endif
+                    {
+                        *pfProbableClExe = mkWinChildIsProbableClExe(wszPathBuf, cwcCombined + (fHasExeSuffix ? 0 : 4) - 1);
                         return mkWinChildDuplicateUtf16String(wszPathBuf, cwcCombined + (fHasExeSuffix ? 0 : 4), ppwszImagePath);
+                    }
                     if (!fHasExeSuffix)
                     {
@@ -1733,5 +1843,8 @@
                                 CloseHandle(hFile);
                                 if (!*pfNeedShell)
+                                {
+                                    *pfProbableClExe = mkWinChildIsProbableClExe(wszPathBuf, cwcCombined - 1);
                                     return mkWinChildDuplicateUtf16String(wszPathBuf, cwcCombined, ppwszImagePath);
+                                }
                                 break;
                             }
@@ -1957,4 +2070,5 @@
     WCHAR  *pwszImageName    = NULL;
     BOOL    fNeedShell       = FALSE;
+    BOOL    fProbableClExe   = FALSE;
     int     rc;
 
@@ -1972,5 +2086,5 @@
     if (rc == 0)
         rc = mkWinChildcareWorkerFindImage(pChild->u.Process.papszArgs[0], pwszSearchPath, pwszzEnvironment,
-                                           pChild->u.Process.pszShell, &pwszImageName, &fNeedShell);
+                                           pChild->u.Process.pszShell, &pwszImageName, &fNeedShell, &pChild->fProbableClExe);
     if (rc == 0)
     {
@@ -2928,7 +3042,9 @@
     WCHAR              *pwszCwd          = NULL;
     BOOL                fNeedShell       = FALSE;
+    PWINCHILD           pChild;
     int                 rc;
     assert(pWorker->uMagic == WINCHILDCAREWORKER_MAGIC);
-    assert(pWorker->pCurChild != NULL && pWorker->pCurChild->uMagic == WINCHILD_MAGIC);
+    pChild = pWorker->pCurChild;
+    assert(pChild != NULL && pChild->uMagic == WINCHILD_MAGIC);
 
     /*
@@ -2961,6 +3077,6 @@
      */
     if (rc == 0)
-        rc = mkWinChildcareWorkerFindImage(pszExecutable, pwszSearchPath, pwszzEnvironment,
-                                           NULL /*pszNull*/, &pwszImageName, &fNeedShell);
+        rc = mkWinChildcareWorkerFindImage(pszExecutable, pwszSearchPath, pwszzEnvironment, NULL /*pszShell*/,
+                                           &pwszImageName, &fNeedShell, &pChild->fProbableClExe);
     if (rc == 0)
     {
@@ -2984,6 +3100,5 @@
                  * Wait for the child to complete.
                  */
-                rc = mkWinChildcareWorkerWaitForProcess(pWorker, pWorker->pCurChild, hProcess, pwszImageName,
-                                                        TRUE /*fCatchOutput*/);
+                rc = mkWinChildcareWorkerWaitForProcess(pWorker, pChild, hProcess, pwszImageName, TRUE /*fCatchOutput*/);
                 CloseHandle(hProcess);
             }
