From 8a9e518371df03b3f382e0fe869da83751fdda0b Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 10 Nov 2021 17:33:22 -0500 Subject: 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. --- source/core/slang-process-util.h | 79 +++++----------------------------------- 1 file changed, 10 insertions(+), 69 deletions(-) (limited to 'source/core/slang-process-util.h') diff --git a/source/core/slang-process-util.h b/source/core/slang-process-util.h index af524940c..14ca208f8 100644 --- a/source/core/slang-process-util.h +++ b/source/core/slang-process-util.h @@ -2,52 +2,14 @@ #ifndef SLANG_PROCESS_UTIL_H #define SLANG_PROCESS_UTIL_H -#include "slang-string.h" -#include "slang-list.h" - -#include "slang-string-escape-util.h" +#include "slang-process.h" namespace Slang { -struct CommandLine -{ - enum class ExecutableType - { - Unknown, ///< The executable is not specified - Path, ///< The executable is set as a path - Filename, ///< The executable is set as a filename - }; - - /// Add args - assumed unescaped - void addArg(const String& in) { m_args.add(in); } - void addArgs(const String* args, Int argsCount) { for (Int i = 0; i < argsCount; ++i) addArg(args[i]); } - - /// Find the index of an arg which is exact match for slice - SLANG_INLINE Index findArgIndex(const UnownedStringSlice& slice) const { return m_args.indexOf(slice); } - - /// Set the executable path - void setExecutablePath(const String& path) { m_executableType = ExecutableType::Path; m_executable = path; } - void setExecutableFilename(const String& filename) { m_executableType = ExecutableType::Filename; m_executable = filename; } - - /// For handling args where the switch is placed directly in front of the path - SLANG_INLINE void addPrefixPathArg(const char* prefix, const String& path, const char* pathPostfix = nullptr); - - /// Get the total number of args - SLANG_FORCE_INLINE Index getArgCount() const { return m_args.getCount(); } - - /// Reset to the initial state - void reset() { *this = CommandLine(); } - - /// Ctor - CommandLine():m_executableType(ExecutableType::Unknown) {} - - ExecutableType m_executableType; ///< How the executable is specified - String m_executable; ///< Executable to run. Note that the executable is never escaped. - List m_args; ///< The arguments (Stored *unescaped*) -}; - struct ExecuteResult { + typedef int ResultCode; + void init() { resultCode = 0; @@ -55,45 +17,24 @@ struct ExecuteResult standardError = String(); } - typedef int ResultCode; ResultCode resultCode; - Slang::String standardOutput; - Slang::String standardError; + String standardOutput; + String standardError; }; struct ProcessUtil { - /// The quoting style used for the command line on this target. Currently just uses Space, - /// but in future may take into account platform sec - static StringEscapeHandler* getEscapeHandler(); - - /// Get the suffix used on this platform - static UnownedStringSlice getExecutableSuffix(); - - /// Output how the command line is executed on the target (with escaping and the such like) - static String getCommandLineString(const CommandLine& commandLine); - /// Execute the command line static SlangResult execute(const CommandLine& commandLine, ExecuteResult& outExecuteResult); - static uint64_t getClockFrequency(); + /// Read from read from streams until process terminates. + /// Passing nullptr for a stream, will just discard what's in the stream + static SlangResult readUntilTermination(Process* process, List* outStdOut, List* stdError); - static uint64_t getClockTick(); + /// Read streams from process. + static SlangResult readUntilTermination(Process* process, ExecuteResult& outExecuteResult); }; -// ----------------------------------------------------------------------- -SLANG_INLINE void CommandLine::addPrefixPathArg(const char* prefix, const String& path, const char* pathPostfix) -{ - StringBuilder builder; - builder << prefix << path; - if (pathPostfix) - { - // Work out the path with the postfix - builder << pathPostfix; - } - addArg(builder.ProduceString()); -} - } #endif // SLANG_PROCESS_UTIL_H -- cgit v1.2.3