comparison third_party/boost/process/process.hpp @ 0:add35537fdbb tip

Initial import
author irh <ian.r.hobson@gmail.com>
date Thu, 25 Aug 2011 11:05:55 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:add35537fdbb
1 //
2 // Boost.Process
3 // ~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
6 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
7 // Copyright (c) 2009 Boris Schaeling
8 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
9 //
10 // Distributed under the Boost Software License, Version 1.0. (See accompanying
11 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
12 //
13
14 /**
15 * \file boost/process/process.hpp
16 *
17 * Includes the declaration of the process class.
18 */
19
20 #ifndef BOOST_PROCESS_PROCESS_HPP
21 #define BOOST_PROCESS_PROCESS_HPP
22
23 #include <boost/process/config.hpp>
24
25 #if defined(BOOST_POSIX_API)
26 # include <unistd.h>
27 # include <sys/types.h>
28 # include <signal.h>
29 # include <sys/wait.h>
30 # include <errno.h>
31 #elif defined(BOOST_WINDOWS_API)
32 # include <boost/process/handle.hpp>
33 # include <cstdlib>
34 # include <windows.h>
35 #else
36 # error "Unsupported platform."
37 #endif
38
39 #include <boost/process/pid_type.hpp>
40
41 namespace boost {
42 namespace process {
43
44 /**
45 * Process class to represent any running process.
46 */
47 class process
48 {
49 public:
50 /**
51 * Constructs a new process object.
52 *
53 * Creates a new process object that represents a running process
54 * within the system.
55 *
56 * On Windows the process is opened and a handle saved. This is required
57 * to avoid the operating system removing process resources when the
58 * process exits. The handle is closed when the process instance (and all
59 * of its copies) is destroyed.
60 */
61 process(pid_type id)
62 : id_(id)
63 #if defined(BOOST_WINDOWS_API)
64 , handle_(open_process(id))
65 #endif
66 {
67 }
68
69 #if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN)
70 /**
71 * Constructs a new process object.
72 *
73 * Creates a new process object that represents a running process
74 * within the system.
75 *
76 * This operation is only available on Windows systems. The handle is
77 * closed when the process instance (and all of its copies) is destroyed.
78 */
79 process(handle h)
80 : id_(GetProcessId(h.native())),
81 handle_(h)
82 {
83 }
84 #endif
85
86 /**
87 * Returns the process identifier.
88 */
89 pid_type get_id() const
90 {
91 return id_;
92 }
93
94 /**
95 * Terminates the process execution.
96 *
97 * Forces the termination of the process execution. Some platforms
98 * allow processes to ignore some external termination notifications
99 * or to capture them for a proper exit cleanup. You can set the
100 * \a force flag to true to force their termination regardless
101 * of any exit handler.
102 *
103 * After this call, accessing this object can be dangerous because the
104 * process identifier may have been reused by a different process. It
105 * might still be valid, though, if the process has refused to die.
106 *
107 * \throw boost::system::system_error If system calls used to terminate the
108 * process fail.
109 */
110 void terminate(bool force = false) const
111 {
112 #if defined(BOOST_POSIX_API)
113 if (kill(id_, force ? SIGKILL : SIGTERM) == -1)
114 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("kill(2) failed");
115 #elif defined(BOOST_WINDOWS_API)
116 #if defined(BOOST_MSVC)
117 force;
118 #endif
119 HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, id_);
120 if (h == NULL)
121 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
122 if (!TerminateProcess(h, EXIT_FAILURE))
123 {
124 CloseHandle(h);
125 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("TerminateProcess() failed");
126 }
127 if (!CloseHandle(h))
128 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
129 #endif
130 }
131
132 /**
133 * Blocks and waits for the process to terminate.
134 *
135 * Returns an exit code. The process object ceases to be valid after this
136 * call.
137 *
138 * \remark Blocking remarks: This call blocks if the process has not
139 * finalized execution and waits until it terminates.
140 *
141 * \throw boost::system::system_error If system calls used to wait for the
142 * process fail.
143 */
144 int wait() const
145 {
146 #if defined(BOOST_POSIX_API)
147 pid_t p;
148 int status;
149 do
150 {
151 p = waitpid(id_, &status, 0);
152 } while (p == -1 && errno == EINTR);
153 if (p == -1)
154 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("waitpid(2) failed");
155 return status;
156 #elif defined(BOOST_WINDOWS_API)
157 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE,
158 id_);
159 if (h == NULL)
160 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
161 if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED)
162 {
163 CloseHandle(h);
164 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
165 "WaitForSingleObject() failed");
166 }
167 DWORD exit_code;
168 if (!GetExitCodeProcess(h, &exit_code))
169 {
170 CloseHandle(h);
171 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
172 "GetExitCodeProcess() failed");
173 }
174 if (!CloseHandle(h))
175 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
176 return exit_code;
177 #endif
178 }
179
180 private:
181 /**
182 * The process identifier.
183 */
184 pid_type id_;
185
186 #if defined(BOOST_WINDOWS_API)
187 /**
188 * Opens a process and returns a handle.
189 *
190 * OpenProcess() returns NULL and not INVALID_HANDLE_VALUE on failure.
191 * That's why the return value is manually checked in this helper function
192 * instead of simply passing it to the constructor of the handle class.
193 */
194 HANDLE open_process(pid_type id)
195 {
196 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id);
197 if (h == NULL)
198 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
199 return h;
200 }
201
202 /**
203 * The process handle.
204 */
205 handle handle_;
206 #endif
207 };
208
209 }
210 }
211
212 #endif