ian@0
|
1 //
|
ian@0
|
2 // Boost.Process
|
ian@0
|
3 // ~~~~~~~~~~~~~
|
ian@0
|
4 //
|
ian@0
|
5 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
ian@0
|
6 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
ian@0
|
7 // Copyright (c) 2009 Boris Schaeling
|
ian@0
|
8 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
ian@0
|
9 //
|
ian@0
|
10 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
ian@0
|
11 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
ian@0
|
12 //
|
ian@0
|
13
|
ian@0
|
14 /**
|
ian@0
|
15 * \file boost/process/handle.hpp
|
ian@0
|
16 *
|
ian@0
|
17 * Includes the declaration of the handle class.
|
ian@0
|
18 */
|
ian@0
|
19
|
ian@0
|
20 #ifndef BOOST_PROCESS_HANDLE_HPP
|
ian@0
|
21 #define BOOST_PROCESS_HANDLE_HPP
|
ian@0
|
22
|
ian@0
|
23 #include <boost/process/config.hpp>
|
ian@0
|
24
|
ian@0
|
25 #if defined(BOOST_POSIX_API)
|
ian@0
|
26 # include <unistd.h>
|
ian@0
|
27 #elif defined(BOOST_WINDOWS_API)
|
ian@0
|
28 # include <windows.h>
|
ian@0
|
29 #else
|
ian@0
|
30 # error "Unsupported platform."
|
ian@0
|
31 #endif
|
ian@0
|
32
|
ian@0
|
33 #include <boost/shared_ptr.hpp>
|
ian@0
|
34 #include <boost/make_shared.hpp>
|
ian@0
|
35
|
ian@0
|
36 namespace boost {
|
ian@0
|
37 namespace process {
|
ian@0
|
38
|
ian@0
|
39 /**
|
ian@0
|
40 * RAII model for handles.
|
ian@0
|
41 *
|
ian@0
|
42 * The \a handle class is a RAII model for native handles. This class wraps
|
ian@0
|
43 * one of such handles grabbing its ownership, and automaticaly closes it
|
ian@0
|
44 * upon destruction. It is used to avoid leaking open handles, shall an
|
ian@0
|
45 * unexpected execution trace occur.
|
ian@0
|
46 */
|
ian@0
|
47 class handle
|
ian@0
|
48 {
|
ian@0
|
49 public:
|
ian@0
|
50 #if defined(BOOST_PROCESS_DOXYGEN)
|
ian@0
|
51 /**
|
ian@0
|
52 * Opaque name for the native handle type.
|
ian@0
|
53 *
|
ian@0
|
54 * On POSIX systems \a NativeSystemHandle is an integer type while it is
|
ian@0
|
55 * a \a HANDLE on Windows systems.
|
ian@0
|
56 */
|
ian@0
|
57 typedef NativeSystemHandle native_type;
|
ian@0
|
58 #elif defined(BOOST_POSIX_API)
|
ian@0
|
59 typedef int native_type;
|
ian@0
|
60 #elif defined(BOOST_WINDOWS_API)
|
ian@0
|
61 typedef HANDLE native_type;
|
ian@0
|
62 #endif
|
ian@0
|
63
|
ian@0
|
64 /**
|
ian@0
|
65 * Constructs an invalid handle.
|
ian@0
|
66 *
|
ian@0
|
67 * \see valid()
|
ian@0
|
68 */
|
ian@0
|
69 handle()
|
ian@0
|
70 {
|
ian@0
|
71 }
|
ian@0
|
72
|
ian@0
|
73 /**
|
ian@0
|
74 * RAII settings to specify if handle should be automatically closed.
|
ian@0
|
75 */
|
ian@0
|
76 enum close_type { do_close, dont_close };
|
ian@0
|
77
|
ian@0
|
78 /**
|
ian@0
|
79 * Constructs a handle from a native handle.
|
ian@0
|
80 *
|
ian@0
|
81 * This constructor creates a new \a handle object that takes
|
ian@0
|
82 * ownership of the given \a native handle. If \a close is set to
|
ian@0
|
83 * handle::dont_close the \a native handle is not closed upon destruction.
|
ian@0
|
84 * The user must not close \a native if it is owned by a \a handle object.
|
ian@0
|
85 * Ownership can be reclaimed using release().
|
ian@0
|
86 *
|
ian@0
|
87 * \see release()
|
ian@0
|
88 */
|
ian@0
|
89 handle(native_type native, close_type close = handle::do_close)
|
ian@0
|
90 : impl_(boost::make_shared<impl>(native, close))
|
ian@0
|
91 {
|
ian@0
|
92 }
|
ian@0
|
93
|
ian@0
|
94 /**
|
ian@0
|
95 * Checks whether the handle is valid or not.
|
ian@0
|
96 *
|
ian@0
|
97 * \return true if the handle is valid; false otherwise.
|
ian@0
|
98 */
|
ian@0
|
99 bool valid() const
|
ian@0
|
100 {
|
ian@0
|
101 return impl_ && impl_->valid();
|
ian@0
|
102 }
|
ian@0
|
103
|
ian@0
|
104 /**
|
ian@0
|
105 * Closes the handle.
|
ian@0
|
106 *
|
ian@0
|
107 * \post The handle is invalid.
|
ian@0
|
108 * \post The native handle is closed.
|
ian@0
|
109 */
|
ian@0
|
110 void close()
|
ian@0
|
111 {
|
ian@0
|
112 if (impl_)
|
ian@0
|
113 impl_->close();
|
ian@0
|
114 }
|
ian@0
|
115
|
ian@0
|
116 /**
|
ian@0
|
117 * Gets the native handle.
|
ian@0
|
118 *
|
ian@0
|
119 * The caller can issue any operation on it except closing it.
|
ian@0
|
120 * If closing is required, release() shall be used.
|
ian@0
|
121 *
|
ian@0
|
122 * \return The native handle.
|
ian@0
|
123 */
|
ian@0
|
124 native_type native() const
|
ian@0
|
125 {
|
ian@0
|
126 return impl_ ? impl_->native() : invalid_handle();
|
ian@0
|
127 }
|
ian@0
|
128
|
ian@0
|
129 /**
|
ian@0
|
130 * Reclaims ownership of the native handle.
|
ian@0
|
131 *
|
ian@0
|
132 * The caller is responsible of closing the native handle.
|
ian@0
|
133 *
|
ian@0
|
134 * \post The handle is invalid.
|
ian@0
|
135 * \return The native handle.
|
ian@0
|
136 */
|
ian@0
|
137 native_type release()
|
ian@0
|
138 {
|
ian@0
|
139 return impl_ ? impl_->release() : invalid_handle();
|
ian@0
|
140 }
|
ian@0
|
141
|
ian@0
|
142 private:
|
ian@0
|
143 class impl
|
ian@0
|
144 {
|
ian@0
|
145 public:
|
ian@0
|
146 typedef handle::native_type native_type;
|
ian@0
|
147
|
ian@0
|
148 impl(native_type native, close_type close)
|
ian@0
|
149 : native_(native),
|
ian@0
|
150 close_(close)
|
ian@0
|
151 {
|
ian@0
|
152 }
|
ian@0
|
153
|
ian@0
|
154 ~impl()
|
ian@0
|
155 {
|
ian@0
|
156 if (valid() && close_ == handle::do_close)
|
ian@0
|
157 {
|
ian@0
|
158 #if defined(BOOST_POSIX_API)
|
ian@0
|
159 ::close(native_);
|
ian@0
|
160 #elif defined(BOOST_WINDOWS_API)
|
ian@0
|
161 CloseHandle(native_);
|
ian@0
|
162 #endif
|
ian@0
|
163 }
|
ian@0
|
164 }
|
ian@0
|
165
|
ian@0
|
166 bool valid() const
|
ian@0
|
167 {
|
ian@0
|
168 return native_ != handle::invalid_handle();
|
ian@0
|
169 }
|
ian@0
|
170
|
ian@0
|
171 void close()
|
ian@0
|
172 {
|
ian@0
|
173 if (valid())
|
ian@0
|
174 {
|
ian@0
|
175 #if defined(BOOST_POSIX_API)
|
ian@0
|
176 ::close(native_);
|
ian@0
|
177 #elif defined(BOOST_WINDOWS_API)
|
ian@0
|
178 CloseHandle(native_);
|
ian@0
|
179 #endif
|
ian@0
|
180 native_ = handle::invalid_handle();
|
ian@0
|
181 }
|
ian@0
|
182 }
|
ian@0
|
183
|
ian@0
|
184 native_type native() const
|
ian@0
|
185 {
|
ian@0
|
186 return native_;
|
ian@0
|
187 }
|
ian@0
|
188
|
ian@0
|
189 native_type release()
|
ian@0
|
190 {
|
ian@0
|
191 native_type native = native_;
|
ian@0
|
192 native_ = handle::invalid_handle();
|
ian@0
|
193 return native;
|
ian@0
|
194 }
|
ian@0
|
195
|
ian@0
|
196 private:
|
ian@0
|
197 native_type native_;
|
ian@0
|
198 close_type close_;
|
ian@0
|
199 };
|
ian@0
|
200
|
ian@0
|
201 /**
|
ian@0
|
202 * Implementation of handle to store native handle value.
|
ian@0
|
203 *
|
ian@0
|
204 * A shared pointer is used as handles represent system resources. If a
|
ian@0
|
205 * handle is closed and becomes invalid the state of copies of the handle
|
ian@0
|
206 * object will be updated as they all share the handle implementation.
|
ian@0
|
207 */
|
ian@0
|
208 boost::shared_ptr<impl> impl_;
|
ian@0
|
209
|
ian@0
|
210 /**
|
ian@0
|
211 * Constant function representing an invalid handle value.
|
ian@0
|
212 *
|
ian@0
|
213 * Returns the platform-specific handle value that represents an
|
ian@0
|
214 * invalid handle. This is a constant function rather than a regular
|
ian@0
|
215 * constant because, in the latter case, we cannot define it under
|
ian@0
|
216 * Windows due to the value being of a complex type.
|
ian@0
|
217 */
|
ian@0
|
218 static const native_type invalid_handle()
|
ian@0
|
219 {
|
ian@0
|
220 #if defined(BOOST_POSIX_API)
|
ian@0
|
221 return -1;
|
ian@0
|
222 #elif defined(BOOST_WINDOWS_API)
|
ian@0
|
223 return INVALID_HANDLE_VALUE;
|
ian@0
|
224 #endif
|
ian@0
|
225 }
|
ian@0
|
226 };
|
ian@0
|
227
|
ian@0
|
228 }
|
ian@0
|
229 }
|
ian@0
|
230
|
ian@0
|
231 #endif
|