Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:25:10

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_PROCESS_V2_DETAIL_PROCESS_HANDLE_WINDOWS_HPP
0006 #define BOOST_PROCESS_V2_DETAIL_PROCESS_HANDLE_WINDOWS_HPP
0007 
0008 #include <boost/process/v2/detail/config.hpp>
0009 
0010 #include <boost/process/v2/exit_code.hpp>
0011 #include <boost/process/v2/pid.hpp>
0012 #include <boost/process/v2/detail/throw_error.hpp>
0013 
0014 #if defined(BOOST_PROCESS_V2_STANDALONE)
0015 #include <asio/any_io_executor.hpp>
0016 #include <asio/compose.hpp>
0017 #include <asio/windows/basic_object_handle.hpp>
0018 #else
0019 #include <boost/asio/any_io_executor.hpp>
0020 #include <boost/asio/compose.hpp>
0021 #include <boost/asio/windows/basic_object_handle.hpp>
0022 #endif
0023 
0024 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0025 
0026 namespace detail
0027 {
0028   
0029 BOOST_PROCESS_V2_DECL void get_exit_code_( void * handle, native_exit_code_type & exit_code, error_code & ec);
0030 BOOST_PROCESS_V2_DECL void * open_process_(pid_type pid);
0031 BOOST_PROCESS_V2_DECL void terminate_if_running_(void * handle);
0032 BOOST_PROCESS_V2_DECL bool check_handle_(void* handle, error_code & ec);
0033 BOOST_PROCESS_V2_DECL bool check_pid_(pid_type pid_, error_code & ec);
0034 BOOST_PROCESS_V2_DECL void interrupt_(pid_type pid_, error_code & ec);
0035 BOOST_PROCESS_V2_DECL void suspend_(void * handle, error_code & ec);
0036 BOOST_PROCESS_V2_DECL void resume_(void * handle, error_code & ec);
0037 BOOST_PROCESS_V2_DECL void terminate_(void * handle, error_code & ec, native_exit_code_type & exit_code);
0038 BOOST_PROCESS_V2_DECL void request_exit_(pid_type pid_, error_code & ec);
0039 BOOST_PROCESS_V2_DECL void check_running_(void* handle, error_code & ec, native_exit_code_type & exit_status);
0040 
0041 template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor>
0042 struct basic_process_handle_win
0043 {
0044     typedef BOOST_PROCESS_V2_ASIO_NAMESPACE::windows::basic_object_handle<Executor> handle_type;
0045     typedef typename handle_type::native_handle_type native_handle_type;
0046 
0047     typedef Executor executor_type;
0048 
0049     executor_type get_executor()
0050     { return handle_.get_executor(); }
0051 
0052     /// Rebinds the process_handle to another executor.
0053     template<typename Executor1>
0054     struct rebind_executor
0055     {
0056         /// The socket type when rebound to the specified executor.
0057         typedef basic_process_handle_win<Executor1> other;
0058     };
0059 
0060     template<typename ExecutionContext>
0061     basic_process_handle_win(ExecutionContext &context,
0062                          typename std::enable_if<
0063                                  std::is_convertible<ExecutionContext &,
0064                                          BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context &>::value
0065                          >::type = 0)
0066             : pid_(0), handle_(context)
0067     {
0068     }
0069 
0070     basic_process_handle_win(Executor executor)
0071             : pid_(0), handle_(executor)
0072     {
0073     }
0074 
0075     basic_process_handle_win(Executor executor, pid_type pid)
0076             : pid_(pid), handle_(executor, detail::open_process_(pid))
0077     {
0078     }
0079 
0080     basic_process_handle_win(Executor executor, pid_type pid, native_handle_type process_handle)
0081             : pid_(pid), handle_(executor, process_handle)
0082     {
0083     }
0084 
0085 
0086     template<typename Executor1>
0087     basic_process_handle_win(basic_process_handle_win<Executor1> && other)
0088             : pid_(other.pid_), handle_(std::move(other.handle_))
0089     {
0090       other.pid_ = static_cast<DWORD>(-1);
0091     }
0092 
0093     basic_process_handle_win(basic_process_handle_win && other)
0094         :  pid_(other.pid_), handle_(std::move(other.handle_))
0095     {
0096       other.pid_ = static_cast<DWORD>(-1);
0097     }
0098 
0099     basic_process_handle_win& operator=(basic_process_handle_win && other)
0100     {
0101         pid_ = other.pid_;
0102         handle_ = std::move(other.handle_);
0103         other.pid_ = static_cast<DWORD>(-1);
0104         return *this;
0105     }
0106 
0107     template<typename Executor1>
0108     basic_process_handle_win& operator=(basic_process_handle_win<Executor1> && other)
0109     {
0110         pid_ = other.pid_;
0111         handle_ = std::move(other.handle_);
0112         other.pid_ = static_cast<DWORD>(-1);
0113         return *this;
0114     }
0115 
0116     ~basic_process_handle_win()
0117     {
0118         if (handle_.is_open())
0119         {
0120             error_code ec;
0121             handle_.close(ec);
0122         }
0123     }
0124 
0125     native_handle_type native_handle()
0126     { return handle_.native_handle(); }
0127 
0128     pid_type id() const
0129     { return pid_; }
0130 
0131     void terminate_if_running(error_code &)
0132     {
0133         detail::terminate_if_running_(handle_.native_handle());
0134     }
0135 
0136     void terminate_if_running()
0137     {
0138         detail::terminate_if_running_(handle_.native_handle());
0139     }
0140 
0141     void wait(native_exit_code_type &exit_status, error_code &ec)
0142     {
0143         if (!detail::check_handle_(handle_.native_handle(), ec))
0144             return;
0145 
0146         handle_.wait(ec);
0147         if (!ec)
0148             detail::get_exit_code_(handle_.native_handle(), exit_status, ec);
0149     }
0150 
0151 
0152     void wait(native_exit_code_type &exit_status)
0153     {
0154         error_code ec;
0155         wait(exit_status, ec);
0156         if (ec)
0157             detail::throw_error(ec, "wait(pid)");
0158     }
0159 
0160     void interrupt(error_code &ec)
0161     {
0162         if (!detail::check_pid_(pid_, ec))
0163             return;
0164 
0165         detail::interrupt_(pid_, ec);
0166     }
0167 
0168     void interrupt()
0169     {
0170         error_code ec;
0171         interrupt(ec);
0172         if (ec)
0173             detail::throw_error(ec, "interrupt");
0174     }
0175 
0176     void request_exit(error_code &ec)
0177     {
0178         if (!detail::check_pid_(pid_, ec))
0179             return;
0180         detail::request_exit_(pid_, ec);
0181     }
0182 
0183     void request_exit()
0184     {
0185         error_code ec;
0186         request_exit(ec);
0187         if (ec)
0188             detail::throw_error(ec, "request_exit");
0189     }
0190 
0191     void suspend(error_code &ec)
0192     {
0193         detail::suspend_(handle_.native_handle(), ec);
0194     }
0195 
0196     void suspend()
0197     {
0198         error_code ec;
0199         suspend(ec);
0200         if (ec)
0201             detail::throw_error(ec, "suspend");
0202     }
0203 
0204     void resume(error_code &ec)
0205     {
0206         detail::resume_(handle_.native_handle(), ec);
0207     }
0208 
0209     void resume()
0210     {
0211         error_code ec;
0212         resume(ec);
0213         if (ec)
0214             detail::throw_error(ec, "resume");
0215     }
0216 
0217     void terminate(native_exit_code_type &exit_status, error_code &ec)
0218     {
0219         if (!detail::check_handle_(handle_.native_handle(), ec))
0220             return;
0221 
0222         detail::terminate_(handle_.native_handle(), ec, exit_status);
0223         if (!ec)
0224             wait(exit_status, ec);
0225 
0226     }
0227 
0228     void terminate(native_exit_code_type &exit_status)
0229     {
0230         error_code ec;
0231         terminate(exit_status, ec);
0232         if (ec)
0233             detail::throw_error(ec, "terminate");
0234     }
0235 
0236     bool running(native_exit_code_type &exit_code, error_code & ec)
0237     {
0238         if (!detail::check_handle_(handle_.native_handle(), ec))
0239             return false;
0240 
0241         native_exit_code_type code;
0242         //single value, not needed in the winapi.
0243         detail::check_running_(handle_.native_handle(), ec, code);
0244         if (ec)
0245             return false;
0246 
0247         if (process_is_running(code))
0248             return true;
0249         else
0250             exit_code = code;
0251 
0252         return false;
0253     }
0254 
0255     bool running(native_exit_code_type &exit_code)
0256     {
0257         error_code ec;
0258         bool res = running(exit_code, ec);
0259         if (ec)
0260             detail::throw_error(ec, "is_running");
0261         return res;
0262     }
0263 
0264     bool is_open() const
0265     {
0266         return handle_.is_open();
0267     }
0268 
0269     template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
0270     WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
0271     BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, native_exit_code_type))
0272     async_wait(WaitHandler &&handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
0273     {
0274         return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
0275                 async_wait_op_{handle_}, handler, handle_
0276         );
0277     }
0278     template<typename>
0279     friend struct basic_process_handle_win;
0280   private:
0281     pid_type pid_;
0282     handle_type handle_;
0283 
0284     struct async_wait_op_
0285     {
0286         handle_type &handle;
0287 
0288         template<typename Self>
0289         void operator()(Self &&self)
0290         {
0291             handle.async_wait(std::move(self));
0292         }
0293 
0294         template<typename Self>
0295         void operator()(Self &&self, error_code ec)
0296         {
0297             native_exit_code_type exit_code{};
0298             if (!ec)
0299                 detail::get_exit_code_(handle.native_handle(), exit_code, ec);
0300             std::move(self).complete(ec, exit_code);
0301         }
0302     };
0303 };
0304 
0305 extern template struct basic_process_handle_win<>;
0306 
0307 }
0308 
0309 BOOST_PROCESS_V2_END_NAMESPACE
0310 
0311 
0312 #endif //BOOST_PROCESS_V2_DETAIL_PROCESS_HANDLE_WINDOWS_HPP