process_handle.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (c) 2022 Klemens D. Morgenstern
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_PROCESS_V2_PROCESS_HANDLE_HPP
  6. #define BOOST_PROCESS_V2_PROCESS_HANDLE_HPP
  7. #include <boost/process/v2/detail/config.hpp>
  8. #if defined(BOOST_PROCESS_V2_WINDOWS)
  9. #include <boost/process/v2/detail/process_handle_windows.hpp>
  10. #else
  11. #if defined(BOOST_PROCESS_V2_PIDFD_OPEN)
  12. #include <boost/process/v2/detail/process_handle_fd.hpp>
  13. #elif defined(BOOST_PROCESS_V2_PDFORK)
  14. #include <boost/process/v2/detail/process_handle_fd_or_signal.hpp>
  15. #else
  16. // with asio support we could use EVFILT_PROC:NOTE_EXIT as well.
  17. #include <boost/process/v2/detail/process_handle_signal.hpp>
  18. #endif
  19. #endif
  20. BOOST_PROCESS_V2_BEGIN_NAMESPACE
  21. #if defined(GENERATING_DOCUMENTATION)
  22. /** A process handle is an unmanaged version of a process.
  23. * This means it does not terminate the proces on destruction and
  24. * will not keep track of the exit-code.
  25. *
  26. * Note that the exit code might be discovered early, during a call to `running`.
  27. * Thus it can only be discovered that process has exited already.
  28. */
  29. template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor>
  30. struct basic_process_handle
  31. {
  32. /// The native handle of the process.
  33. /** This might be undefined on posix systems that only support signals */
  34. using native_handle_type = implementation_defined;
  35. /// The executor_type of the process_handle
  36. using executor_type = Executor;
  37. /// Getter for the executor
  38. executor_type get_executor();
  39. /// Rebinds the process_handle to another executor.
  40. template<typename Executor1>
  41. struct rebind_executor
  42. {
  43. /// The socket type when rebound to the specified executor.
  44. typedef basic_process_handle<Executor1> other;
  45. };
  46. /// Construct a basic_process_handle from an execution_context.
  47. /**
  48. * @tparam ExecutionContext The context must fulfill the asio::execution_context requirements
  49. */
  50. template<typename ExecutionContext>
  51. basic_process_handle(ExecutionContext &context);
  52. /// Construct an empty process_handle from an executor.
  53. basic_process_handle(executor_type executor);
  54. /// Construct an empty process_handle from an executor and bind it to a pid.
  55. /** On NON-linux posix systems this call is not able to obtain a file-descriptor and will thus
  56. * rely on signals.
  57. */
  58. basic_process_handle(executor_type executor, pid_type pid);
  59. /// Construct an empty process_handle from an executor and bind it to a pid and the native-handle
  60. /** On some non-linux posix systems this overload is not present.
  61. */
  62. basic_process_handle(executor_type executor, pid_type pid, native_handle_type process_handle);
  63. /// Move construct and rebind the executor.
  64. template<typename Executor1>
  65. basic_process_handle(basic_process_handle<Executor1> &&handle);
  66. /// Get the id of the process
  67. pid_type id() const
  68. { return pid_; }
  69. /// Terminate the process if it's still running and ignore the result
  70. void terminate_if_running(error_code &);
  71. /// Throwing @overload void terminate_if_running(error_code & ec;
  72. void terminate_if_running();
  73. /// wait for the process to exit and store the exit code in exit_status.
  74. void wait(native_exit_code_type &exit_status, error_code &ec);
  75. /// Throwing @overload wait(native_exit_code_type &exit_code, error_code & ec)
  76. void wait(native_exit_code_type &exit_status);
  77. /// Sends the process a signal to ask for an interrupt, which the process may interpret as a shutdown.
  78. /** Maybe be ignored by the subprocess. */
  79. void interrupt(error_code &ec);
  80. /// Throwing @overload void interrupt()
  81. void interrupt();
  82. /// Sends the process a signal to ask for a graceful shutdown. Maybe be ignored by the subprocess.
  83. void request_exit(error_code &ec);
  84. /// Throwing @overload void request_exit(error_code & ec)
  85. void request_exit()
  86. /// Unconditionally terminates the process and stores the exit code in exit_status.
  87. void terminate(native_exit_code_type &exit_status, error_code &ec);\
  88. /// Throwing @overload void terminate(native_exit_code_type &exit_code, error_code & ec)
  89. void terminate(native_exit_code_type &exit_status);/
  90. /// Checks if the current process is running.
  91. /**If it has already completed, it assigns the exit code to `exit_code`.
  92. */
  93. bool running(native_exit_code_type &exit_code, error_code &ec);
  94. /// Throwing @overload bool running(native_exit_code_type &exit_code, error_code & ec)
  95. bool running(native_exit_code_type &exit_code);
  96. /// Check if the process handle is referring to an existing process.
  97. bool is_open() const;
  98. /// Asynchronously wait for the process to exit and deliver the native exit-code in the completion handler.
  99. template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
  100. WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  101. BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, native_exit_code_type))
  102. async_wait(WaitHandler &&handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type));
  103. };
  104. #else
  105. #if defined(BOOST_PROCESS_V2_WINDOWS)
  106. template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor>
  107. using basic_process_handle = detail::basic_process_handle_win<Executor>;
  108. #else
  109. #if defined(BOOST_PROCESS_V2_PIDFD_OPEN)
  110. template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor>
  111. using basic_process_handle = detail::basic_process_handle_fd<Executor>;
  112. #elif defined(BOOST_PROCESS_V2_PDFORK)
  113. template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor>
  114. using basic_process_handle = detail::basic_process_handle_fd_or_signal<Executor>;
  115. #else
  116. template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor>
  117. using basic_process_handle = detail::basic_process_handle_signal<Executor>;
  118. #endif
  119. #endif
  120. /// Process handle with the default executor.
  121. using process_handle = basic_process_handle<>;
  122. #endif
  123. BOOST_PROCESS_V2_END_NAMESPACE
  124. #endif //BOOST_PROCESS_V2_PROCESS_HANDLE_HPP