diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-11-15 20:45:21 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-15 20:45:21 -0500 |
| commit | 914a3808ebefb0f7f0a728469a2ce6b56dfc316c (patch) | |
| tree | 9e452c21cf2a1d89d180818c65c6e7909f3328cf /source/core/windows | |
| parent | ae9df74fce7e3583effc822b3003542cf753823d (diff) | |
Http protocol support (#2012)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Use 'Process' to communicate with an command line tool.
* Remove slang-win-stream
* Tidy up windows ProcessUtil.
* First version of BufferedReadStream.
* Windows working IPC for steams.
* Test proxy count option.
* Split Process/ProcessUtil. Process is platform dependant. ProcessUtil are functions that are platform independent.
* First implementation of Unix Process interface.
* Unix process compiles on cygwin.
* Fix typo in unix process.
* Separate unix pipe stream error of invalid access, from pipe availability.
* Fix in standard line extraction.
* Make fd non blocking.
* Fix issues with Windows Process streams.
* Added UnixPipe.
* Some fixes around UnixPipeStream.
* Make a unix stream closed explicit.
* Hack to debug linux process/stream.
* Revert to old linux pipe handling.
* Pass executable path for unit tests.
Split out CommandLine into own source.
* Small improvements in process/command line.
* Check process behavior with crash.
* Make stderr and stdout unbuffered for crash testing.
* Only turn disable buffering in crash test.
* Disable crash test on CI.
* Fix crash on clang/linux.
* Enable crash test.
Remove _appendBuffer as can use StreamUtil functionality.
* Added inital processing for http headers.
* Small improvements to HttpHeader.
* First pass HTTPPacketConnection working on windows.
* Enable other Process communication tests.
* Update comments.
Diffstat (limited to 'source/core/windows')
| -rw-r--r-- | source/core/windows/slang-win-process.cpp | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/source/core/windows/slang-win-process.cpp b/source/core/windows/slang-win-process.cpp index 57eb209c3..c37936a30 100644 --- a/source/core/windows/slang-win-process.cpp +++ b/source/core/windows/slang-win-process.cpp @@ -103,6 +103,7 @@ protected: FileAccess m_access = FileAccess::None; WinHandle m_streamHandle; bool m_isOwned; + bool m_isPipe; }; @@ -135,10 +136,17 @@ WinPipeStream::WinPipeStream(HANDLE handle, FileAccess access, bool isOwned) : m_access(access), m_isOwned(isOwned) { - // It might be handy to get information about the handle - // https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-getnamedpipeinfo + // On Win32 a HANDLE has to be handled differently if it's a PIPE or FILE, so first determine + // if it really is a pipe. + // http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx + m_isPipe = ::GetFileType(handle) == FILE_TYPE_PIPE; + + if (m_isPipe) { + // It might be handy to get information about the handle + // https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-getnamedpipeinfo + DWORD flags, outBufferSize, inBufferSize, maxInstances; // It appears that by default windows pipe buffer size is 4k. if (GetNamedPipeInfo(handle, &flags, &outBufferSize, &inBufferSize, &maxInstances)) @@ -181,31 +189,40 @@ SlangResult WinPipeStream::read(void* buffer, size_t length, size_t& outReadByte return SLANG_OK; } + DWORD bytesRead = 0; + // Check if there is any data, so won't block + if (m_isPipe) { - DWORD bytesRead = 0; - DWORD totalBytes = 0; - DWORD remainingBytes = 0; + DWORD pipeBytesRead = 0; + DWORD pipeTotalBytesAvailable = 0; + DWORD pipeRemainingBytes = 0; // Works on anonymous pipes too // https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-peeknamedpipe - SLANG_RETURN_ON_FAIL(_updateState(PeekNamedPipe(m_streamHandle, nullptr, DWORD(0), &bytesRead, &totalBytes, &remainingBytes))); + SLANG_RETURN_ON_FAIL(_updateState(::PeekNamedPipe(m_streamHandle, nullptr, DWORD(0), &pipeBytesRead, &pipeTotalBytesAvailable, &pipeRemainingBytes))); // If there is nothing to read we are done // If we don't do this ReadFile will *block* if there is nothing available - if (totalBytes == 0) + if (pipeTotalBytesAvailable == 0) { return SLANG_OK; } - } + SLANG_RETURN_ON_FAIL(_updateState(::ReadFile(m_streamHandle, buffer, DWORD(length), &bytesRead, nullptr))); + } + else { - DWORD bytesRead = 0; - SLANG_RETURN_ON_FAIL(_updateState(ReadFile(m_streamHandle, buffer, DWORD(length), &bytesRead, nullptr))); + SLANG_RETURN_ON_FAIL(_updateState(::ReadFile(m_streamHandle, buffer, DWORD(length), &bytesRead, nullptr))); - outReadBytes = size_t(bytesRead); + // If it's not a pipe, and there is nothing left, then we are done. + if (length > 0 && bytesRead == 0) + { + close(); + } } + outReadBytes = size_t(bytesRead); return SLANG_OK; } @@ -223,9 +240,23 @@ SlangResult WinPipeStream::write(const void* buffer, size_t length) } DWORD numWritten = 0; - BOOL writeResult = WriteFile(m_streamHandle, buffer, DWORD(length), &numWritten, nullptr); + BOOL writeResult = ::WriteFile(m_streamHandle, buffer, DWORD(length), &numWritten, nullptr); + + if (!writeResult) + { + auto err = ::GetLastError(); + + if (err == ERROR_BROKEN_PIPE) + { + close(); + return SLANG_FAIL; + } + + SLANG_UNUSED(err); + return SLANG_FAIL; + } - if (!writeResult || numWritten != length) + if (numWritten != length) { return SLANG_FAIL; } @@ -251,8 +282,7 @@ SlangResult WinPipeStream::flush() } // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-flushfilebuffers - - if (!FlushFileBuffers(m_streamHandle)) + if (!::FlushFileBuffers(m_streamHandle)) { auto err = GetLastError(); SLANG_UNUSED(err); @@ -327,8 +357,17 @@ bool WinProcess::isTerminated() { case StreamType::StdIn: { - const HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE); - out = new WinPipeStream(stdinHandle, FileAccess::Read, false); + out = new WinPipeStream(GetStdHandle(STD_INPUT_HANDLE), FileAccess::Read, false); + return SLANG_OK; + } + case StreamType::StdOut: + { + out = new WinPipeStream(GetStdHandle(STD_OUTPUT_HANDLE), FileAccess::Write, false); + return SLANG_OK; + } + case StreamType::ErrorOut: + { + out = new WinPipeStream(GetStdHandle(STD_ERROR_HANDLE), FileAccess::Write, false); return SLANG_OK; } } |
