Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:11

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_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 /// A posix fork launcher that ignores errors after `fork`.
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 //BOOST_PROCESS_V2_POSIX_FORK_AND_FORGET_LAUNCHER_HPP