|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r64373 - in sandbox/SOC/2010/process: boost/process boost/process/detail libs/process/test
From: boris_at_[hidden]
Date: 2010-07-26 17:54:08
Author: bschaeling
Date: 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
New Revision: 64373
URL: http://svn.boost.org/trac/boost/changeset/64373
Log:
Updated the implementation of file_handle, renamed the class to handle and made it a first-class citizen
Improved implementation of named pipe stream behavior
Added:
sandbox/SOC/2010/process/boost/process/handle.hpp (contents, props changed)
Removed:
sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp
Text files modified:
sandbox/SOC/2010/process/boost/process/all.hpp | 1
sandbox/SOC/2010/process/boost/process/child.hpp | 34 +++---
sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp | 21 ++--
sandbox/SOC/2010/process/boost/process/operations.hpp | 93 ++++++++------------
sandbox/SOC/2010/process/boost/process/pistream.hpp | 44 ++++-----
sandbox/SOC/2010/process/boost/process/postream.hpp | 46 ++++-----
sandbox/SOC/2010/process/boost/process/process.hpp | 34 ++++--
sandbox/SOC/2010/process/boost/process/stream_behavior.hpp | 181 ++++++++++++++++++---------------------
sandbox/SOC/2010/process/libs/process/test/child.cpp | 18 ++-
9 files changed, 222 insertions(+), 250 deletions(-)
Modified: sandbox/SOC/2010/process/boost/process/all.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/all.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/all.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -23,6 +23,7 @@
#include <boost/process/child.hpp>
#include <boost/process/context.hpp>
#include <boost/process/environment.hpp>
+#include <boost/process/handle.hpp>
#include <boost/process/operations.hpp>
#include <boost/process/pid_type.hpp>
#include <boost/process/pipe.hpp>
Modified: sandbox/SOC/2010/process/boost/process/child.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/child.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/child.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -33,7 +33,7 @@
#include <boost/process/pid_type.hpp>
#include <boost/process/pistream.hpp>
#include <boost/process/postream.hpp>
-#include <boost/process/detail/file_handle.hpp>
+#include <boost/process/handle.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/assert.hpp>
@@ -56,16 +56,15 @@
* match the redirections configured by the launcher that spawned this
* process.
*/
- child(pid_type id, detail::file_handle fhstdin,
- detail::file_handle fhstdout, detail::file_handle fhstderr)
+ child(pid_type id, handle hstdin, handle hstdout, handle hstderr)
: process(id)
{
- if (fhstdin.valid())
- stdin_.reset(new postream(fhstdin));
- if (fhstdout.valid())
- stdout_.reset(new pistream(fhstdout));
- if (fhstderr.valid())
- stderr_.reset(new pistream(fhstderr));
+ if (hstdin.valid())
+ stdin_.reset(new postream(hstdin));
+ if (hstdout.valid())
+ stdout_.reset(new pistream(hstdout));
+ if (hstderr.valid())
+ stderr_.reset(new pistream(hstderr));
}
#if defined(BOOST_WINDOWS_API)
@@ -81,16 +80,15 @@
*
* This operation is only available on Windows systems.
*/
- child(HANDLE handle, detail::file_handle fhstdin,
- detail::file_handle fhstdout, detail::file_handle fhstderr)
- : process(handle)
+ child(handle hprocess, handle hstdin, handle hstdout, handle hstderr)
+ : process(hprocess)
{
- if (fhstdin.valid())
- stdin_.reset(new postream(fhstdin));
- if (fhstdout.valid())
- stdout_.reset(new pistream(fhstdout));
- if (fhstderr.valid())
- stderr_.reset(new pistream(fhstderr));
+ if (hstdin.valid())
+ stdin_.reset(new postream(hstdin));
+ if (hstdout.valid())
+ stdout_.reset(new pistream(hstdout));
+ if (hstderr.valid())
+ stderr_.reset(new pistream(hstderr));
}
#endif
Deleted: sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
+++ (empty file)
@@ -1,288 +0,0 @@
-//
-// Boost.Process
-// ~~~~~~~~~~~~~
-//
-// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
-// Copyright (c) 2009 Boris Schaeling
-// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-/**
- * \file boost/process/detail/file_handle.hpp
- *
- * Includes the declaration of the file_handle class.
- */
-
-#ifndef BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP
-#define BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP
-
-#include <boost/process/config.hpp>
-
-#if defined(BOOST_POSIX_API)
-# include <cerrno>
-# include <unistd.h>
-#elif defined(BOOST_WINDOWS_API)
-# include <windows.h>
-#else
-# error "Unsupported platform."
-#endif
-
-#include <boost/assert.hpp>
-
-namespace boost {
-namespace process {
-namespace detail {
-
-/**
- * Simple RAII model for system file handles.
- *
- * The \a file_handle class is a simple RAII model for native system file
- * handles. This class wraps one of such handles grabbing its ownership,
- * and automaticaly closes it upon destruction. It is basically used
- * inside the library to avoid leaking open file handles, shall an
- * unexpected execution trace occur.
- *
- * A \a file_handle object can be copied but doing so invalidates the
- * source object. There can only be a single valid \a file_handle object
- * for a given system file handle. This is similar to std::auto_ptr's
- * semantics.
- *
- * This class also provides some convenience methods to issue special file
- * operations under their respective platforms.
- */
-class file_handle
-{
-public:
-#if defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Opaque name for the native handle type.
- *
- * Each operating system identifies file handles using a specific type.
- * The \a handle_type type is used to transparently refer to file
- * handles regarless of the operating system in which this class is
- * used.
- *
- * If this class is used on a POSIX system, \a NativeSystemHandle is
- * an integer type while it is a \a HANDLE on a Windows system.
- */
- typedef NativeSystemHandle handle_type;
-#elif defined(BOOST_POSIX_API)
- typedef int handle_type;
-#elif defined(BOOST_WINDOWS_API)
- typedef HANDLE handle_type;
-#endif
-
- /**
- * Constructs an invalid file handle.
- *
- * This constructor creates a new \a file_handle object that represents
- * an invalid file handle. An invalid file handle can be copied but
- * cannot be manipulated in any way (except checking for its validity).
- *
- * \see valid()
- */
- file_handle()
- : handle_(invalid_value())
- {
- }
-
- /**
- * Constructs a new file handle from a native file handle.
- *
- * This constructor creates a new \a file_handle object that takes
- * ownership of the given \a h native file handle. The user must not
- * close \a h on his own during the lifetime of the new object.
- * Ownership can be reclaimed using release().
- *
- * \pre The native file handle must be valid; a close operation must
- * succeed on it.
- * \see release()
- */
- file_handle(handle_type h)
- : handle_(h)
- {
- // Boris: I wonder why this assert existed before (also in
- // previous Boost.Process versions).
- // BOOST_ASSERT(handle_ != invalid_value());
- }
-
- /**
- * Copy constructor; invalidates the source handle.
- *
- * This copy constructor creates a new file handle from a given one.
- * Ownership of the native file handle is transferred to the new
- * object, effectively invalidating the source file handle. This
- * avoids having two live \a file_handle objects referring to the
- * same native file handle. The source file handle needs not be
- * valid in the name of simplicity.
- *
- * \post The source file handle is invalid.
- * \post The new file handle owns the source's native file handle.
- */
- file_handle(const file_handle &fh)
- : handle_(fh.handle_)
- {
- fh.handle_ = invalid_value();
- }
-
- /**
- * Releases resources if the handle is valid.
- *
- * If the file handle is valid, the destructor closes it.
- *
- * \see valid()
- */
- ~file_handle()
- {
- if (valid())
- close();
- }
-
- /**
- * Assignment operator; invalidates the source handle.
- *
- * This assignment operator transfers ownership of the RHS file
- * handle to the LHS one, effectively invalidating the source file
- * handle. This avoids having two live \a file_handle objects
- * referring to the same native file handle. The source file
- * handle needs not be valid in the name of simplicity.
- *
- * \post The RHS file handle is invalid.
- * \post The LHS file handle owns RHS' native file handle.
- * \return A reference to the LHS file handle.
- */
- file_handle &operator=(const file_handle &fh)
- {
- handle_ = fh.handle_;
- fh.handle_ = invalid_value();
- return *this;
- }
-
- /**
- * Checks whether the file handle is valid or not.
- *
- * Returns a boolean indicating whether the file handle is valid or
- * not. If the file handle is invalid, no other methods can be
- * executed other than the destructor.
- *
- * \return true if the file handle is valid; false otherwise.
- */
- bool valid()
- {
- return handle_ != invalid_value();
- }
-
- /**
- * Reclaims ownership of the native file handle.
- *
- * Explicitly reclaims ownership of the native file handle contained
- * in the \a file_handle object, returning the native file handle.
- * The caller is responsible of closing it later on.
- *
- * \pre The file handle is valid.
- * \post The file handle is invalid.
- * \return The native file handle.
- */
- handle_type release()
- {
- BOOST_ASSERT(valid());
-
- handle_type h = handle_;
- handle_ = invalid_value();
- return h;
- }
-
- /**
- * Gets the native file handle.
- *
- * Returns the native file handle for the \a file_handle object.
- * The caller can issue any operation on it except closing it.
- * If closing is required, release() shall be used.
- *
- * \pre The file handle is valid.
- * \post The file handle is valid.
- * \return The native file handle.
- */
- handle_type get()
- {
- BOOST_ASSERT(valid());
-
- return handle_;
- }
-
-#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Closes the file handle.
- *
- * Explicitly closes the file handle, which must be valid. Upon
- * exit, the handle is not valid any more.
- *
- * \pre The file handle is valid.
- * \post The file handle is invalid.
- * \post The native file handle is closed.
- */
- void close()
- {
- BOOST_ASSERT(valid());
- ::close(handle_);
- handle_ = invalid_value();
- }
-#endif
-
-#if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Closes the file handle.
- *
- * Explicitly closes the file handle, which must be valid. Upon
- * exit, the handle is not valid any more.
- *
- * \pre The file handle is valid.
- * \post The file handle is invalid.
- * \post The native file handle is closed.
- */
- void close()
- {
- BOOST_ASSERT(valid());
- ::CloseHandle(handle_);
- handle_ = invalid_value();
- }
-#endif
-
-private:
- /**
- * Internal handle value.
- *
- * This variable holds the native handle value for the file handle
- * hold by this object. It is interesting to note that this needs
- * to be mutable because the copy constructor and the assignment
- * operator invalidate the source object.
- */
- mutable handle_type handle_;
-
- /**
- * Constant function representing an invalid handle value.
- *
- * Returns the platform-specific handle value that represents an
- * invalid handle. This is a constant function rather than a regular
- * constant because, in the latter case, we cannot define it under
- * Windows due to the value being of a complex type.
- */
- static const handle_type invalid_value()
- {
-#if defined(BOOST_POSIX_API)
- return -1;
-#elif defined(BOOST_WINDOWS_API)
- return INVALID_HANDLE_VALUE;
-#endif
- }
-};
-
-}
-}
-}
-
-#endif
Modified: sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -45,11 +45,11 @@
namespace detail {
/**
- * std::streambuf implementation for system file handles.
+ * std::streambuf implementation for handles.
*
- * systembuf provides a std::streambuf implementation for system file
- * handles. Contrarywise to file_handle, this class does \b not take
- * ownership of the native file handle; this should be taken care of
+ * systembuf provides a std::streambuf implementation for handles.
+ * Contrarywise to the handle class, this class does \b not take
+ * ownership of the native handle; this should be taken care of
* somewhere else.
*
* This class follows the expected semantics of a std::streambuf object.
@@ -73,10 +73,10 @@
#endif
/**
- * Constructs a new systembuf for the given file handle.
+ * Constructs a new systembuf for the given handle.
*
* This constructor creates a new systembuf object that reads or
- * writes data from/to the \a h native file handle. This handle
+ * writes data from/to the \a h native handle. This handle
* is \b not owned by the created systembuf object; the code
* should take care of it externally.
*
@@ -103,7 +103,7 @@
protected:
/**
- * Reads new data from the native file handle.
+ * Reads new data from the native handle.
*
* This operation is called by input methods when there is no more
* data in the input buffer. The function fills the buffer with new
@@ -174,9 +174,8 @@
* Flushes the output buffer to disk.
*
* Synchronizes the systembuf buffers with the contents of the file
- * associated to this object through the native file handle. The
- * output buffer is flushed to disk and cleared to leave new room
- * for more data.
+ * associated to this object through the native handle. The output buffer
+ * is flushed to disk and cleared to leave new room for more data.
*
* \returns 0 on success, -1 if an error occurred.
*/
@@ -201,7 +200,7 @@
private:
/**
- * Native file handle used by the systembuf object.
+ * Native handle used by the systembuf object.
*/
handle_type handle_;
Added: sandbox/SOC/2010/process/boost/process/handle.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/handle.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -0,0 +1,223 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * \file boost/process/handle.hpp
+ *
+ * Includes the declaration of the handle class.
+ */
+
+#ifndef BOOST_PROCESS_HANDLE_HPP
+#define BOOST_PROCESS_HANDLE_HPP
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+# include <unistd.h>
+#elif defined(BOOST_WINDOWS_API)
+# include <windows.h>
+#else
+# error "Unsupported platform."
+#endif
+
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+
+namespace boost {
+namespace process {
+
+/**
+ * RAII model for handles.
+ *
+ * The \a handle class is a RAII model for native handles. This class wraps
+ * one of such handles grabbing its ownership, and automaticaly closes it
+ * upon destruction. It is basically used inside the library to avoid leaking
+ * open handles, shall an unexpected execution trace occur.
+ */
+class handle
+{
+public:
+#if defined(BOOST_PROCESS_DOXYGEN)
+ /**
+ * Opaque name for the native handle type.
+ *
+ * On POSIX systems \a NativeSystemHandle is an integer type while it is
+ * a \a HANDLE on Windows systems.
+ */
+ typedef NativeSystemHandle native_type;
+#elif defined(BOOST_POSIX_API)
+ typedef int native_type;
+#elif defined(BOOST_WINDOWS_API)
+ typedef HANDLE native_type;
+#endif
+
+ /**
+ * Constructs an invalid handle.
+ *
+ * \see valid()
+ */
+ handle()
+ {
+ }
+
+ /**
+ * Constructs a handle from a native handle.
+ *
+ * This constructor creates a new \a handle object that takes
+ * ownership of the given \a h native handle. The user must not
+ * close \a native on his own during the lifetime of the new object.
+ * Ownership can be reclaimed using release().
+ *
+ * \see release()
+ */
+ handle(native_type native)
+ : impl_(boost::make_shared<impl>(native))
+ {
+ }
+
+ /**
+ * Checks whether the handle is valid or not.
+ *
+ * \return true if the handle is valid; false otherwise.
+ */
+ bool valid() const
+ {
+ return impl_ && impl_->valid();
+ }
+
+ /**
+ * Closes the handle.
+ *
+ * \post The handle is invalid.
+ * \post The native handle is closed.
+ */
+ void close()
+ {
+ if (impl_)
+ impl_->close();
+ }
+
+ /**
+ * Gets the native handle.
+ *
+ * The caller can issue any operation on it except closing it.
+ * If closing is required, release() shall be used.
+ *
+ * \return The native handle.
+ */
+ native_type native() const
+ {
+ return impl_ ? impl_->native() : invalid_handle();
+ }
+
+ /**
+ * Reclaims ownership of the native handle.
+ *
+ * The caller is responsible of closing the native handle.
+ *
+ * \post The handle is invalid.
+ * \return The native handle.
+ */
+ native_type release()
+ {
+ return impl_ ? impl_->release() : invalid_handle();
+ }
+
+private:
+ class impl
+ {
+ public:
+ typedef handle::native_type native_type;
+
+ impl(native_type native)
+ : native_(native)
+ {
+ }
+
+ ~impl()
+ {
+ if (valid())
+ {
+#if defined(BOOST_POSIX_API)
+ close(native_);
+#elif defined(BOOST_WINDOWS_API)
+ CloseHandle(native_);
+#endif
+ }
+ }
+
+ bool valid() const
+ {
+ return native_ != handle::invalid_handle();
+ }
+
+ void close()
+ {
+ if (valid())
+ {
+#if defined(BOOST_POSIX_API)
+ close(native_);
+#elif defined(BOOST_WINDOWS_API)
+ CloseHandle(native_);
+#endif
+ native_ = handle::invalid_handle();
+ }
+ }
+
+ native_type native() const
+ {
+ return native_;
+ }
+
+ native_type release()
+ {
+ native_type native = native_;
+ native_ = handle::invalid_handle();
+ return native;
+ }
+
+ private:
+ native_type native_;
+ };
+
+ /**
+ * Implementation of handle to store native handle value.
+ *
+ * A shared pointer is used as handles represent system resources. If a
+ * handle is closed and becomes invalid the state of copies of the handle
+ * object will be updated as they all share the handle implementation.
+ */
+ boost::shared_ptr<impl> impl_;
+
+ /**
+ * Constant function representing an invalid handle value.
+ *
+ * Returns the platform-specific handle value that represents an
+ * invalid handle. This is a constant function rather than a regular
+ * constant because, in the latter case, we cannot define it under
+ * Windows due to the value being of a complex type.
+ */
+ static const native_type invalid_handle()
+ {
+#if defined(BOOST_POSIX_API)
+ return -1;
+#elif defined(BOOST_WINDOWS_API)
+ return INVALID_HANDLE_VALUE;
+#endif
+ }
+};
+
+}
+}
+
+#endif
Modified: sandbox/SOC/2010/process/boost/process/operations.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/operations.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/operations.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -43,7 +43,7 @@
#include <boost/process/child.hpp>
#include <boost/process/context.hpp>
-#include <boost/process/detail/file_handle.hpp>
+#include <boost/process/handle.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/system/system_error.hpp>
@@ -66,7 +66,8 @@
* \throw boost::filesystem::filesystem_error If the file cannot be found
* in the path.
*/
-inline std::string find_executable_in_path(const std::string &file, std::string path = "")
+inline std::string find_executable_in_path(const std::string &file,
+ std::string path = "")
{
#if defined(BOOST_POSIX_API)
BOOST_ASSERT(file.find('/') == std::string::npos);
@@ -181,7 +182,8 @@
* \return A handle to the new child process.
*/
template <typename Arguments, typename Context>
-inline child create_child(const std::string &executable, Arguments args, Context ctx)
+inline child create_child(const std::string &executable, Arguments args,
+ Context ctx)
{
#if !defined(NDEBUG)
BOOST_ASSERT(ctx.stdin_behavior.get());
@@ -216,10 +218,10 @@
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("fork(2) failed");
else if (pid == 0)
{
- int stdin_fd = ctx.stdin_behavior->get_child_end();
- if (stdin_fd != -1)
+ handle hstdin = ctx.stdin_behavior->get_child_end();
+ if (hstdin.valid())
{
- if (dup2(stdin_fd, STDIN_FILENO) == -1)
+ if (dup2(hstdin.native(), STDIN_FILENO) == -1)
{
write(STDERR_FILENO, "dup2() failed\n", 14);
_exit(127);
@@ -227,10 +229,10 @@
closeflags[STDIN_FILENO] = false;
}
- int stdout_fd = ctx.stdout_behavior->get_child_end();
- if (stdout_fd != -1)
+ handle hstdout = ctx.stdout_behavior->get_child_end();
+ if (hstdout.valid())
{
- if (dup2(stdout_fd, STDOUT_FILENO) == -1)
+ if (dup2(hstdout.native(), STDOUT_FILENO) == -1)
{
write(STDERR_FILENO, "dup2() failed\n", 14);
_exit(127);
@@ -238,10 +240,10 @@
closeflags[STDOUT_FILENO] = false;
}
- int stderr_fd = ctx.stderr_behavior->get_child_end();
- if (stderr_fd != -1)
+ handle hstderr = ctx.stderr_behavior->get_child_end();
+ if (hstderr.valid())
{
- if (dup2(stderr_fd, STDERR_FILENO) == -1)
+ if (dup2(hstderr.native(), STDERR_FILENO) == -1)
{
write(STDERR_FILENO, "dup2() failed\n", 14);
_exit(127);
@@ -274,33 +276,23 @@
{
BOOST_ASSERT(pid > 0);
- if (ctx.stdin_behavior->get_child_end() != -1)
- close(ctx.stdin_behavior->get_child_end());
- if (ctx.stdout_behavior->get_child_end() != -1)
- close(ctx.stdout_behavior->get_child_end());
- if (ctx.stderr_behavior->get_child_end() != -1)
- close(ctx.stderr_behavior->get_child_end());
-
- detail::file_handle fhin(ctx.stdin_behavior->get_parent_end());
- detail::file_handle fhout(ctx.stdout_behavior->get_parent_end());
- detail::file_handle fherr(ctx.stderr_behavior->get_parent_end());
-
-#if !defined(NDEBUG)
- ctx.stdin_behavior.reset();
- ctx.stdout_behavior.reset();
- ctx.stderr_behavior.reset();
-#endif
-
- return child(pid, fhin, fhout, fherr);
+ ctx.stdin_behavior->get_child_end().close();
+ ctx.stdout_behavior->get_child_end().close();
+ ctx.stderr_behavior->get_child_end().close();
+
+ return child(pid,
+ ctx.stdin_behavior->get_parent_end(),
+ ctx.stdout_behavior->get_parent_end(),
+ ctx.stderr_behavior->get_parent_end());
}
#elif defined(BOOST_WINDOWS_API)
STARTUPINFOA startup_info;
ZeroMemory(&startup_info, sizeof(startup_info));
startup_info.cb = sizeof(startup_info);
startup_info.dwFlags |= STARTF_USESTDHANDLES;
- startup_info.hStdInput = ctx.stdin_behavior->get_child_end();
- startup_info.hStdOutput = ctx.stdout_behavior->get_child_end();
- startup_info.hStdError = ctx.stderr_behavior->get_child_end();
+ startup_info.hStdInput = ctx.stdin_behavior->get_child_end().native();
+ startup_info.hStdOutput = ctx.stdout_behavior->get_child_end().native();
+ startup_info.hStdError = ctx.stderr_behavior->get_child_end().native();
ctx.setup(startup_info);
@@ -323,28 +315,19 @@
envstrs.get(), workdir.get(), &startup_info, &pi) == 0)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed");
- // Don't throw an exception if CloseHandle() fails as we would
- // leak the process handle in pi.hProcess.
- CloseHandle(pi.hThread);
-
- if (ctx.stdin_behavior->get_child_end() != INVALID_HANDLE_VALUE)
- CloseHandle(ctx.stdin_behavior->get_child_end());
- if (ctx.stdout_behavior->get_child_end() != INVALID_HANDLE_VALUE)
- CloseHandle(ctx.stdout_behavior->get_child_end());
- if (ctx.stderr_behavior->get_child_end() != INVALID_HANDLE_VALUE)
- CloseHandle(ctx.stderr_behavior->get_child_end());
-
- detail::file_handle fhin(ctx.stdin_behavior->get_parent_end());
- detail::file_handle fhout(ctx.stdout_behavior->get_parent_end());
- detail::file_handle fherr(ctx.stderr_behavior->get_parent_end());
-
-#if !defined(NDEBUG)
- ctx.stdin_behavior.reset();
- ctx.stdout_behavior.reset();
- ctx.stderr_behavior.reset();
-#endif
-
- return child(pi.hProcess, fhin, fhout, fherr);
+ ctx.stdin_behavior->get_child_end().close();
+ ctx.stdout_behavior->get_child_end().close();
+ ctx.stderr_behavior->get_child_end().close();
+
+ handle hprocess(pi.hProcess);
+
+ if (CloseHandle(pi.hThread) == 0)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
+
+ return child(hprocess,
+ ctx.stdin_behavior->get_parent_end(),
+ ctx.stdout_behavior->get_parent_end(),
+ ctx.stderr_behavior->get_parent_end());
#endif
}
Modified: sandbox/SOC/2010/process/boost/process/pistream.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/pistream.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/pistream.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -20,7 +20,7 @@
#ifndef BOOST_PROCESS_PISTREAM_HPP
#define BOOST_PROCESS_PISTREAM_HPP
-#include <boost/process/detail/file_handle.hpp>
+#include <boost/process/handle.hpp>
#include <boost/process/detail/systembuf.hpp>
#include <boost/noncopyable.hpp>
#include <istream>
@@ -38,8 +38,7 @@
* output one, but from the parent's point of view it is an input one;
* hence the confusing pistream name.
*
- * pistream objects cannot be copied because they own the file handle
- * they use to communicate with the child and because they buffer data
+ * pistream objects cannot be copied because they buffer data
* that flows through the communication channel.
*
* A pistream object behaves as a std::istream stream in all senses.
@@ -47,7 +46,7 @@
* the caller explicitly close the communication channel.
*
* \remark Blocking remarks: Functions that read data from this
- * stream can block if the associated file handle blocks during
+ * stream can block if the associated handle blocks during
* the read. As this class is used to communicate with child
* processes through anonymous pipes, the most typical blocking
* condition happens when the child has no more data to send to
@@ -60,38 +59,35 @@
public:
/**
* Creates a new process' output stream.
- *
- * Given a file handle, this constructor creates a new pistream
- * object that owns the given file handle \a fh. Ownership of
- * \a fh is transferred to the created pistream object.
- *
- * \pre \a fh is valid.
- * \post \a fh is invalid.
- * \post The new pistream object owns \a fh.
*/
- explicit pistream(detail::file_handle &fh)
+ explicit pistream(boost::process::handle &h)
: std::istream(0),
- handle_(fh),
- systembuf_(handle_.get())
+ handle_(h),
+ systembuf_(handle_.native())
{
rdbuf(&systembuf_);
}
/**
- * Returns the file handle managed by this stream.
- *
- * The file handle must not be copied. Copying invalidates
- * the source file handle making the pistream unusable.
+ * Returns the handle managed by this stream.
+ */
+ const boost::process::handle &handle() const
+ {
+ return handle_;
+ }
+
+ /**
+ * Returns the handle managed by this stream.
*/
- detail::file_handle &native()
+ boost::process::handle &handle()
{
return handle_;
}
/**
- * Closes the file handle managed by this stream.
+ * Closes the handle managed by this stream.
*
- * Explicitly closes the file handle managed by this stream. This
+ * Explicitly closes the handle managed by this stream. This
* function can be used by the user to tell the child process it's
* not willing to receive more data.
*/
@@ -102,9 +98,9 @@
private:
/**
- * The file handle managed by this stream.
+ * The handle managed by this stream.
*/
- detail::file_handle handle_;
+ boost::process::handle handle_;
/**
* The systembuf object used to manage this stream's data.
Modified: sandbox/SOC/2010/process/boost/process/postream.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/postream.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/postream.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -20,7 +20,7 @@
#ifndef BOOST_PROCESS_POSTREAM_HPP
#define BOOST_PROCESS_POSTREAM_HPP
-#include <boost/process/detail/file_handle.hpp>
+#include <boost/process/handle.hpp>
#include <boost/process/detail/systembuf.hpp>
#include <boost/noncopyable.hpp>
#include <ostream>
@@ -38,16 +38,15 @@
* input one, but from the parent's point of view it is an output one;
* hence the confusing postream name.
*
- * postream objects cannot be copied because they own the file handle
- * they use to communicate with the child and because they buffer data
- * that flows through the communication channel.
+ * postream objects cannot be copied because they buffer data that flows
+ * through the communication channel.
*
* A postream object behaves as a std::ostream stream in all senses.
* The class is only provided because it must provide a method to let
* the caller explicitly close the communication channel.
*
* \remark Blocking remarks: Functions that write data to this
- * stream can block if the associated file handle blocks during
+ * stream can block if the associated handle blocks during
* the write. As this class is used to communicate with child
* processes through anonymous pipes, the most typical blocking
* condition happens when the child is not processing the data
@@ -60,38 +59,35 @@
public:
/**
* Creates a new process' input stream.
- *
- * Given a file handle, this constructor creates a new postream
- * object that owns the given file handle \a fh. Ownership of
- * \a fh is transferred to the created postream object.
- *
- * \pre \a fh is valid.
- * \post \a fh is invalid.
- * \post The new postream object owns \a fh.
*/
- explicit postream(detail::file_handle &fh)
+ explicit postream(boost::process::handle &h)
: std::ostream(0),
- handle_(fh),
- systembuf_(handle_.get())
+ handle_(h),
+ systembuf_(handle_.native())
{
rdbuf(&systembuf_);
}
/**
- * Returns the file handle managed by this stream.
- *
- * The file handle must not be copied. Copying invalidates
- * the source file handle making the postream unusable.
+ * Returns the handle managed by this stream.
+ */
+ const boost::process::handle &handle() const
+ {
+ return handle_;
+ }
+
+ /**
+ * Returns the handle managed by this stream.
*/
- detail::file_handle &native()
+ boost::process::handle &handle()
{
return handle_;
}
/**
- * Closes the file handle managed by this stream.
+ * Closes the handle managed by this stream.
*
- * Explicitly closes the file handle managed by this stream. This
+ * Explicitly closes the handle managed by this stream. This
* function can be used by the user to tell the child process there
* is no more data to send.
*/
@@ -103,9 +99,9 @@
private:
/**
- * The file handle managed by this stream.
+ * The handle managed by this stream.
*/
- detail::file_handle handle_;
+ boost::process::handle handle_;
/**
* The systembuf object used to manage this stream's data.
Modified: sandbox/SOC/2010/process/boost/process/process.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/process.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/process.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -28,6 +28,7 @@
# include <signal.h>
# include <sys/wait.h>
#elif defined(BOOST_WINDOWS_API)
+# include <boost/process/handle.hpp>
# include <boost/shared_ptr.hpp>
# include <cstdlib>
# include <windows.h>
@@ -60,13 +61,9 @@
process(pid_type id)
: id_(id)
#if defined(BOOST_WINDOWS_API)
- , handle_(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id), CloseHandle)
+ , handle_(open_process(id))
#endif
{
-#if defined(BOOST_WINDOWS_API)
- if (handle_ == NULL)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
-#endif
}
#if defined(BOOST_WINDOWS_API)
@@ -79,9 +76,9 @@
* This operation is only available on Windows systems. The handle is
* closed when the process instance (and all of its copies) is destroyed.
*/
- process(HANDLE handle)
- : id_(GetProcessId(handle)),
- handle_(handle, CloseHandle)
+ process(handle h)
+ : id_(GetProcessId(h.native())),
+ handle_(h)
{
}
#endif
@@ -180,13 +177,24 @@
#if defined(BOOST_WINDOWS_API)
/**
- * The process handle.
+ * Opens a process and returns a handle.
*
- * The process handle is saved in a shared pointer to guarantee that it
- * is closed when not needed anymore. The handle guarantees that Windows
- * does not remove process resources when a process exits.
+ * OpenProcess() returns NULL and not INVALID_HANDLE_VALUE on failure.
+ * That's why the return value is manually checked in this helper function
+ * instead of simply passing it to the constructor of the handle class.
+ */
+ HANDLE open_process(pid_type id)
+ {
+ HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id);
+ if (h == NULL)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
+ return h;
+ }
+
+ /**
+ * The process handle.
*/
- boost::shared_ptr<void> handle_;
+ handle handle_;
#endif
};
Modified: sandbox/SOC/2010/process/boost/process/stream_behavior.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/stream_behavior.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/stream_behavior.hpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -28,13 +28,18 @@
# include <fcntl.h>
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
-# include <boost/lexical_cast.hpp>
-# include <string>
# include <windows.h>
#endif
+#include <boost/process/handle.hpp>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/random_generator.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
+#include <string>
+#include <algorithm>
namespace boost {
namespace process {
@@ -50,23 +55,6 @@
{
public:
/**
- * Opaque identifier for a stream's end.
- *
- * Each operating system identifies streams' ends using a specific type.
- * The \a stream_end_type type is used to transparently refer to a stream's
- * end regardless of the operating system in which this class is used.
- *
- * On POSIX systems it is defined as int, on Windows systems as HANDLE.
- */
-#if defined(BOOST_PROCESS_DOXYGEN)
- typedef NativeStreamType stream_end_type;
-#elif defined(BOOST_POSIX_API)
- typedef int stream_end_type;
-#elif defined(BOOST_WINDOWS_API)
- typedef HANDLE stream_end_type;
-#endif
-
- /**
* Factory function to create a stream behavior object.
*
* Returns a shared pointer to the stream behavior object as this is
@@ -81,25 +69,17 @@
/**
* Returns the child's end of the stream.
*/
- virtual stream_end_type get_child_end()
+ virtual handle get_child_end()
{
-#if defined(BOOST_POSIX_API)
- return -1;
-#elif defined(BOOST_WINDOWS_API)
- return INVALID_HANDLE_VALUE;
-#endif
+ return handle();
}
/**
* Returns the parent's end of the stream.
*/
- virtual stream_end_type get_parent_end()
+ virtual handle get_parent_end()
{
-#if defined(BOOST_POSIX_API)
- return -1;
-#elif defined(BOOST_WINDOWS_API)
- return INVALID_HANDLE_VALUE;
-#endif
+ return handle();
}
};
@@ -118,32 +98,33 @@
class inherit : public stream
{
public:
- inherit(stream_end_type child_end)
- : child_end_(child_end)
+ inherit(handle::native_type child_end)
{
#if defined(BOOST_POSIX_API)
child_end_ = dup(child_end);
- if (child_end_ == -1)
+ if (!child_end_.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup(2) failed");
#elif defined(BOOST_WINDOWS_API)
- if (!DuplicateHandle(GetCurrentProcess(), child_end_,
- GetCurrentProcess(), &child_end_, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ HANDLE h;
+ if (!DuplicateHandle(GetCurrentProcess(), child_end,
+ GetCurrentProcess(), &h, 0, TRUE, DUPLICATE_SAME_ACCESS))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("DuplicateHandle() failed");
+ child_end_ = h;
#endif
}
- static boost::shared_ptr<inherit> def(stream_end_type child_end)
+ static boost::shared_ptr<inherit> def(handle::native_type child_end)
{
return boost::make_shared<inherit>(inherit(child_end));
}
- stream_end_type get_child_end()
+ handle get_child_end()
{
return child_end_;
}
private:
- stream_end_type child_end_;
+ handle child_end_;
};
/**
@@ -158,7 +139,7 @@
pipe(stream_type stream)
{
- stream_end_type ends[2];
+ handle::native_type ends[2];
#if defined(BOOST_POSIX_API)
if (::pipe(ends) == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pipe(2) failed");
@@ -174,7 +155,7 @@
child_end_ = ends[(stream == input_stream) ? 0 : 1];
parent_end_ = ends[(stream == input_stream) ? 1 : 0];
#if defined(BOOST_WINDOWS_API)
- if (!SetHandleInformation(child_end_, HANDLE_FLAG_INHERIT,
+ if (!SetHandleInformation(child_end_.native(), HANDLE_FLAG_INHERIT,
HANDLE_FLAG_INHERIT))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
"SetHandleInformation() failed");
@@ -186,19 +167,19 @@
return boost::make_shared<pipe>(pipe(stream));
}
- stream_end_type get_child_end()
+ handle get_child_end()
{
return child_end_;
}
- stream_end_type get_parent_end()
+ handle get_parent_end()
{
return parent_end_;
}
private:
- stream_end_type child_end_;
- stream_end_type parent_end_;
+ handle child_end_;
+ handle parent_end_;
};
/**
@@ -213,54 +194,55 @@
public:
enum stream_type { input_stream, output_stream };
- named_pipe(stream_type stream, std::string name = "")
+ named_pipe(stream_type stream, std::string *name = 0)
{
- stream_end_type ends[2];
#if defined(BOOST_POSIX_API)
- if (name.empty())
- // TODO: Generate unique filename.
- name = "/tmp/fifo.1";
-
- // TODO: Use RAII to close HANDLEs if an exception is thrown.
- if (mkfifo(name.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("mkfifo(3) failed");
- if (stream == input_stream)
- {
- child_end_ = open(name.c_str(), O_RDONLY);
- if (child_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- parent_end_ = open(name.c_str(), O_WRONLY);
- if (parent_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- }
+ std::string s;
+ if (name && !name->empty())
+ s = *name;
else
{
- child_end_ = open(name.c_str(), O_WRONLY);
- if (child_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- parent_end_ = open(name.c_str(), O_RDONLY);
- if (parent_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
+ boost::uuids::random_generator gen;
+ boost::uuids::uuid u = gen();
+ s = "/tmp/boost_process_" + boost::lexical_cast<std::string>(u);
+ if (name)
+ *name = s;
}
+
+ if (mkfifo(s.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("mkfifo(3) failed");
+ child_end_ = open(s.c_str(), O_RDONLY);
+ if (!child_end_.valid())
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
+ parent_end_ = open(s.c_str(), O_WRONLY);
+ if (!parent_end_.valid())
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
#elif defined(BOOST_WINDOWS_API)
- if (name.empty())
+ std::string s;
+ if (name && !name->empty())
+ s = *name;
+ else
{
- // TODO: Make this thread-safe (create unique filename differently).
- static unsigned int nextid = 0;
- name = "\\\\.\\pipe\\boost_process_" + boost::lexical_cast<std::string>(::GetCurrentProcessId()) + "_" + boost::lexical_cast<std::string>(nextid++);
+ boost::uuids::random_generator gen;
+ boost::uuids::uuid u = gen();
+ s = "\\\\.\\pipe\\boost_process_" +
+ boost::lexical_cast<std::string>(u);
+ if (name)
+ *name = s;
}
- // TODO: Use RAII to close HANDLEs if an exception is thrown.
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
- ends[0] = CreateNamedPipeA(name.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa);
- if (ends[0] == INVALID_HANDLE_VALUE)
+ child_end_ = CreateNamedPipeA(s.c_str(), PIPE_ACCESS_INBOUND |
+ FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa);
+ if (!child_end_.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateNamedPipe() failed");
- ends[1] = ::CreateFileA(name.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (ends[1] == INVALID_HANDLE_VALUE)
+ parent_end_ = CreateFileA(s.c_str(), GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ if (!parent_end_.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
OVERLAPPED overlapped;
@@ -268,30 +250,35 @@
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!overlapped.hEvent)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateEvent() failed");
- BOOL b = ConnectNamedPipe(ends[0], &overlapped);
+ BOOL b = ConnectNamedPipe(child_end_.native(), &overlapped);
if (!b)
{
if (GetLastError() == ERROR_IO_PENDING)
{
- if (WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_FAILED)
+ if (WaitForSingleObject(overlapped.hEvent, INFINITE) ==
+ WAIT_FAILED)
{
CloseHandle(overlapped.hEvent);
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("WaitForSingleObject() failed");
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
+ "WaitForSingleObject() failed");
}
}
else if (GetLastError() != ERROR_PIPE_CONNECTED)
{
CloseHandle(overlapped.hEvent);
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("ConnectNamedPipe() failed");
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
+ "ConnectNamedPipe() failed");
}
}
CloseHandle(overlapped.hEvent);
#endif
- child_end_ = ends[(stream == input_stream) ? 0 : 1];
- parent_end_ = ends[(stream == input_stream) ? 1 : 0];
+ if (stream == output_stream)
+ std::swap(child_end_, parent_end_);
#if defined(BOOST_WINDOWS_API)
- if (!SetHandleInformation(child_end_, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("SetHandleInformation() failed");
+ if (!SetHandleInformation(child_end_.native(), HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
+ "SetHandleInformation() failed");
#endif
}
@@ -300,19 +287,19 @@
return boost::make_shared<named_pipe>(named_pipe(stream));
}
- stream_end_type get_child_end()
+ handle get_child_end()
{
return child_end_;
}
- stream_end_type get_parent_end()
+ handle get_parent_end()
{
return parent_end_;
}
private:
- stream_end_type child_end_;
- stream_end_type parent_end_;
+ handle child_end_;
+ handle parent_end_;
};
/**
@@ -329,14 +316,16 @@
dummy(stream_type stream)
{
#if defined(BOOST_POSIX_API)
- std::string filename = (stream == input_stream) ? "/dev/zero" : "/dev/null";
+ std::string filename = (stream == input_stream) ? "/dev/zero" :
+ "/dev/null";
child_end_ = open(filename.c_str(), O_RDONLY);
- if (child_end_ == -1)
+ if (!child_end_.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
#elif defined(BOOST_WINDOWS_API)
DWORD access = (stream == input_stream) ? GENERIC_READ : GENERIC_WRITE;
- child_end_ = CreateFileA("NUL", access, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (child_end_ == INVALID_HANDLE_VALUE)
+ child_end_ = CreateFileA("NUL", access, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (!child_end_.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
#endif
}
@@ -346,13 +335,13 @@
return boost::make_shared<dummy>(dummy(stream));
}
- stream_end_type get_child_end()
+ handle get_child_end()
{
return child_end_;
}
private:
- stream_end_type child_end_;
+ handle child_end_;
};
}
Modified: sandbox/SOC/2010/process/libs/process/test/child.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/child.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/child.cpp 2010-07-26 17:54:06 EDT (Mon, 26 Jul 2010)
@@ -205,31 +205,33 @@
class redirect_to : public bpb::stream
{
public:
- redirect_to(stream_end_type stream_end)
+ redirect_to(bp::handle child_end)
{
#if defined(BOOST_POSIX_API)
- child_end_ = dup(stream_end);
- if (child_end_ == -1)
+ child_end_ = dup(child_end.native());
+ if (!child_end_.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup(2) failed");
#elif defined(BOOST_WINDOWS_API)
- if (!DuplicateHandle(GetCurrentProcess(), stream_end,
- GetCurrentProcess(), &child_end_, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ HANDLE h;
+ if (!DuplicateHandle(GetCurrentProcess(), child_end.native(),
+ GetCurrentProcess(), &h, 0, TRUE, DUPLICATE_SAME_ACCESS))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("DuplicateHandle() failed");
+ child_end_ = h;
#endif
}
- static boost::shared_ptr<redirect_to> def(stream_end_type stream_end)
+ static boost::shared_ptr<redirect_to> def(bp::handle stream_end)
{
return boost::make_shared<redirect_to>(redirect_to(stream_end));
}
- stream_end_type get_child_end()
+ bp::handle get_child_end()
{
return child_end_;
}
private:
- stream_end_type child_end_;
+ bp::handle child_end_;
};
BOOST_AUTO_TEST_CASE(test_redirect_err_to_out)
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk