File indexing completed on 2025-01-18 09:50:11
0001
0002
0003
0004
0005 #ifndef BOOST_PROCESS_V2_POSIX_FORK_AND_FORGET_LAUNCHER_HPP
0006 #define BOOST_PROCESS_V2_POSIX_FORK_AND_FORGET_LAUNCHER_HPP
0007
0008 #include <boost/process/v2/posix/default_launcher.hpp>
0009
0010 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0011
0012 namespace posix
0013 {
0014
0015
0016 struct fork_and_forget_launcher : default_launcher
0017 {
0018 fork_and_forget_launcher() = default;
0019
0020 template<typename ExecutionContext, typename Args, typename ... Inits>
0021 auto operator()(ExecutionContext & context,
0022 const typename std::enable_if<is_convertible<
0023 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0024 filesystem::path >::type & executable,
0025 Args && args,
0026 Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
0027 {
0028 error_code ec;
0029 auto proc = (*this)(context, ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
0030
0031 if (ec)
0032 v2::detail::throw_error(ec, "fork_and_forget_launcher");
0033
0034 return proc;
0035 }
0036
0037
0038 template<typename ExecutionContext, typename Args, typename ... Inits>
0039 auto operator()(ExecutionContext & context,
0040 error_code & ec,
0041 const typename std::enable_if<is_convertible<
0042 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0043 filesystem::path >::type & executable,
0044 Args && args,
0045 Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
0046 {
0047 return (*this)(context.get_executor(), executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
0048 }
0049
0050 template<typename Executor, typename Args, typename ... Inits>
0051 auto operator()(Executor exec,
0052 const typename std::enable_if<
0053 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0054 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0055 filesystem::path >::type & executable,
0056 Args && args,
0057 Inits && ... inits ) -> basic_process<Executor>
0058 {
0059 error_code ec;
0060 auto proc = (*this)(std::move(exec), ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
0061
0062 if (ec)
0063 v2::detail::throw_error(ec, "fork_and_forget_launcher");
0064
0065 return proc;
0066 }
0067
0068 template<typename Executor, typename Args, typename ... Inits>
0069 auto operator()(Executor exec,
0070 error_code & ec,
0071 const typename std::enable_if<
0072 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0073 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0074 filesystem::path >::type & executable,
0075 Args && args,
0076 Inits && ... inits ) -> basic_process<Executor>
0077 {
0078 auto argv = this->build_argv_(executable, std::forward<Args>(args));
0079 {
0080 ec = detail::on_setup(*this, executable, argv, inits ...);
0081 if (ec)
0082 {
0083 detail::on_error(*this, executable, argv, ec, inits...);
0084 return basic_process<Executor>(exec);
0085 }
0086
0087 auto & ctx = BOOST_PROCESS_V2_ASIO_NAMESPACE::query(
0088 exec, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::context);
0089 ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_prepare);
0090 pid = ::fork();
0091 if (pid == -1)
0092 {
0093 ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent);
0094 detail::on_fork_error(*this, executable, argv, ec, inits...);
0095 detail::on_error(*this, executable, argv, ec, inits...);
0096
0097 BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category())
0098 return basic_process<Executor>{exec};
0099 }
0100 else if (pid == 0)
0101 {
0102 ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_child);
0103
0104 ec = detail::on_exec_setup(*this, executable, argv, inits...);
0105 if (!ec)
0106 close_all_fds(ec);
0107 if (!ec)
0108 ::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env));
0109
0110 BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category())
0111 detail::on_exec_error(*this, executable, argv, ec, inits...);
0112 ::exit(EXIT_FAILURE);
0113 return basic_process<Executor>{exec};
0114 }
0115 ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent);
0116 if (ec)
0117 {
0118 detail::on_error(*this, executable, argv, ec, inits...);
0119 return basic_process<Executor>{exec};
0120 }
0121 }
0122 basic_process<Executor> proc(exec, pid);
0123 detail::on_success(*this, executable, argv, ec, inits...);
0124 return proc;
0125
0126 }
0127 };
0128
0129
0130 }
0131
0132 BOOST_PROCESS_V2_END_NAMESPACE
0133
0134
0135 #endif