ian@0: // ian@0: // Boost.Process ian@0: // ~~~~~~~~~~~~~ ian@0: // ian@0: // Copyright (c) 2006, 2007 Julio M. Merino Vidal ian@0: // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling ian@0: // Copyright (c) 2009 Boris Schaeling ian@0: // Copyright (c) 2010 Felipe Tanus, Boris Schaeling ian@0: // ian@0: // Distributed under the Boost Software License, Version 1.0. (See accompanying ian@0: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ian@0: // ian@0: ian@0: /** ian@0: * \file boost/process/handle.hpp ian@0: * ian@0: * Includes the declaration of the handle class. ian@0: */ ian@0: ian@0: #ifndef BOOST_PROCESS_HANDLE_HPP ian@0: #define BOOST_PROCESS_HANDLE_HPP ian@0: ian@0: #include ian@0: ian@0: #if defined(BOOST_POSIX_API) ian@0: # include ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: # include ian@0: #else ian@0: # error "Unsupported platform." ian@0: #endif ian@0: ian@0: #include ian@0: #include ian@0: ian@0: namespace boost { ian@0: namespace process { ian@0: ian@0: /** ian@0: * RAII model for handles. ian@0: * ian@0: * The \a handle class is a RAII model for native handles. This class wraps ian@0: * one of such handles grabbing its ownership, and automaticaly closes it ian@0: * upon destruction. It is used to avoid leaking open handles, shall an ian@0: * unexpected execution trace occur. ian@0: */ ian@0: class handle ian@0: { ian@0: public: ian@0: #if defined(BOOST_PROCESS_DOXYGEN) ian@0: /** ian@0: * Opaque name for the native handle type. ian@0: * ian@0: * On POSIX systems \a NativeSystemHandle is an integer type while it is ian@0: * a \a HANDLE on Windows systems. ian@0: */ ian@0: typedef NativeSystemHandle native_type; ian@0: #elif defined(BOOST_POSIX_API) ian@0: typedef int native_type; ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: typedef HANDLE native_type; ian@0: #endif ian@0: ian@0: /** ian@0: * Constructs an invalid handle. ian@0: * ian@0: * \see valid() ian@0: */ ian@0: handle() ian@0: { ian@0: } ian@0: ian@0: /** ian@0: * RAII settings to specify if handle should be automatically closed. ian@0: */ ian@0: enum close_type { do_close, dont_close }; ian@0: ian@0: /** ian@0: * Constructs a handle from a native handle. ian@0: * ian@0: * This constructor creates a new \a handle object that takes ian@0: * ownership of the given \a native handle. If \a close is set to ian@0: * handle::dont_close the \a native handle is not closed upon destruction. ian@0: * The user must not close \a native if it is owned by a \a handle object. ian@0: * Ownership can be reclaimed using release(). ian@0: * ian@0: * \see release() ian@0: */ ian@0: handle(native_type native, close_type close = handle::do_close) ian@0: : impl_(boost::make_shared(native, close)) ian@0: { ian@0: } ian@0: ian@0: /** ian@0: * Checks whether the handle is valid or not. ian@0: * ian@0: * \return true if the handle is valid; false otherwise. ian@0: */ ian@0: bool valid() const ian@0: { ian@0: return impl_ && impl_->valid(); ian@0: } ian@0: ian@0: /** ian@0: * Closes the handle. ian@0: * ian@0: * \post The handle is invalid. ian@0: * \post The native handle is closed. ian@0: */ ian@0: void close() ian@0: { ian@0: if (impl_) ian@0: impl_->close(); ian@0: } ian@0: ian@0: /** ian@0: * Gets the native handle. ian@0: * ian@0: * The caller can issue any operation on it except closing it. ian@0: * If closing is required, release() shall be used. ian@0: * ian@0: * \return The native handle. ian@0: */ ian@0: native_type native() const ian@0: { ian@0: return impl_ ? impl_->native() : invalid_handle(); ian@0: } ian@0: ian@0: /** ian@0: * Reclaims ownership of the native handle. ian@0: * ian@0: * The caller is responsible of closing the native handle. ian@0: * ian@0: * \post The handle is invalid. ian@0: * \return The native handle. ian@0: */ ian@0: native_type release() ian@0: { ian@0: return impl_ ? impl_->release() : invalid_handle(); ian@0: } ian@0: ian@0: private: ian@0: class impl ian@0: { ian@0: public: ian@0: typedef handle::native_type native_type; ian@0: ian@0: impl(native_type native, close_type close) ian@0: : native_(native), ian@0: close_(close) ian@0: { ian@0: } ian@0: ian@0: ~impl() ian@0: { ian@0: if (valid() && close_ == handle::do_close) ian@0: { ian@0: #if defined(BOOST_POSIX_API) ian@0: ::close(native_); ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: CloseHandle(native_); ian@0: #endif ian@0: } ian@0: } ian@0: ian@0: bool valid() const ian@0: { ian@0: return native_ != handle::invalid_handle(); ian@0: } ian@0: ian@0: void close() ian@0: { ian@0: if (valid()) ian@0: { ian@0: #if defined(BOOST_POSIX_API) ian@0: ::close(native_); ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: CloseHandle(native_); ian@0: #endif ian@0: native_ = handle::invalid_handle(); ian@0: } ian@0: } ian@0: ian@0: native_type native() const ian@0: { ian@0: return native_; ian@0: } ian@0: ian@0: native_type release() ian@0: { ian@0: native_type native = native_; ian@0: native_ = handle::invalid_handle(); ian@0: return native; ian@0: } ian@0: ian@0: private: ian@0: native_type native_; ian@0: close_type close_; ian@0: }; ian@0: ian@0: /** ian@0: * Implementation of handle to store native handle value. ian@0: * ian@0: * A shared pointer is used as handles represent system resources. If a ian@0: * handle is closed and becomes invalid the state of copies of the handle ian@0: * object will be updated as they all share the handle implementation. ian@0: */ ian@0: boost::shared_ptr impl_; ian@0: ian@0: /** ian@0: * Constant function representing an invalid handle value. ian@0: * ian@0: * Returns the platform-specific handle value that represents an ian@0: * invalid handle. This is a constant function rather than a regular ian@0: * constant because, in the latter case, we cannot define it under ian@0: * Windows due to the value being of a complex type. ian@0: */ ian@0: static const native_type invalid_handle() ian@0: { ian@0: #if defined(BOOST_POSIX_API) ian@0: return -1; ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: return INVALID_HANDLE_VALUE; ian@0: #endif ian@0: } ian@0: }; ian@0: ian@0: } ian@0: } ian@0: ian@0: #endif