+
+size_t wxPipeInputStream::OnSysRead(void *buffer, size_t len)
+{
+ if ( !IsOpened() )
+ {
+ m_lasterror = wxSTREAM_EOF;
+
+ return 0;
+ }
+
+ DWORD bytesRead;
+ if ( !::ReadFile(m_hInput, buffer, len, &bytesRead, NULL) )
+ {
+ m_lasterror = ::GetLastError() == ERROR_BROKEN_PIPE
+ ? wxSTREAM_EOF
+ : wxSTREAM_READ_ERROR;
+ }
+
+ // bytesRead is set to 0, as desired, if an error occurred
+ return bytesRead;
+}
+
+// ----------------------------------------------------------------------------
+// wxPipeOutputStream
+// ----------------------------------------------------------------------------
+
+wxPipeOutputStream::wxPipeOutputStream(HANDLE hOutput)
+{
+ m_hOutput = hOutput;
+
+ // unblock the pipe to prevent deadlocks when we're writing to the pipe
+ // from which the child process can't read because it is writing in its own
+ // end of it
+ DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT;
+ if ( !::SetNamedPipeHandleState
+ (
+ m_hOutput,
+ &mode,
+ NULL, // collection count (we don't set it)
+ NULL // timeout (we don't set it neither)
+ ) )
+ {
+ wxLogLastError(_T("SetNamedPipeHandleState(PIPE_NOWAIT)"));
+ }
+}
+
+bool wxPipeOutputStream::Close()
+{
+ return ::CloseHandle(m_hOutput) != 0;
+}
+
+
+size_t wxPipeOutputStream::OnSysWrite(const void *buffer, size_t len)
+{
+ m_lasterror = wxSTREAM_NO_ERROR;
+
+ DWORD totalWritten = 0;
+ while ( len > 0 )
+ {
+ DWORD chunkWritten;
+ if ( !::WriteFile(m_hOutput, buffer, len, &chunkWritten, NULL) )
+ {
+ m_lasterror = ::GetLastError() == ERROR_BROKEN_PIPE
+ ? wxSTREAM_EOF
+ : wxSTREAM_WRITE_ERROR;
+ break;
+ }
+
+ if ( !chunkWritten )
+ break;
+
+ buffer = (char *)buffer + chunkWritten;
+ totalWritten += chunkWritten;
+ len -= chunkWritten;
+ }
+
+ return totalWritten;
+}
+
+#endif // wxUSE_STREAMS
+
+// ============================================================================
+// wxExecute functions family
+// ============================================================================