File indexing completed on 2025-01-30 09:58:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_PROCESS_SYSTEM_HPP
0018 #define BOOST_PROCESS_SYSTEM_HPP
0019
0020 #include <boost/process/detail/config.hpp>
0021 #include <boost/process/detail/on_exit.hpp>
0022 #include <boost/process/child.hpp>
0023 #include <boost/process/detail/async_handler.hpp>
0024 #include <boost/process/detail/execute_impl.hpp>
0025 #include <boost/asio/post.hpp>
0026 #include <type_traits>
0027 #include <mutex>
0028 #include <condition_variable>
0029
0030 #if defined(BOOST_POSIX_API)
0031 #include <boost/process/posix.hpp>
0032 #endif
0033
0034 namespace boost {
0035
0036 namespace process {
0037
0038 namespace detail
0039 {
0040
0041 struct system_impl_success_check : handler
0042 {
0043 bool succeeded = false;
0044
0045 template<typename Exec>
0046 void on_success(Exec &) { succeeded = true; }
0047 };
0048
0049 template<typename IoService, typename ...Args>
0050 inline int system_impl(
0051 std::true_type,
0052 std::true_type,
0053 Args && ...args)
0054 {
0055 IoService & ios = ::boost::process::detail::get_io_context_var(args...);
0056
0057 system_impl_success_check check;
0058
0059 std::atomic_bool exited{false};
0060
0061 child c(std::forward<Args>(args)...,
0062 check,
0063 ::boost::process::on_exit(
0064 [&](int, const std::error_code&)
0065 {
0066 boost::asio::post(ios.get_executor(), [&]{exited.store(true);});
0067 }));
0068 if (!c.valid() || !check.succeeded)
0069 return -1;
0070
0071 while (!exited.load())
0072 ios.poll();
0073
0074 return c.exit_code();
0075 }
0076
0077 template<typename IoService, typename ...Args>
0078 inline int system_impl(
0079 std::true_type,
0080 std::false_type,
0081 Args && ...args)
0082 {
0083 IoService ios;
0084 child c(ios, std::forward<Args>(args)...);
0085 if (!c.valid())
0086 return -1;
0087
0088 ios.run();
0089 if (c.running())
0090 c.wait();
0091 return c.exit_code();
0092 }
0093
0094
0095 template<typename IoService, typename ...Args>
0096 inline int system_impl(
0097 std::false_type,
0098 std::true_type,
0099 Args && ...args)
0100 {
0101 child c(std::forward<Args>(args)...);
0102 if (!c.valid())
0103 return -1;
0104 c.wait();
0105 return c.exit_code();
0106 }
0107
0108 template<typename IoService, typename ...Args>
0109 inline int system_impl(
0110 std::false_type,
0111 std::false_type,
0112 Args && ...args)
0113 {
0114 child c(std::forward<Args>(args)...
0115 #if defined(BOOST_POSIX_API)
0116 ,::boost::process::posix::sig.dfl()
0117 #endif
0118 );
0119 if (!c.valid())
0120 return -1;
0121 c.wait();
0122 return c.exit_code();
0123 }
0124
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 template<typename ...Args>
0143 inline int system(Args && ...args)
0144 {
0145 typedef typename ::boost::process::detail::needs_io_context<Args...>::type
0146 need_ios;
0147 typedef typename ::boost::process::detail::has_io_context<Args...>::type
0148 has_ios;
0149 return ::boost::process::detail::system_impl<boost::asio::io_context>(
0150 need_ios(), has_ios(),
0151 std::forward<Args>(args)...);
0152 }
0153
0154
0155 }}
0156 #endif
0157