Mercurial > hg > gpsynth
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 |