cmProcess.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. #include "cmConfigure.h" // IWYU pragma: keep
  6. #include "cmUVHandlePtr.h"
  7. #include "cm_uv.h"
  8. #include <chrono>
  9. #include <stddef.h>
  10. #include <string>
  11. #include <sys/types.h>
  12. #include <vector>
  13. class cmCTestRunTest;
  14. /** \class cmProcess
  15. * \brief run a process with c++
  16. *
  17. * cmProcess wraps the kwsys process stuff in a c++ class.
  18. */
  19. class cmProcess
  20. {
  21. public:
  22. explicit cmProcess(cmCTestRunTest& runner);
  23. ~cmProcess();
  24. const char* GetCommand() { return this->Command.c_str(); }
  25. void SetCommand(const char* command);
  26. void SetCommandArguments(std::vector<std::string> const& arg);
  27. void SetWorkingDirectory(const char* dir) { this->WorkingDirectory = dir; }
  28. void SetTimeout(std::chrono::duration<double> t) { this->Timeout = t; }
  29. void ChangeTimeout(std::chrono::duration<double> t);
  30. void ResetStartTime();
  31. // Return true if the process starts
  32. bool StartProcess(uv_loop_t& loop);
  33. enum class State
  34. {
  35. Starting,
  36. Error,
  37. Exception,
  38. Executing,
  39. Exited,
  40. Expired,
  41. Killed,
  42. Disowned
  43. };
  44. State GetProcessStatus();
  45. int GetId() { return this->Id; }
  46. void SetId(int id) { this->Id = id; }
  47. int GetExitValue() { return this->ExitValue; }
  48. std::chrono::duration<double> GetTotalTime() { return this->TotalTime; }
  49. enum class Exception
  50. {
  51. None,
  52. Fault,
  53. Illegal,
  54. Interrupt,
  55. Numerical,
  56. Other
  57. };
  58. Exception GetExitException();
  59. std::string GetExitExceptionString();
  60. private:
  61. std::chrono::duration<double> Timeout;
  62. std::chrono::steady_clock::time_point StartTime;
  63. std::chrono::duration<double> TotalTime;
  64. bool ReadHandleClosed = false;
  65. bool ProcessHandleClosed = false;
  66. cm::uv_process_ptr Process;
  67. cm::uv_pipe_ptr PipeReader;
  68. cm::uv_timer_ptr Timer;
  69. std::vector<char> Buf;
  70. cmCTestRunTest& Runner;
  71. int Signal = 0;
  72. cmProcess::State ProcessState = cmProcess::State::Starting;
  73. static void OnExitCB(uv_process_t* process, int64_t exit_status,
  74. int term_signal);
  75. static void OnTimeoutCB(uv_timer_t* timer);
  76. static void OnReadCB(uv_stream_t* stream, ssize_t nread,
  77. const uv_buf_t* buf);
  78. static void OnAllocateCB(uv_handle_t* handle, size_t suggested_size,
  79. uv_buf_t* buf);
  80. void OnExit(int64_t exit_status, int term_signal);
  81. void OnTimeout();
  82. void OnRead(ssize_t nread, const uv_buf_t* buf);
  83. void OnAllocate(size_t suggested_size, uv_buf_t* buf);
  84. void StartTimer();
  85. class Buffer : public std::vector<char>
  86. {
  87. // Half-open index range of partial line already scanned.
  88. size_type First;
  89. size_type Last;
  90. public:
  91. Buffer()
  92. : First(0)
  93. , Last(0)
  94. {
  95. }
  96. bool GetLine(std::string& line);
  97. bool GetLast(std::string& line);
  98. };
  99. Buffer Output;
  100. std::string Command;
  101. std::string WorkingDirectory;
  102. std::vector<std::string> Arguments;
  103. std::vector<const char*> ProcessArgs;
  104. int Id;
  105. int ExitValue;
  106. };
  107. #endif