summaryrefslogtreecommitdiff
path: root/boost/process/detail/posix/wait_for_exit.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/process/detail/posix/wait_for_exit.hpp')
-rw-r--r--boost/process/detail/posix/wait_for_exit.hpp205
1 files changed, 205 insertions, 0 deletions
diff --git a/boost/process/detail/posix/wait_for_exit.hpp b/boost/process/detail/posix/wait_for_exit.hpp
new file mode 100644
index 0000000000..bf25e2a3d8
--- /dev/null
+++ b/boost/process/detail/posix/wait_for_exit.hpp
@@ -0,0 +1,205 @@
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
+#define BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
+
+#include <boost/process/detail/config.hpp>
+#include <boost/process/detail/posix/child_handle.hpp>
+#include <system_error>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+
+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)));
+ if (ret == -1)
+ boost::process::detail::throw_last_error("waitpid(2) failed");
+ exit_code = status;
+}
+
+inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) noexcept
+{
+ pid_t ret;
+ int status;
+
+ do
+ {
+ ret = ::waitpid(p.pid, &status, 0);
+ }
+ while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status)));
+
+ if (ret == -1)
+ ec = boost::process::detail::get_last_error();
+ else
+ {
+ 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)
+{
+
+ 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.pid, &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)));
+
+
+ if (ret == -1)
+ boost::process::detail::throw_last_error("waitpid(2) failed");
+
+ exit_code = status;
+
+ return !time_out_occured;
+}
+
+
+template< class Rep, class Period >
+inline bool wait_for(
+ const child_handle &p,
+ int & exit_code,
+ const std::chrono::duration<Rep, Period>& rel_time,
+ std::error_code & ec) 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.pid, &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)));
+
+
+ if (ret == -1)
+ ec = boost::process::detail::get_last_error();
+ else
+ {
+ ec.clear();
+ exit_code = status;
+ }
+
+ return !time_out_occured;
+}
+
+
+
+template< class Rep, class Period >
+inline bool wait_until(
+ const child_handle &p,
+ int & exit_code,
+ const std::chrono::duration<Rep, Period>& time_out)
+{
+
+ pid_t ret;
+ int status;
+
+ bool time_out_occured = false;
+ do
+ {
+ ret = ::waitpid(p.pid, &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)));
+
+
+ if (ret == -1)
+ boost::process::detail::throw_last_error("waitpid(2) failed");
+
+ exit_code = status;
+
+ return !time_out_occured;
+}
+
+
+template< class Rep, class Period >
+inline bool wait_until(
+ const child_handle &p,
+ int & exit_code,
+ const std::chrono::duration<Rep, Period>& time_out,
+ std::error_code & ec) noexcept
+{
+
+ pid_t ret;
+ int status;
+
+ bool time_out_occured = false;
+ do
+ {
+ ret = ::waitpid(p.pid, &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)));
+
+
+ if (ret == -1)
+ ec = boost::process::detail::get_last_error();
+ else
+ {
+ ec.clear();
+ exit_code = status;
+ }
+
+ return !time_out_occured;
+}
+
+}}}}
+
+#endif