diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-11-10 17:33:22 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-10 17:33:22 -0500 |
| commit | 8a9e518371df03b3f382e0fe869da83751fdda0b (patch) | |
| tree | 749f9c1c79acd375ec3ee97e45a10007dd6632fa /source/core/slang-process-util.cpp | |
| parent | 95e82acc0b32c81a9c6ac39708d18a423d8c7b1e (diff) | |
Interprocess communication via pipes (#2009)
* #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.
Diffstat (limited to 'source/core/slang-process-util.cpp')
| -rw-r--r-- | source/core/slang-process-util.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/source/core/slang-process-util.cpp b/source/core/slang-process-util.cpp new file mode 100644 index 000000000..b1466d150 --- /dev/null +++ b/source/core/slang-process-util.cpp @@ -0,0 +1,78 @@ +// slang-process-util.cpp + +#include "slang-process-util.h" + +#include "slang-string.h" +#include "slang-string-escape-util.h" +#include "slang-string-util.h" + +#include "../../slang-com-helper.h" + +namespace Slang { + +/* static */SlangResult ProcessUtil::execute(const CommandLine& commandLine, ExecuteResult& outExecuteResult) +{ + RefPtr<Process> process; + SLANG_RETURN_ON_FAIL(Process::create(commandLine, 0, process)); + SLANG_RETURN_ON_FAIL(readUntilTermination(process, outExecuteResult)); + return SLANG_OK; +} + +static Index _getCount(List<Byte>* buf) +{ + return buf ? buf->getCount() : 0; +} + +// We may want something more sophisticated here, if bytes is something other than ascii/utf8 +static String _getText(const ConstArrayView<Byte>& bytes) +{ + StringBuilder buf; + StringUtil::appendStandardLines(UnownedStringSlice((const char*)bytes.begin(), (const char*)bytes.end()), buf); + return buf.ProduceString(); +} + +/* static */SlangResult ProcessUtil::readUntilTermination(Process* process, ExecuteResult& outExecuteResult) +{ + List<Byte> stdOut; + List<Byte> stdError; + + SLANG_RETURN_ON_FAIL(readUntilTermination(process, &stdOut, &stdError)); + + // Get the return code + outExecuteResult.resultCode = ExecuteResult::ResultCode(process->getReturnValue()); + + outExecuteResult.standardOutput = _getText(stdOut.getArrayView()); + outExecuteResult.standardError = _getText(stdError.getArrayView()); + + return SLANG_OK; +} + +/* static */SlangResult ProcessUtil::readUntilTermination(Process* process, List<Byte>* outStdOut, List<Byte>* outStdError) +{ + Stream* stdOutStream = process->getStream(Process::StreamType::StdOut); + Stream* stdErrorStream = process->getStream(Process::StreamType::ErrorOut); + + while (!process->isTerminated()) + { + const auto preCount = _getCount(outStdOut) + _getCount(outStdError); + + SLANG_RETURN_ON_FAIL(StreamUtil::readOrDiscard(stdOutStream, 0, outStdOut)); + SLANG_RETURN_ON_FAIL(StreamUtil::readOrDiscard(stdErrorStream, 0, outStdError)); + + const auto postCount = _getCount(outStdOut) + _getCount(outStdError); + + // If nothing was read, we can yield + if (preCount == postCount) + { + Process::sleepCurrentThread(0); + } + } + + // Read anything remaining + SLANG_RETURN_ON_FAIL(StreamUtil::readOrDiscardAll(stdOutStream, 0, outStdOut)); + SLANG_RETURN_ON_FAIL(StreamUtil::readOrDiscardAll(stdErrorStream, 0, outStdError)); + + return SLANG_OK; +} + +} // namespace Slang |
