1    	// Copyright (c) 2006, 2007 Julio M. Merino Vidal
2    	// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
3    	// Copyright (c) 2009 Boris Schaeling
4    	// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
5    	// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
6    	//
7    	// Distributed under the Boost Software License, Version 1.0. (See accompanying
8    	// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9    	
10   	#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
11   	#define BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
12   	
13   	#include <boost/process/detail/config.hpp>
14   	#include <boost/process/detail/posix/child_handle.hpp>
15   	#include <system_error>
16   	#include <sys/types.h>
17   	#include <sys/wait.h>
18   	#include <unistd.h>
19   	
20   	namespace boost { namespace process { namespace detail { namespace posix {
21   	
22   	inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) noexcept
23   	{
24   	    pid_t ret;
25   	    int status;
26   	
27   	    do
28   	    {
(9) Event example_assign: Example 5: Assigning: "ret" = return value from "waitpid(p.pid, &status, 0)".
Also see events: [check_return][example_checked][example_checked][example_checked][example_assign][example_checked][example_checked]
29   	        ret = ::waitpid(p.pid, &status, 0);
30   	    } 
(10) Event example_checked: Example 5 (cont.): "ret" has its value checked in "ret == -1".
Also see events: [check_return][example_checked][example_checked][example_checked][example_assign][example_checked][example_assign]
31   	    while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status)));
32   	
33   	    if (ret == -1)
34   	        ec = boost::process::detail::get_last_error();
35   	    else
36   	    {
37   	        ec.clear();
38   	        exit_code = status;
39   	    }
40   	}
41   	
42   	inline void wait(const child_handle &p, int & exit_code) noexcept
43   	{
44   	    std::error_code ec;
45   	    wait(p, exit_code, ec);
46   	    boost::process::detail::throw_error(ec, "waitpid(2) failed in wait");
47   	}
48   	
49   	template< class Clock, class Duration >
50   	inline bool wait_until(
51   	        const child_handle &p,
52   	        int & exit_code,
53   	        const std::chrono::time_point<Clock, Duration>& time_out,
54   	        std::error_code & ec) noexcept
55   	{
56   	    pid_t ret;
57   	    int status;
58   	
59   	    bool timed_out;
60   	
61   	    do
62   	    {
63   	        ret = ::waitpid(p.pid, &status, WNOHANG);
64   	        if (ret == 0)
65   	        {
66   	            timed_out = Clock::now() >= time_out;
67   	            if (timed_out)
68   	                return false;
69   	        }
70   	    }
71   	    while ((ret == 0) ||
72   	          (((ret == -1) && errno == EINTR) ||
73   	           ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))));
74   	
75   	    if (ret == -1)
76   	        ec = boost::process::detail::get_last_error();
77   	    else
78   	    {
79   	        ec.clear();
80   	        exit_code = status;
81   	    }
82   	
83   	    return true;
84   	}
85   	
86   	template< class Clock, class Duration >
87   	inline bool wait_until(
88   	        const child_handle &p,
89   	        int & exit_code,
90   	        const std::chrono::time_point<Clock, Duration>& time_out) noexcept
91   	{
92   	    std::error_code ec;
93   	    bool b = wait_until(p, exit_code, time_out, ec);
94   	    boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_until");
95   	    return b;
96   	}
97   	
98   	template< class Rep, class Period >
99   	inline bool wait_for(
100  	        const child_handle &p,
101  	        int & exit_code,
102  	        const std::chrono::duration<Rep, Period>& rel_time,
103  	        std::error_code & ec) noexcept
104  	{
105  	    return wait_until(p, exit_code, std::chrono::steady_clock::now() + rel_time, ec);
106  	}
107  	
108  	template< class Rep, class Period >
109  	inline bool wait_for(
110  	        const child_handle &p,
111  	        int & exit_code,
112  	        const std::chrono::duration<Rep, Period>& rel_time) noexcept
113  	{
114  	    std::error_code ec;
115  	    bool b = wait_for(p, exit_code, rel_time, ec);
116  	    boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_for");
117  	    return b;
118  	}
119  	
120  	}}}}
121  	
122  	#endif
123