Imported Upstream version 3.17.1
[platform/upstream/cmake.git] / Source / CTest / cmProcess.h
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #ifndef cmProcess_h
4 #define cmProcess_h
5
6 #include "cmConfigure.h" // IWYU pragma: keep
7
8 #include <chrono>
9 #include <string>
10 #include <vector>
11
12 #include <stddef.h>
13 #include <stdint.h>
14
15 #include "cm_uv.h"
16
17 #include "cmDuration.h"
18 #include "cmProcessOutput.h"
19 #include "cmUVHandlePtr.h"
20
21 class cmCTestRunTest;
22
23 /** \class cmProcess
24  * \brief run a process with c++
25  *
26  * cmProcess wraps the kwsys process stuff in a c++ class.
27  */
28 class cmProcess
29 {
30 public:
31   explicit cmProcess(cmCTestRunTest& runner);
32   ~cmProcess();
33   void SetCommand(std::string const& command);
34   void SetCommandArguments(std::vector<std::string> const& arg);
35   void SetWorkingDirectory(std::string const& dir);
36   void SetTimeout(cmDuration t) { this->Timeout = t; }
37   void ChangeTimeout(cmDuration t);
38   void ResetStartTime();
39   // Return true if the process starts
40   bool StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity);
41
42   enum class State
43   {
44     Starting,
45     Error,
46     Exception,
47     Executing,
48     Exited,
49     Expired,
50     Killed,
51     Disowned
52   };
53
54   State GetProcessStatus();
55   int GetId() { return this->Id; }
56   void SetId(int id) { this->Id = id; }
57   int64_t GetExitValue() { return this->ExitValue; }
58   cmDuration GetTotalTime() { return this->TotalTime; }
59
60   enum class Exception
61   {
62     None,
63     Fault,
64     Illegal,
65     Interrupt,
66     Numerical,
67     Other
68   };
69
70   Exception GetExitException();
71   std::string GetExitExceptionString();
72
73 private:
74   cmDuration Timeout;
75   std::chrono::steady_clock::time_point StartTime;
76   cmDuration TotalTime;
77   bool ReadHandleClosed = false;
78   bool ProcessHandleClosed = false;
79
80   cm::uv_process_ptr Process;
81   cm::uv_pipe_ptr PipeReader;
82   cm::uv_timer_ptr Timer;
83   std::vector<char> Buf;
84
85   cmCTestRunTest& Runner;
86   cmProcessOutput Conv;
87   int Signal = 0;
88   cmProcess::State ProcessState = cmProcess::State::Starting;
89
90   static void OnExitCB(uv_process_t* process, int64_t exit_status,
91                        int term_signal);
92   static void OnTimeoutCB(uv_timer_t* timer);
93   static void OnReadCB(uv_stream_t* stream, ssize_t nread,
94                        const uv_buf_t* buf);
95   static void OnAllocateCB(uv_handle_t* handle, size_t suggested_size,
96                            uv_buf_t* buf);
97
98   void OnExit(int64_t exit_status, int term_signal);
99   void OnTimeout();
100   void OnRead(ssize_t nread, const uv_buf_t* buf);
101   void OnAllocate(size_t suggested_size, uv_buf_t* buf);
102
103   void StartTimer();
104   void Finish();
105
106   class Buffer : public std::vector<char>
107   {
108     // Half-open index range of partial line already scanned.
109     size_type First;
110     size_type Last;
111
112   public:
113     Buffer()
114       : First(0)
115       , Last(0)
116     {
117     }
118     bool GetLine(std::string& line);
119     bool GetLast(std::string& line);
120   };
121   Buffer Output;
122   std::string Command;
123   std::string WorkingDirectory;
124   std::vector<std::string> Arguments;
125   std::vector<const char*> ProcessArgs;
126   int Id;
127   int64_t ExitValue;
128 };
129
130 #endif