Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:58:05

0001 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
0002 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
0003 // Copyright (c) 2009 Boris Schaeling
0004 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
0005 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
0006 // Copyright (c) 2016 Klemens D. Morgenstern
0007 //
0008 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0009 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 /**
0012  * \file boost/process/system.hpp
0013  *
0014  * Defines a system function.
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, /*needs ios*/
0052         std::true_type, /*has io_context*/
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,  /*needs ios */
0080         std::false_type, /*has io_context*/
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, /*needs ios*/
0098         std::true_type, /*has io_context*/
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, /*has async */
0111         std::false_type, /*has io_context*/
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 /** Launches a process and waits for its exit.
0128 It works as std::system, though it allows
0129 all the properties boost.process provides. It will execute the process and wait for it's exit; then return the exit_code.
0130 
0131 \code{.cpp}
0132 int ret = system("ls");
0133 \endcode
0134 
0135 \attention Using this function with synchronous pipes leads to many potential deadlocks.
0136 
0137 When using this function with an asynchronous properties and NOT passing an io_context object,
0138 the system function will create one and run it. When the io_context is passed to the function,
0139 the system function will check if it is active, and call the io_context::run function if not.
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