summaryrefslogtreecommitdiffstats
path: root/Source/CTest/cmProcess.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmProcess.h')
-rw-r--r--Source/CTest/cmProcess.h133
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;
+};