File indexing completed on 2025-09-17 08:48:47
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&, net::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&, net::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(), ec, 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 net::execution::is_executor<Executor>::value ||
0054 net::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 net::execution::is_executor<Executor>::value ||
0073 net::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 = net::query(
0088 exec, net::execution::context);
0089 #if !defined(BOOST_PROCESS_V2_DISABLE_NOTIFY_FORK)
0090 ctx.notify_fork(net::execution_context::fork_prepare);
0091 #endif
0092 pid = ::fork();
0093 if (pid == -1)
0094 {
0095 #if !defined(BOOST_PROCESS_V2_DISABLE_NOTIFY_FORK)
0096 ctx.notify_fork(net::execution_context::fork_parent);
0097 #endif
0098 detail::on_fork_error(*this, executable, argv, ec, inits...);
0099 detail::on_fork_error(*this, executable, argv, ec, inits...);
0100 detail::on_error(*this, executable, argv, ec, inits...);
0101
0102 BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
0103 return basic_process<Executor>{exec};
0104 }
0105 else if (pid == 0)
0106 {
0107 #if !defined(BOOST_PROCESS_V2_DISABLE_NOTIFY_FORK)
0108 ctx.notify_fork(net::execution_context::fork_child);
0109 #endif
0110 ec = detail::on_exec_setup(*this, executable, argv, inits...);
0111 if (!ec)
0112 close_all_fds(ec);
0113 if (!ec)
0114 ::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env));
0115
0116 BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
0117 detail::on_exec_error(*this, executable, argv, ec, inits...);
0118 ::exit(EXIT_FAILURE);
0119 return basic_process<Executor>{exec};
0120 }
0121 #if !defined(BOOST_PROCESS_V2_DISABLE_NOTIFY_FORK)
0122 ctx.notify_fork(net::execution_context::fork_parent);
0123 #endif
0124 if (ec)
0125 {
0126 detail::on_error(*this, executable, argv, ec, inits...);
0127 do { ::waitpid(pid, nullptr, 0); } while (errno == EINTR);
0128 return basic_process<Executor>{exec};
0129 }
0130 }
0131 basic_process<Executor> proc(exec, pid);
0132 detail::on_success(*this, executable, argv, ec, inits...);
0133 return proc;
0134
0135 }
0136 };
0137
0138
0139 }
0140
0141 BOOST_PROCESS_V2_END_NAMESPACE
0142
0143
0144 #endif