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 // Copyright (c) 2016 Klemens D. Morgenstern
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10
11 /**
12 * \file boost/process/child.hpp
13 *
14 * Defines a child process class.
15 */
16
17 #ifndef BOOST_PROCESS_CHILD_HPP
18 #define BOOST_PROCESS_CHILD_HPP
19
20 #include <boost/process/detail/config.hpp>
21 #include <boost/process/detail/child_decl.hpp>
22 #include <boost/process/detail/execute_impl.hpp>
23
24 #if defined(BOOST_POSIX_API)
25 #include <boost/process/posix.hpp>
26 #endif
27
28 namespace boost {
29
30 ///The main namespace of boost.process.
31 namespace process {
32
33 template<typename ...Args>
child(Args &&...args)34 child::child(Args&&...args)
35 : child(::boost::process::detail::execute_impl(std::forward<Args>(args)...)) {}
36
37
38 ///Typedef for the type of an pid_t
39 typedef ::boost::process::detail::api::pid_t pid_t;
40
41 #if defined(BOOST_PROCESS_DOXYGEN)
42 /** The main class to hold a child process. It is simliar to [std::thread](http://en.cppreference.com/w/cpp/thread/thread),
43 * in that it has a join and detach function.
44 *
45 * @attention The destructor will call terminate on the process if not joined or detached without any warning.
46 *
47 */
48
49 class child
50 {
51 /** Type definition for the native process handle. */
52 typedef platform_specific native_handle_t;
53
54 /** Construct the child from a pid.
55 *
56 * @attention There is no guarantee that this will work. The process need the right access rights, which are very platform specific.
57 */
child(pid_t & pid)58 explicit child(pid_t & pid) : _child_handle(pid) {};
59
60 /** Move-Constructor.*/
61 child(child && lhs);
62
63 /** Construct a child from a property list and launch it
64 * The standard version is to create a subprocess, which will spawn the process.
65 */
66 template<typename ...Args>
67 explicit child(Args&&...args);
68
69 /** Construct an empty child. */
70 child() = default;
71
72 /** Move assign. */
73 child& operator=(child && lhs);
74
75 /** Detach the child, i.e. let it run after this handle dies. */
76 void detach();
77 /** Join the child. This just calls wait, but that way the naming is similar to std::thread */
78 void join();
79 /** Check if the child is joinable. */
80 bool joinable();
81
82 /** Destructor.
83 * @attention Will call terminate (without warning) when the child was neither joined nor detached.
84 */
85 ~child();
86
87 /** Get the native handle for the child process. */
88 native_handle_t native_handle() const;
89
90 /** Get the exit_code. The return value is without any meaning if the child wasn't waited for or if it was terminated. */
91 int exit_code() const;
92 /** Get the Process Identifier. */
93 pid_t id() const;
94
95 /** Get the native, uninterpreted exit code. The return value is without any meaning if the child wasn't waited
96 * for or if it was terminated. */
97 int native_exit_code() const;
98
99 /** Check if the child process is running. */
100 bool running();
101 /** \overload void running() */
102 bool running(std::error_code & ec) noexcept;
103
104 /** Wait for the child process to exit. */
105 void wait();
106 /** \overload void wait() */
107 void wait(std::error_code & ec) noexcept;
108
109 /** Wait for the child process to exit for a period of time.
110 * \return True if child exited while waiting.
111 */
112 template< class Rep, class Period >
113 bool wait_for (const std::chrono::duration<Rep, Period>& rel_time);
114 /** \overload bool wait_for(const std::chrono::duration<Rep, Period>& rel_time) */
115 bool wait_for (const std::chrono::duration<Rep, Period>& rel_time, std::error_code & ec) noexcept;
116
117 /** Wait for the child process to exit until a point in time.
118 * \return True if child exited while waiting.*/
119 template< class Clock, class Duration >
120 bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time );
121 /** \overload bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time )*/
122 bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, std::error_code & ec) noexcept;
123
124 /** Check if this handle holds a child process.
125 * @note That does not mean, that the process is still running. It only means, that the handle does or did exist.
126 */
127 bool valid() const;
128 /** Same as valid, for convenience. */
129 explicit operator bool() const;
130
131 /** Check if the the chlid process is in any process group. */
132 bool in_group() const;
133
134 /** \overload bool in_group() const */
135 bool in_group(std::error_code & ec) const noexcept;
136
137 /** Terminate the child process.
138 *
139 * This function will cause the child process to unconditionally and immediately exit.
140 * It is implement with [SIGKILL](http://pubs.opengroup.org/onlinepubs/009695399/functions/kill.html) on posix
141 * and [TerminateProcess](https://technet.microsoft.com/en-us/library/ms686714.aspx) on windows.
142 *
143 */
144 void terminate();
145
146 /** \overload void terminate() */
147 void terminate(std::error_code & ec) noexcept;
148 };
149
150 #endif
151
152 }}
153 #endif
154
155