]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/process/detail/posix/wait_for_exit.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / process / detail / posix / wait_for_exit.hpp
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)
23 {
24 pid_t ret;
25 int status;
26 do
27 {
28 ret = ::waitpid(p.pid, &status, 0);
29 } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status)));
30 if (ret == -1)
31 boost::process::detail::throw_last_error("waitpid(2) failed");
32 if (WIFSIGNALED(status))
33 throw process_error(std::error_code(), "process terminated due to receipt of a signal");
34 exit_code = status;
35 }
36
37 inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) noexcept
38 {
39 pid_t ret;
40 int status;
41
42 do
43 {
44 ret = ::waitpid(p.pid, &status, 0);
45 }
46 while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status)));
47
48 if (ret == -1)
49 ec = boost::process::detail::get_last_error();
50 else
51 {
52 ec.clear();
53 exit_code = status;
54 }
55
56
57 }
58
59 template< class Rep, class Period >
60 inline bool wait_for(
61 const child_handle &p,
62 int & exit_code,
63 const std::chrono::duration<Rep, Period>& rel_time)
64 {
65
66 pid_t ret;
67 int status;
68
69 auto start = std::chrono::system_clock::now();
70 auto time_out = start + rel_time;
71
72 bool timed_out;
73 do
74 {
75 ret = ::waitpid(p.pid, &status, WNOHANG);
76 if (ret == 0)
77 {
78 timed_out = std::chrono::system_clock::now() >= time_out;
79 if (timed_out)
80 return false;
81 }
82 }
83 while ((ret == 0) ||
84 ((ret == -1) && errno == EINTR) ||
85 ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)));
86
87 if (ret == -1)
88 boost::process::detail::throw_last_error("waitpid(2) failed");
89
90 exit_code = status;
91
92 return true;
93 }
94
95
96 template< class Rep, class Period >
97 inline bool wait_for(
98 const child_handle &p,
99 int & exit_code,
100 const std::chrono::duration<Rep, Period>& rel_time,
101 std::error_code & ec) noexcept
102 {
103
104 pid_t ret;
105 int status;
106
107 auto start = std::chrono::system_clock::now();
108 auto time_out = start + rel_time;
109 bool timed_out;
110
111 do
112 {
113 ret = ::waitpid(p.pid, &status, WNOHANG);
114 if (ret == 0)
115 {
116 timed_out = std::chrono::system_clock::now() >= time_out;
117 if (timed_out)
118 return false;
119 }
120 }
121 while ((ret == 0) ||
122 (((ret == -1) && errno == EINTR) ||
123 ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))));
124
125
126 if (timed_out && (ret == -1))
127 return false;
128
129 if (ret == -1)
130 ec = boost::process::detail::get_last_error();
131 else
132 {
133 ec.clear();
134 exit_code = status;
135 }
136
137 return true;
138 }
139
140
141
142 template< class Clock, class Duration >
143 inline bool wait_until(
144 const child_handle &p,
145 int & exit_code,
146 const std::chrono::time_point<Clock, Duration>& time_out)
147 {
148
149 pid_t ret;
150 int status;
151
152 bool timed_out;
153 do
154 {
155 ret = ::waitpid(p.pid, &status, WNOHANG);
156 if (ret == 0)
157 {
158 timed_out = std::chrono::system_clock::now() >= time_out;
159 if (timed_out)
160 return false;
161 }
162 }
163 while ((ret == 0) ||
164 (((ret == -1) && errno == EINTR) ||
165 ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))));
166
167
168 if (timed_out && !WIFEXITED(status))
169 return false;
170
171 if (ret == -1)
172 boost::process::detail::throw_last_error("waitpid(2) failed");
173 exit_code = status;
174
175 return true;
176 }
177
178
179 template< class Clock, class Duration >
180 inline bool wait_until(
181 const child_handle &p,
182 int & exit_code,
183 const std::chrono::time_point<Clock, Duration>& time_out,
184 std::error_code & ec) noexcept
185 {
186
187 pid_t ret;
188 int status;
189
190 bool timed_out;
191
192 do
193 {
194 ret = ::waitpid(p.pid, &status, WNOHANG);
195 if (ret == 0)
196 {
197 timed_out = std::chrono::system_clock::now() >= time_out;
198 if (timed_out)
199 return false;
200 }
201 }
202 while ((ret == 0) ||
203 (((ret == -1) && errno == EINTR) ||
204 ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))));
205
206
207
208 if (timed_out && !WIFEXITED(status))
209 return false;
210
211 if (ret == -1)
212 ec = boost::process::detail::get_last_error();
213 else
214 {
215 ec.clear();
216 exit_code = status;
217 }
218
219 return true;
220 }
221
222 }}}}
223
224 #endif