diff options
Diffstat (limited to 'boost/process/detail/posix')
-rw-r--r-- | boost/process/detail/posix/async_in.hpp | 4 | ||||
-rw-r--r-- | boost/process/detail/posix/async_out.hpp | 3 | ||||
-rw-r--r-- | boost/process/detail/posix/async_pipe.hpp | 12 | ||||
-rw-r--r-- | boost/process/detail/posix/basic_cmd.hpp | 14 | ||||
-rw-r--r-- | boost/process/detail/posix/group_handle.hpp | 23 | ||||
-rw-r--r-- | boost/process/detail/posix/io_context_ref.hpp | 9 | ||||
-rw-r--r-- | boost/process/detail/posix/is_running.hpp | 57 | ||||
-rw-r--r-- | boost/process/detail/posix/search_path.hpp | 4 | ||||
-rw-r--r-- | boost/process/detail/posix/sigchld_service.hpp | 31 | ||||
-rw-r--r-- | boost/process/detail/posix/terminate.hpp | 16 | ||||
-rw-r--r-- | boost/process/detail/posix/wait_for_exit.hpp | 162 | ||||
-rw-r--r-- | boost/process/detail/posix/wait_group.hpp | 164 |
12 files changed, 163 insertions, 336 deletions
diff --git a/boost/process/detail/posix/async_in.hpp b/boost/process/detail/posix/async_in.hpp index 1c1e2f40fb..7e9fb94ebd 100644 --- a/boost/process/detail/posix/async_in.hpp +++ b/boost/process/detail/posix/async_in.hpp @@ -85,7 +85,9 @@ struct async_in_buffer : ::boost::process::detail::posix::handler_base_ext, if (::dup2(pipe->native_source(), STDIN_FILENO) == -1) exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); - ::close(pipe->native_source()); + if (pipe->native_source() != STDIN_FILENO) + ::close(pipe->native_source()); + ::close(pipe->native_sink()); } }; diff --git a/boost/process/detail/posix/async_out.hpp b/boost/process/detail/posix/async_out.hpp index c448490e67..06fd92e1b1 100644 --- a/boost/process/detail/posix/async_out.hpp +++ b/boost/process/detail/posix/async_out.hpp @@ -89,6 +89,8 @@ struct async_out_buffer : ::boost::process::detail::posix::handler_base_ext, exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); ::close(pipe->native_sink()); + ::close(pipe->native_source()); + } }; @@ -161,6 +163,7 @@ struct async_out_future : ::boost::process::detail::posix::handler_base_ext, exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); ::close(pipe->native_sink()); + ::close(pipe->native_source()); } }; diff --git a/boost/process/detail/posix/async_pipe.hpp b/boost/process/detail/posix/async_pipe.hpp index 8f138bdfa3..f27ecfe392 100644 --- a/boost/process/detail/posix/async_pipe.hpp +++ b/boost/process/detail/posix/async_pipe.hpp @@ -125,6 +125,18 @@ public: return _sink.write_some(buffers); } + template<typename MutableBufferSequence> + std::size_t read_some(const MutableBufferSequence & buffers, boost::system::error_code & ec) noexcept + { + return _source.read_some(buffers, ec); + } + template<typename MutableBufferSequence> + std::size_t write_some(const MutableBufferSequence & buffers, boost::system::error_code & ec) noexcept + { + return _sink.write_some(buffers, ec); + } + + native_handle_type native_source() const {return const_cast<boost::asio::posix::stream_descriptor&>(_source).native_handle();} native_handle_type native_sink () const {return const_cast<boost::asio::posix::stream_descriptor&>(_sink ).native_handle();} diff --git a/boost/process/detail/posix/basic_cmd.hpp b/boost/process/detail/posix/basic_cmd.hpp index eefcc5c53f..326e30dc0b 100644 --- a/boost/process/detail/posix/basic_cmd.hpp +++ b/boost/process/detail/posix/basic_cmd.hpp @@ -118,12 +118,8 @@ struct exe_cmd_init<char> : boost::process::detail::api::handler_base_ext else exec.exe = &exe.front(); - - if (!args.empty()) - { - cmd_impl = make_cmd(); - exec.cmd_line = cmd_impl.data(); - } + cmd_impl = make_cmd(); + exec.cmd_line = cmd_impl.data(); } static exe_cmd_init exe_args(std::string && exe, std::vector<std::string> && args) {return exe_cmd_init(std::move(exe), std::move(args));} static exe_cmd_init cmd (std::string && cmd) @@ -163,8 +159,10 @@ std::vector<char*> exe_cmd_init<char>::make_cmd() if (!exe.empty()) vec.push_back(&exe.front()); - for (auto & v : args) - vec.push_back(&v.front()); + if (!args.empty()) { + for (auto & v : args) + vec.push_back(&v.front()); + } vec.push_back(nullptr); diff --git a/boost/process/detail/posix/group_handle.hpp b/boost/process/detail/posix/group_handle.hpp index 856b36a6b0..8df4d39435 100644 --- a/boost/process/detail/posix/group_handle.hpp +++ b/boost/process/detail/posix/group_handle.hpp @@ -6,14 +6,13 @@ #ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_ #define BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_ +#include <boost/process/detail/config.hpp> #include <boost/process/detail/posix/child_handle.hpp> #include <system_error> #include <unistd.h> namespace boost { namespace process { namespace detail { namespace posix { - - struct group_handle { pid_t grp = -1; @@ -26,7 +25,6 @@ struct group_handle { } - group_handle() = default; ~group_handle() = default; @@ -38,7 +36,6 @@ struct group_handle group_handle &operator=(const group_handle & c) = delete; group_handle &operator=(group_handle && c) { - grp = c.grp; c.grp = -1; return *this; @@ -62,23 +59,14 @@ struct group_handle bool has(handle_t proc, std::error_code & ec) noexcept { return ::getpgid(proc) == grp; - } bool valid() const { return grp != -1; } - }; -inline void terminate(group_handle &p) -{ - if (::killpg(p.grp, SIGKILL) == -1) - boost::process::detail::throw_last_error("killpg(2) failed"); - p.grp = -1; -} - inline void terminate(group_handle &p, std::error_code &ec) noexcept { if (::killpg(p.grp, SIGKILL) == -1) @@ -89,15 +77,18 @@ inline void terminate(group_handle &p, std::error_code &ec) noexcept p.grp = -1; } +inline void terminate(group_handle &p) +{ + std::error_code ec; + terminate(p, ec); + boost::process::detail::throw_error(ec, "killpg(2) failed in terminate"); +} inline bool in_group() { return true; } - - }}}} - #endif /* BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_ */ diff --git a/boost/process/detail/posix/io_context_ref.hpp b/boost/process/detail/posix/io_context_ref.hpp index 603fd59a16..6eefee2247 100644 --- a/boost/process/detail/posix/io_context_ref.hpp +++ b/boost/process/detail/posix/io_context_ref.hpp @@ -18,6 +18,7 @@ #include <boost/process/detail/posix/sigchld_service.hpp> +#include <boost/process/detail/posix/is_running.hpp> #include <functional> #include <type_traits> @@ -95,11 +96,11 @@ struct io_context_ref : handler_base_ext auto & es = exec.exit_status; auto wh = [funcs, es](int val, const std::error_code & ec) - { - es->store(val); + { + es->store(val); for (auto & func : funcs) - func(WEXITSTATUS(val), ec); - }; + func(::boost::process::detail::posix::eval_exit_status(val), ec); + }; sigchld_service.async_wait(exec.pid, std::move(wh)); } diff --git a/boost/process/detail/posix/is_running.hpp b/boost/process/detail/posix/is_running.hpp index e8a009dd22..0d431a9126 100644 --- a/boost/process/detail/posix/is_running.hpp +++ b/boost/process/detail/posix/is_running.hpp @@ -13,37 +13,22 @@ namespace boost { namespace process { namespace detail { namespace posix { - +// Use the "stopped" state (WIFSTOPPED) to indicate "not terminated". +// This bit arrangement of status codes is not guaranteed by POSIX, but (according to comments in +// the glibc <bits/waitstatus.h> header) is the same across systems in practice. constexpr int still_active = 0x7F; -static_assert(!WIFEXITED(still_active), "Internal Error"); +static_assert(!WIFEXITED(still_active) && !WIFSIGNALED(still_active), "Internal Error"); -inline bool is_running(const child_handle &p, int & exit_code) +inline bool is_running(int code) { - int status; - auto ret = ::waitpid(p.pid, &status, WNOHANG|WUNTRACED); - - if (ret == -1) - { - if (errno != ECHILD) //because it no child is running, than this one isn't either, obviously. - ::boost::process::detail::throw_last_error("is_running error"); - - return false; - } - else if (ret == 0) - return true; - else //exited - { - if (WIFEXITED(status)) - exit_code = status; - return false; - } + return !WIFEXITED(code) && !WIFSIGNALED(code); } inline bool is_running(const child_handle &p, int & exit_code, std::error_code &ec) noexcept { int status; - auto ret = ::waitpid(p.pid, &status, WNOHANG|WUNTRACED); - + auto ret = ::waitpid(p.pid, &status, WNOHANG); + if (ret == -1) { if (errno != ECHILD) //because it no child is running, than this one isn't either, obviously. @@ -55,22 +40,36 @@ inline bool is_running(const child_handle &p, int & exit_code, std::error_code & else { ec.clear(); - - if (WIFEXITED(status)) + + if (!is_running(status)) exit_code = status; - + return false; } } -inline bool is_running(int code) +inline bool is_running(const child_handle &p, int & exit_code) { - return !WIFEXITED(code); + std::error_code ec; + bool b = is_running(p, exit_code, ec); + boost::process::detail::throw_error(ec, "waitpid(2) failed in is_running"); + return b; } inline int eval_exit_status(int code) { - return WEXITSTATUS(code); + if (WIFEXITED(code)) + { + return WEXITSTATUS(code); + } + else if (WIFSIGNALED(code)) + { + return WTERMSIG(code); + } + else + { + return code; + } } }}}} diff --git a/boost/process/detail/posix/search_path.hpp b/boost/process/detail/posix/search_path.hpp index 633cf0702e..ad781e57d8 100644 --- a/boost/process/detail/posix/search_path.hpp +++ b/boost/process/detail/posix/search_path.hpp @@ -27,7 +27,9 @@ inline boost::filesystem::path search_path( for (const boost::filesystem::path & pp : path) { auto p = pp / filename; - if (!::access(p.c_str(), X_OK)) + boost::system::error_code ec; + bool file = boost::filesystem::is_regular_file(p, ec); + if (!ec && file && ::access(p.c_str(), X_OK) == 0) return p; } return ""; diff --git a/boost/process/detail/posix/sigchld_service.hpp b/boost/process/detail/posix/sigchld_service.hpp index 7fee01e075..108b2b3fba 100644 --- a/boost/process/detail/posix/sigchld_service.hpp +++ b/boost/process/detail/posix/sigchld_service.hpp @@ -77,19 +77,28 @@ void sigchld_service::_handle_signal(const boost::system::error_code & ec) r.second(-1, ec_); return; } - int status; - int pid = ::waitpid(0, &status, WNOHANG); - auto itr = std::find_if(_receivers.begin(), _receivers.end(), - [&pid](const std::pair<::pid_t, std::function<void(int, std::error_code)>> & p) - { - return p.first == pid; - }); - if (itr != _receivers.cend()) - { - _strand.get_io_context().wrap(itr->second)(status, ec_); - _receivers.erase(itr); + for (auto & r : _receivers) { + int status; + int pid = ::waitpid(r.first, &status, WNOHANG); + if (pid < 0) { + // error (eg: the process no longer exists) + r.second(-1, get_last_error()); + r.first = 0; // mark for deletion + } else if (pid == r.first) { + r.second(status, ec_); + r.first = 0; // mark for deletion + } + // otherwise the process is still around } + + _receivers.erase(std::remove_if(_receivers.begin(), _receivers.end(), + [](const std::pair<::pid_t, std::function<void(int, std::error_code)>> & p) + { + return p.first == 0; + }), + _receivers.end()); + if (!_receivers.empty()) { _signal_set.async_wait( diff --git a/boost/process/detail/posix/terminate.hpp b/boost/process/detail/posix/terminate.hpp index d8048362b0..84024a5b34 100644 --- a/boost/process/detail/posix/terminate.hpp +++ b/boost/process/detail/posix/terminate.hpp @@ -19,15 +19,6 @@ namespace boost { namespace process { namespace detail { namespace posix { - -inline void terminate(const child_handle &p) -{ - if (::kill(p.pid, SIGKILL) == -1) - boost::process::detail::throw_last_error("kill(2) failed"); - int status; - ::waitpid(p.pid, &status, 0); //just to clean it up -} - inline void terminate(const child_handle &p, std::error_code &ec) noexcept { if (::kill(p.pid, SIGKILL) == -1) @@ -39,6 +30,13 @@ inline void terminate(const child_handle &p, std::error_code &ec) noexcept ::waitpid(p.pid, &status, 0); //just to clean it up } +inline void terminate(const child_handle &p) +{ + std::error_code ec; + terminate(p, ec); + boost::process::detail::throw_error(ec, "kill(2) failed"); +} + }}}} #endif diff --git a/boost/process/detail/posix/wait_for_exit.hpp b/boost/process/detail/posix/wait_for_exit.hpp index 308aaf6908..21e277baea 100644 --- a/boost/process/detail/posix/wait_for_exit.hpp +++ b/boost/process/detail/posix/wait_for_exit.hpp @@ -19,21 +19,6 @@ namespace boost { namespace process { namespace detail { namespace posix { -inline void wait(const child_handle &p, int & exit_code) -{ - pid_t ret; - int status; - do - { - ret = ::waitpid(p.pid, &status, 0); - } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); - if (ret == -1) - boost::process::detail::throw_last_error("waitpid(2) failed"); - if (WIFSIGNALED(status)) - throw process_error(std::error_code(), "process terminated due to receipt of a signal"); - exit_code = status; -} - inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) noexcept { pid_t ret; @@ -44,7 +29,7 @@ inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) no ret = ::waitpid(p.pid, &status, 0); } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); - + if (ret == -1) ec = boost::process::detail::get_last_error(); else @@ -52,60 +37,25 @@ inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) no ec.clear(); exit_code = status; } - - } -template< class Rep, class Period > -inline bool wait_for( - const child_handle &p, - int & exit_code, - const std::chrono::duration<Rep, Period>& rel_time) +inline void wait(const child_handle &p, int & exit_code) noexcept { - - pid_t ret; - int status; - - auto start = std::chrono::system_clock::now(); - auto time_out = start + rel_time; - - bool timed_out; - do - { - ret = ::waitpid(p.pid, &status, WNOHANG); - if (ret == 0) - { - timed_out = std::chrono::system_clock::now() >= time_out; - if (timed_out) - return false; - } - } - while ((ret == 0) || - ((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); - - if (ret == -1) - boost::process::detail::throw_last_error("waitpid(2) failed"); - - exit_code = status; - - return true; + std::error_code ec; + wait(p, exit_code, ec); + boost::process::detail::throw_error(ec, "waitpid(2) failed in wait"); } - -template< class Rep, class Period > -inline bool wait_for( +template< class Clock, class Duration > +inline bool wait_until( const child_handle &p, int & exit_code, - const std::chrono::duration<Rep, Period>& rel_time, + const std::chrono::time_point<Clock, Duration>& time_out, std::error_code & ec) noexcept { - pid_t ret; int status; - auto start = std::chrono::system_clock::now(); - auto time_out = start + rel_time; bool timed_out; do @@ -113,19 +63,15 @@ inline bool wait_for( ret = ::waitpid(p.pid, &status, WNOHANG); if (ret == 0) { - timed_out = std::chrono::system_clock::now() >= time_out; + timed_out = Clock::now() >= time_out; if (timed_out) return false; } - } + } while ((ret == 0) || (((ret == -1) && errno == EINTR) || ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)))); - - if (timed_out && (ret == -1)) - return false; - if (ret == -1) ec = boost::process::detail::get_last_error(); else @@ -137,86 +83,38 @@ inline bool wait_for( return true; } - - template< class Clock, class Duration > inline bool wait_until( const child_handle &p, int & exit_code, - const std::chrono::time_point<Clock, Duration>& time_out) + const std::chrono::time_point<Clock, Duration>& time_out) noexcept { - - pid_t ret; - int status; - - bool timed_out; - do - { - ret = ::waitpid(p.pid, &status, WNOHANG); - if (ret == 0) - { - timed_out = std::chrono::system_clock::now() >= time_out; - if (timed_out) - return false; - } - } - while ((ret == 0) || - (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)))); - - - if (timed_out && !WIFEXITED(status)) - return false; - - if (ret == -1) - boost::process::detail::throw_last_error("waitpid(2) failed"); - exit_code = status; - - return true; + std::error_code ec; + bool b = wait_until(p, exit_code, time_out, ec); + boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_until"); + return b; } - -template< class Clock, class Duration > -inline bool wait_until( +template< class Rep, class Period > +inline bool wait_for( const child_handle &p, int & exit_code, - const std::chrono::time_point<Clock, Duration>& time_out, + const std::chrono::duration<Rep, Period>& rel_time, std::error_code & ec) noexcept { + return wait_until(p, exit_code, std::chrono::steady_clock::now() + rel_time, ec); +} - pid_t ret; - int status; - - bool timed_out; - - do - { - ret = ::waitpid(p.pid, &status, WNOHANG); - if (ret == 0) - { - timed_out = std::chrono::system_clock::now() >= time_out; - if (timed_out) - return false; - } - } - while ((ret == 0) || - (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)))); - - - - if (timed_out && !WIFEXITED(status)) - return false; - - if (ret == -1) - ec = boost::process::detail::get_last_error(); - else - { - ec.clear(); - exit_code = status; - } - - return true; +template< class Rep, class Period > +inline bool wait_for( + const child_handle &p, + int & exit_code, + const std::chrono::duration<Rep, Period>& rel_time) noexcept +{ + std::error_code ec; + bool b = wait_for(p, exit_code, rel_time, ec); + boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_for"); + return b; } }}}} diff --git a/boost/process/detail/posix/wait_group.hpp b/boost/process/detail/posix/wait_group.hpp index 172fe06b5b..024d9003b9 100644 --- a/boost/process/detail/posix/wait_group.hpp +++ b/boost/process/detail/posix/wait_group.hpp @@ -12,26 +12,13 @@ #include <boost/process/detail/config.hpp> #include <boost/process/detail/posix/group_handle.hpp> +#include <chrono> #include <system_error> #include <sys/types.h> #include <sys/wait.h> namespace boost { namespace process { namespace detail { namespace posix { -inline void wait(const group_handle &p) -{ - pid_t ret; - int status; - do - { - ret = ::waitpid(-p.grp, &status, 0); - } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); - if (ret == -1) - boost::process::detail::throw_last_error("waitpid(2) failed"); - if (WIFSIGNALED(status)) - throw process_error(std::error_code(), "process group terminated due to receipt of a signal"); -} - inline void wait(const group_handle &p, std::error_code &ec) noexcept { pid_t ret; @@ -42,155 +29,82 @@ inline void wait(const group_handle &p, std::error_code &ec) noexcept ret = ::waitpid(-p.grp, &status, 0); } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); - + if (ret == -1) ec = boost::process::detail::get_last_error(); - else if (WIFSIGNALED(status)) - ec = std::make_error_code(std::errc::no_such_process); else ec.clear(); - } -template< class Rep, class Period > -inline bool wait_for( - const group_handle &p, - const std::chrono::duration<Rep, Period>& rel_time) +inline void wait(const group_handle &p) noexcept { - - pid_t ret; - int status; - - auto start = std::chrono::system_clock::now(); - auto time_out = start + rel_time; - - bool time_out_occured = false; - do - { - ret = ::waitpid(-p.grp, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) - { - time_out_occured = true; - break; - } - } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); - - - if (ret == -1) - boost::process::detail::throw_last_error("waitpid(2) failed"); - if (WIFSIGNALED(status)) - throw process_error(std::error_code(), "process group terminated due to receipt of a signal"); - - return !time_out_occured; + std::error_code ec; + wait(p, ec); + boost::process::detail::throw_error(ec, "waitpid(2) failed in wait"); } - -template< class Rep, class Period > -inline bool wait_for( +template< class Clock, class Duration > +inline bool wait_until( const group_handle &p, - const std::chrono::duration<Rep, Period>& rel_time, + const std::chrono::time_point<Clock, Duration>& time_out, std::error_code & ec) noexcept { - pid_t ret; int status; - auto start = std::chrono::system_clock::now(); - auto time_out = start + rel_time; + bool timed_out; - bool time_out_occured = false; do { - ret = ::waitpid(-p.grp, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) + ret = ::waitpid(-p.grp, &status, WNOHANG); + if (ret == 0) { - time_out_occured = true; - break; + timed_out = Clock::now() >= time_out; + if (timed_out) + return false; } - } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); - + } + while ((ret == 0) || + (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)))); if (ret == -1) ec = boost::process::detail::get_last_error(); - else if (WIFSIGNALED(status)) - ec = std::make_error_code(std::errc::no_such_process); else ec.clear(); - return !time_out_occured; + return true; } - - -template< class Rep, class Period > +template< class Clock, class Duration > inline bool wait_until( const group_handle &p, - const std::chrono::duration<Rep, Period>& time_out) + const std::chrono::time_point<Clock, Duration>& time_out) noexcept { - - pid_t ret; - int status; - - bool time_out_occured = false; - do - { - ret = ::waitpid(-p.grp, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) - { - time_out_occured = true; - break; - } - } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); - - - if (ret == -1) - boost::process::detail::throw_last_error("waitpid(2) failed"); - if (WIFSIGNALED(status)) - throw process_error(std::error_code(), "process group terminated due to receipt of a signal"); - - - return !time_out_occured; + std::error_code ec; + bool b = wait_until(p, time_out, ec); + boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_until"); + return b; } - template< class Rep, class Period > -inline bool wait_until( +inline bool wait_for( const group_handle &p, - const std::chrono::duration<Rep, Period>& time_out, + const std::chrono::duration<Rep, Period>& rel_time, std::error_code & ec) noexcept { + return wait_until(p, std::chrono::steady_clock::now() + rel_time, ec); +} - pid_t ret; - int status; - - bool time_out_occured = false; - do - { - ret = ::waitpid(-p.grp, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) - { - time_out_occured = true; - break; - } - } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); - - - if (ret == -1) - ec = boost::process::detail::get_last_error(); - else if (WIFSIGNALED(status)) - ec = std::make_error_code(std::errc::no_such_process); - else - ec.clear(); - - return !time_out_occured; +template< class Rep, class Period > +inline bool wait_for( + const group_handle &p, + const std::chrono::duration<Rep, Period>& rel_time) noexcept +{ + std::error_code ec; + bool b = wait_for(p, rel_time, ec); + boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_for"); + return b; } }}}} |