]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
b32b8144
FG
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
20namespace boost { namespace process { namespace detail { namespace posix {
21
22inline 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
37inline 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
59template< class Rep, class Period >
60inline 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
96template< class Rep, class Period >
97inline 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
142template< class Clock, class Duration >
143inline 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
179template< class Clock, class Duration >
180inline 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