| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #pragma once | |
| #include "cmConfigure.h" // IWYU pragma: keep | |
| #include <chrono> | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include <cm/optional> | |
| #include <cm3p/uv.h> | |
| #include <sys/types.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 command); | |
| void SetCommandArguments(std::vector<std::string> arg); | |
| void SetEnvironment(std::vector<std::string> env); | |
| void SetWorkingDirectory(std::string dir); | |
| void SetStopTimeout(cmDuration t) { this->StopTimeout = t; } | |
| 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 TimeoutReason | |
| { | |
| Normal, | |
| StopTime, | |
| }; | |
| TimeoutReason GetTimeoutReason() const { return this->TimeoutReason_; } | |
| struct ComputedTimeout | |
| { | |
| TimeoutReason Reason; | |
| cmDuration Duration; | |
| }; | |
| cm::optional<ComputedTimeout> GetComputedTimeout() const; | |
| enum class State | |
| { | |
| Starting, | |
| Error, | |
| Exception, | |
| Executing, | |
| Exited, | |
| Expired, | |
| Killed, | |
| Disowned | |
| }; | |
| State GetProcessStatus(); | |
| int GetId() const { return this->Id; } | |
| void SetId(int id) { this->Id = id; } | |
| int64_t GetExitValue() const { return this->ExitValue; } | |
| cmDuration GetTotalTime() { return this->TotalTime; } | |
| std::chrono::steady_clock::time_point GetStartTime() | |
| { | |
| return this->StartTime; | |
| } | |
| std::chrono::system_clock::time_point GetSystemStartTime() | |
| { | |
| return this->SystemStartTime; | |
| } | |
| 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); | |
| } | |
| enum class Termination | |
| { | |
| Normal, | |
| Custom, | |
| Forced, | |
| }; | |
| Termination GetTerminationStyle() const { return this->TerminationStyle; } | |
| private: | |
| cm::optional<cmDuration> StopTimeout; | |
| cm::optional<cmDuration> Timeout; | |
| TimeoutReason TimeoutReason_ = TimeoutReason::Normal; | |
| std::chrono::steady_clock::time_point StartTime; | |
| std::chrono::system_clock::time_point SystemStartTime; | |
| 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, | |
| uv_buf_t const* 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, uv_buf_t const* 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 = 0; | |
| size_type Last = 0; | |
| public: | |
| Buffer() = default; | |
| 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<char const*> ProcessArgs; | |
| std::vector<std::string> Environment; | |
| std::vector<char const*> Env; | |
| int Id; | |
| int64_t ExitValue; | |
| Termination TerminationStyle = Termination::Normal; | |
| }; |