diff options
Diffstat (limited to 'Source/CTest/cmProcess.h')
-rw-r--r-- | Source/CTest/cmProcess.h | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h new file mode 100644 index 0000000..a44aeb0 --- /dev/null +++ b/Source/CTest/cmProcess.h @@ -0,0 +1,133 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <chrono> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include <cm3p/uv.h> +#include <stddef.h> +#include <stdint.h> + +#include "cmDuration.h" +#include "cmProcessOutput.h" +#include "cmUVHandlePtr.h" + +class cmCTestRunTest; + +/** \class cmProcess + * \brief run a process with c++ + * + * cmProcess wraps the kwsys process stuff in a c++ class. + */ +class cmProcess +{ +public: + explicit cmProcess(std::unique_ptr<cmCTestRunTest> runner); + ~cmProcess(); + void SetCommand(std::string const& command); + void SetCommandArguments(std::vector<std::string> const& arg); + void SetWorkingDirectory(std::string const& dir); + void SetTimeout(cmDuration t) { this->Timeout = t; } + void ChangeTimeout(cmDuration t); + void ResetStartTime(); + // Return true if the process starts + bool StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity); + + enum class State + { + Starting, + Error, + Exception, + Executing, + Exited, + Expired, + Killed, + Disowned + }; + + State GetProcessStatus(); + int GetId() { return this->Id; } + void SetId(int id) { this->Id = id; } + int64_t GetExitValue() { return this->ExitValue; } + cmDuration GetTotalTime() { return this->TotalTime; } + + enum class Exception + { + None, + Fault, + Illegal, + Interrupt, + Numerical, + Other + }; + + Exception GetExitException() const; + std::string GetExitExceptionString() const; + + std::unique_ptr<cmCTestRunTest> GetRunner() + { + return std::move(this->Runner); + } + +private: + cmDuration Timeout; + std::chrono::steady_clock::time_point StartTime; + cmDuration TotalTime; + bool ReadHandleClosed = false; + bool ProcessHandleClosed = false; + + cm::uv_process_ptr Process; + cm::uv_pipe_ptr PipeReader; + cm::uv_timer_ptr Timer; + std::vector<char> Buf; + + std::unique_ptr<cmCTestRunTest> Runner; + cmProcessOutput Conv; + int Signal = 0; + cmProcess::State ProcessState = cmProcess::State::Starting; + + static void OnExitCB(uv_process_t* process, int64_t exit_status, + int term_signal); + static void OnTimeoutCB(uv_timer_t* timer); + static void OnReadCB(uv_stream_t* stream, ssize_t nread, + const uv_buf_t* buf); + static void OnAllocateCB(uv_handle_t* handle, size_t suggested_size, + uv_buf_t* buf); + + void OnExit(int64_t exit_status, int term_signal); + void OnTimeout(); + void OnRead(ssize_t nread, const uv_buf_t* buf); + void OnAllocate(size_t suggested_size, uv_buf_t* buf); + + void StartTimer(); + void Finish(); + + class Buffer : public std::vector<char> + { + // Half-open index range of partial line already scanned. + size_type First; + size_type Last; + + public: + Buffer() + : First(0) + , Last(0) + { + } + bool GetLine(std::string& line); + bool GetLast(std::string& line); + }; + Buffer Output; + std::string Command; + std::string WorkingDirectory; + std::vector<std::string> Arguments; + std::vector<const char*> ProcessArgs; + int Id; + int64_t ExitValue; +}; |