Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>"Broken pipe" is a normal error when the other end closes the pipe. In your case, this either means there is no "other end", or the other application hasn't written anything to its <code>stdout</code>. I've modified your code to be a compilable test case – there are two cases in which <code>ReadFile</code> fails without having read any data for me:</p> <ul> <li><code>CreateProcess</code> failed. I've added an <code>assert</code> so that problem will be recognizable. It would of course result in a broken pipe.</li> <li>The process does not write anything to standard output. It might instead write to its standard error stream. I've redirected <code>stderr</code> to the pipe as well, and as my <code>echo</code> example shows, this will receive both streams on the other end of the pipe now.</li> </ul> <p>Code:</p> <pre><code>#define WIN32_LEAN_AND_MEAN #include &lt;Windows.h&gt; #include &lt;assert.h&gt; #include &lt;stdio.h&gt; #include &lt;string.h&gt; #define BUFSIZE 200 int main(void) { BOOL bSuccess; char szCmdLine[MAX_PATH]; char chBuf[BUFSIZE]; DWORD dwRead; HANDLE g_hChildStd_OUT_Rd2 = NULL; HANDLE g_hChildStd_OUT_Wr2 = NULL; SECURITY_ATTRIBUTES saAttr2; STARTUPINFO si2; PROCESS_INFORMATION pi2; ZeroMemory( &amp;si2, sizeof(si2) ); si2.cb = sizeof(si2); ZeroMemory( &amp;pi2, sizeof(pi2) ); //create pipe saAttr2.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr2.bInheritHandle = TRUE; saAttr2.lpSecurityDescriptor = NULL; assert(CreatePipe(&amp;g_hChildStd_OUT_Rd2, &amp;g_hChildStd_OUT_Wr2, &amp;saAttr2, 0)); //create child process bSuccess = FALSE; memset(szCmdLine, 0, MAX_PATH); sprintf(szCmdLine, "cmd /c echo output &amp;&amp; echo error&gt;&amp;2"); ZeroMemory( &amp;pi2, sizeof(PROCESS_INFORMATION) ); ZeroMemory( &amp;si2, sizeof(STARTUPINFO) ); si2.cb = sizeof(STARTUPINFO); si2.hStdOutput = g_hChildStd_OUT_Wr2; si2.hStdError = g_hChildStd_OUT_Wr2; // also add the pipe as stderr! si2.dwFlags |= STARTF_USESTDHANDLES; assert(CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &amp;si2, &amp;pi2)); //read from pipe CloseHandle(g_hChildStd_OUT_Wr2); memset(chBuf, 0, BUFSIZE); for (;;) { bSuccess = ReadFile( g_hChildStd_OUT_Rd2, chBuf, BUFSIZE, &amp;dwRead, NULL); printf("%d %lu 0x%08lx\n", bSuccess, dwRead, GetLastError()); if (bSuccess) printf("\t'%*s'\n", (int)dwRead, chBuf); else break; } return 0; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload