$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61904 - sandbox/SOC/2010/process/boost/process/details
From: fotanus_at_[hidden]
Date: 2010-05-11 01:26:57
Author: fotanus
Date: 2010-05-11 01:26:56 EDT (Tue, 11 May 2010)
New Revision: 61904
URL: http://svn.boost.org/trac/boost/changeset/61904
Log:
Missing files from previous commit
Added:
   sandbox/SOC/2010/process/boost/process/details/
   sandbox/SOC/2010/process/boost/process/details/file_handle.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/details/pipe.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/details/posix_ops.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/details/stream_info.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/details/systembuf.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/details/win32_ops.hpp   (contents, props changed)
Added: sandbox/SOC/2010/process/boost/process/details/file_handle.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/details/file_handle.hpp	2010-05-11 01:26:56 EDT (Tue, 11 May 2010)
@@ -0,0 +1,406 @@
+// 
+// Boost.Process 
+// ~~~~~~~~~~~~~ 
+// 
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal 
+// Copyright (c) 2008, 2009 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. This file is for 
+ * internal usage only and must not be included by the library user. 
+ */ 
+
+#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> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.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) 
+    { 
+        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() const 
+    { 
+        return handle_ != invalid_value(); 
+    } 
+
+    /** 
+     * 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()); 
+
+#if defined(BOOST_POSIX_API) 
+        ::close(handle_); 
+#elif defined(BOOST_WINDOWS_API) 
+        ::CloseHandle(handle_); 
+#endif 
+
+        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() const 
+    { 
+        BOOST_ASSERT(valid()); 
+
+        return handle_; 
+    } 
+
+#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) 
+    /** 
+     * Changes the native file handle to the given one. 
+     * 
+     * Given a new native file handle \a h, this operation assigns this 
+     * handle to the current object, closing its old native file handle. 
+     * In other words, it first calls dup2() to remap the old handle to 
+     * the new one and then closes the old handle. 
+     * 
+     * If \a h is open, it is automatically closed by dup2(). 
+     * 
+     * This operation is only available in POSIX systems. 
+     * 
+     * \pre The file handle is valid. 
+     * \pre The native file handle \a h is valid; i.e., it must be 
+     *      closeable. 
+     * \post The file handle's native file handle is \a h. 
+     * \throw boost::system::system_error If the internal remapping 
+     *        operation fails. 
+     */ 
+    void posix_remap(handle_type h) 
+    { 
+        BOOST_ASSERT(valid()); 
+
+        if (::dup2(handle_, h) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: dup2(2) failed")); 
+
+        if (::close(handle_) == -1) 
+        { 
+            ::close(h); 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: close(2) failed")); 
+        } 
+
+        handle_ = h; 
+    } 
+
+    /** 
+     * Duplicates an open native file handle. 
+     * 
+     * Given a native file handle \a h1, this routine duplicates it so 
+     * that it ends up being identified by the native file handle \a h2 
+     * and returns a new \a file_handle owning \a h2. 
+     * 
+     * This operation is only available in POSIX systems. 
+     * 
+     * \pre The native file handle \a h1 is open. 
+     * \pre The native file handle \a h2 is valid (non-negative). 
+     * \post The native file handle \a h1 is closed. 
+     * \post The native file handle \a h2 is the same as the old \a h1 
+     *       from the operating system's point of view. 
+     * \return A new \a file_handle object that owns \a h2. 
+     * \throw boost::system::system_error If dup2() fails. 
+     */ 
+    static file_handle posix_dup(int h1, int h2) 
+    { 
+        if (::dup2(h1, h2) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_dup: dup2(2) failed")); 
+
+        return file_handle(h2); 
+    } 
+#endif 
+
+#if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN) 
+    /** 
+     * Duplicates the \a h native file handle. 
+     * 
+     * Given a native file handle \a h, this routine constructs a new 
+     * \a file_handle object that owns a new duplicate of \a h. The 
+     * duplicate's inheritable flag is set to the value of \a inheritable. 
+     * 
+     * This operation is only available in Windows systems. 
+     * 
+     * \pre The native file handle \a h is valid. 
+     * \return A file handle owning a duplicate of \a h. 
+     * \throw boost::system::system_error If DuplicateHandle() fails. 
+     */ 
+    static file_handle win32_dup(HANDLE h, bool inheritable) 
+    { 
+        HANDLE h2; 
+        if (!::DuplicateHandle(::GetCurrentProcess(), h, ::GetCurrentProcess(), &h2, 0, inheritable ? TRUE : FALSE, DUPLICATE_SAME_ACCESS)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_dup: DuplicateHandle failed")); 
+
+        return file_handle(h2); 
+    } 
+
+    /** 
+     * Creates a new duplicate of a standard file handle. 
+     * 
+     * Constructs a new \a file_handle object that owns a duplicate of a 
+     * standard file handle. The \a d parameter specifies which standard 
+     * file handle to duplicate and can be one of \a STD_INPUT_HANDLE, 
+     * \a STD_OUTPUT_HANDLE or \a STD_ERROR_HANDLE. The duplicate's 
+     * inheritable flag is set to the value of \a inheritable. 
+     * 
+     * This operation is only available in Windows systems. 
+     * 
+     * \pre \a d refers to one of the standard handles as described above. 
+     * \return A file handle owning a duplicate of the standard handle 
+     *         referred to by \a d. 
+     * \throw boost::system::system_error If GetStdHandle() or 
+     *        DuplicateHandle() fails. 
+     */ 
+    static file_handle win32_std(DWORD d, bool inheritable) 
+    { 
+        BOOST_ASSERT(d == STD_INPUT_HANDLE || d == STD_OUTPUT_HANDLE || d == STD_ERROR_HANDLE); 
+
+        HANDLE h = ::GetStdHandle(d); 
+        if (h == INVALID_HANDLE_VALUE) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_std: GetStdHandle failed")); 
+
+        return win32_dup(h, inheritable); 
+    } 
+
+    /** 
+     * Changes the file handle's inheritable flag. 
+     * 
+     * Changes the file handle's inheritable flag to \a i. It is not 
+     * necessary for the file handle's flag to be different than \a i. 
+     * 
+     * This operation is only available in Windows systems. 
+     * 
+     * \pre The file handle is valid. 
+     * \post The native file handle's inheritable flag is set to \a i. 
+     * \throw boost::system::system_error If the property change fails. 
+     */ 
+    void win32_set_inheritable(bool i) 
+    { 
+        BOOST_ASSERT(valid()); 
+
+        if (!::SetHandleInformation(handle_, HANDLE_FLAG_INHERIT, i ? HANDLE_FLAG_INHERIT : 0)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_set_inheritable: SetHandleInformation failed")); 
+    } 
+#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 
Added: sandbox/SOC/2010/process/boost/process/details/pipe.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/details/pipe.hpp	2010-05-11 01:26:56 EDT (Tue, 11 May 2010)
@@ -0,0 +1,187 @@
+// 
+// Boost.Process 
+// ~~~~~~~~~~~~~ 
+// 
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal 
+// Copyright (c) 2008, 2009 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/pipe.hpp 
+ * 
+ * Includes the declaration of the pipe class. This file is for 
+ * internal usage only and must not be included by the library user. 
+ */ 
+
+#ifndef BOOST_PROCESS_DETAIL_PIPE_HPP 
+#define BOOST_PROCESS_DETAIL_PIPE_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <unistd.h> 
+#  include <cerrno> 
+#elif defined(BOOST_WINDOWS_API) 
+#  if defined(BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE) 
+#    include <boost/lexical_cast.hpp> 
+#    include <string> 
+#  endif 
+#  include <windows.h> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+
+namespace boost { 
+namespace process { 
+namespace detail { 
+
+/** 
+ * Simple RAII model for anonymous pipes. 
+ * 
+ * The pipe class is a simple RAII model for anonymous pipes. It 
+ * provides a portable constructor that allocates a new %pipe and creates 
+ * a pipe object that owns the two file handles associated to it: the 
+ * read end and the write end. 
+ * 
+ * These handles can be retrieved for modification according to 
+ * file_handle semantics. Optionally, their ownership can be transferred 
+ * to external \a file_handle objects which comes handy when the two 
+ * ends need to be used in different places (i.e. after a POSIX fork() 
+ * system call). 
+ * 
+ * Pipes can be copied following the same semantics as file handles. 
+ * In other words, copying a %pipe object invalidates the source one. 
+ * 
+ * \see file_handle 
+ */ 
+class pipe 
+{ 
+public: 
+    /** 
+     * Creates a new %pipe. 
+     * 
+     * The default pipe constructor allocates a new anonymous %pipe 
+     * and assigns its ownership to the created pipe object. On Windows 
+     * when the macro BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE is defined 
+     * a named pipe is created. This is required if asynchronous I/O 
+     * should be used as asynchronous I/O is only supported by named 
+     * pipes on Windows. 
+     * 
+     * \throw boost::system::system_error If the anonymous %pipe 
+     *        creation fails. 
+     */ 
+    pipe() 
+    { 
+        file_handle::handle_type hs[2]; 
+
+#if defined(BOOST_POSIX_API) 
+        if (::pipe(hs) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::pipe::pipe: pipe(2) failed")); 
+#elif defined(BOOST_WINDOWS_API) 
+        SECURITY_ATTRIBUTES sa; 
+        ZeroMemory(&sa, sizeof(sa)); 
+        sa.nLength = sizeof(sa); 
+        sa.lpSecurityDescriptor = NULL; 
+        sa.bInheritHandle = FALSE; 
+
+#  if defined(BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE) 
+        static unsigned int nextid = 0; 
+        std::string pipe = "\\\\.\\pipe\\boost_process_" + boost::lexical_cast<std::string>(::GetCurrentProcessId()) + "_" + boost::lexical_cast<std::string>(nextid++); 
+        hs[0] = ::CreateNamedPipeA(pipe.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa); 
+        if (hs[0] == INVALID_HANDLE_VALUE) 
+            boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category, "boost::process::detail::pipe::pipe: CreateNamedPipe failed")); 
+        hs[1] = ::CreateFileA(pipe.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 
+        if (hs[1] == INVALID_HANDLE_VALUE) 
+            boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category, "boost::process::detail::pipe::pipe: CreateFile failed")); 
+
+        OVERLAPPED overlapped; 
+        ZeroMemory(&overlapped, sizeof(overlapped)); 
+        overlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); 
+        if (!overlapped.hEvent) 
+            boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category, "boost::process::detail::pipe::pipe: CreateEvent failed")); 
+        BOOL b = ::ConnectNamedPipe(hs[0], &overlapped); 
+        if (!b) 
+        { 
+            if (::GetLastError() == ERROR_IO_PENDING) 
+            { 
+                if (::WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_FAILED) 
+                { 
+                    ::CloseHandle(overlapped.hEvent); 
+                    boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category, "boost::process::detail::pipe::pipe: WaitForSingleObject failed")); 
+                } 
+            } 
+            else if (::GetLastError() != ERROR_PIPE_CONNECTED) 
+            { 
+                ::CloseHandle(overlapped.hEvent); 
+                boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category, "boost::process::detail::pipe::pipe: ConnectNamedPipe failed")); 
+            } 
+        } 
+        ::CloseHandle(overlapped.hEvent); 
+#  else 
+        if (!::CreatePipe(&hs[0], &hs[1], &sa, 0)) 
+            boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category, "boost::process::detail::pipe::pipe: CreatePipe failed")); 
+#  endif 
+#endif 
+
+        read_end_ = file_handle(hs[0]); 
+        write_end_ = file_handle(hs[1]); 
+    } 
+
+    /** 
+     * Returns the %pipe's read end file handle. 
+     * 
+     * Obtains a reference to the %pipe's read end file handle. Care 
+     * should be taken to not duplicate the returned object if ownership 
+     * shall remain to the %pipe. 
+     * 
+     * Duplicating the returned object invalidates its corresponding file 
+     * handle in the %pipe. 
+     * 
+     * \return A reference to the %pipe's read end file handle. 
+     */ 
+    file_handle &rend() 
+    { 
+        return read_end_; 
+    } 
+
+    /** 
+     * Returns the %pipe's write end file handle. 
+     * 
+     * Obtains a reference to the %pipe's write end file handle. Care 
+     * should be taken to not duplicate the returned object if ownership 
+     * shall remain to the %pipe. 
+     * 
+     * Duplicating the returned object invalidates its corresponding file 
+     * handle in the %pipe. 
+     * 
+     * \return A reference to the %pipe's write end file handle. 
+     */ 
+    file_handle &wend() 
+    { 
+        return write_end_; 
+    } 
+
+private: 
+    /** 
+     * The %pipe's read end file handle. 
+     */ 
+    file_handle read_end_; 
+
+    /** 
+     * The %pipe's write end file handle. 
+     */ 
+    file_handle write_end_; 
+}; 
+
+} 
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/details/posix_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/details/posix_ops.hpp	2010-05-11 01:26:56 EDT (Tue, 11 May 2010)
@@ -0,0 +1,495 @@
+// 
+// Boost.Process 
+// ~~~~~~~~~~~~~ 
+// 
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal 
+// Copyright (c) 2008, 2009 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/posix_ops.hpp 
+ * 
+ * Provides some convenience functions to start processes under POSIX 
+ * operating systems. 
+ */ 
+
+#ifndef BOOST_PROCESS_DETAIL_POSIX_OPS_HPP 
+#define BOOST_PROCESS_DETAIL_POSIX_OPS_HPP 
+
+#include <boost/process/environment.hpp> 
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/process/detail/pipe.hpp> 
+#include <boost/process/detail/stream_info.hpp> 
+#include <boost/scoped_array.hpp> 
+#include <boost/assert.hpp> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+#include <map> 
+#include <utility> 
+#include <string> 
+#include <cerrno> 
+#include <cstdlib> 
+#include <cstring> 
+#include <fcntl.h> 
+#include <unistd.h> 
+
+namespace boost { 
+namespace process { 
+namespace detail { 
+
+/** 
+ * Converts the command line to an array of C strings. 
+ * 
+ * Converts the command line's list of arguments to the format expected 
+ * by the \a argv parameter in the POSIX execve() system call. 
+ * 
+ * This operation is only available on POSIX systems. 
+ * 
+ * \return The first argument of the pair is an integer that indicates 
+ *         how many strings are stored in the second argument. The 
+ *         second argument is a NULL-terminated, dynamically allocated 
+ *         array of dynamically allocated strings holding the arguments 
+ *         to the executable. The caller is responsible of freeing them. 
+ */ 
+template <class Arguments> 
+inline std::pair<std::size_t, char**> collection_to_posix_argv(const Arguments &args) 
+{ 
+    std::size_t nargs = args.size(); 
+    BOOST_ASSERT(nargs > 0); 
+
+    char **argv = new char*[nargs + 1]; 
+    typename Arguments::size_type i = 0; 
+    for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it) 
+    { 
+        argv[i] = new char[it->size() + 1]; 
+        std::strncpy(argv[i], it->c_str(), it->size() + 1); 
+        ++i; 
+    } 
+    argv[nargs] = 0; 
+
+    return std::pair<std::size_t, char**>(nargs, argv); 
+} 
+
+/** 
+ * Converts an environment to a char** table as used by execve(). 
+ * 
+ * Converts the environment's contents to the format used by the 
+ * execve() system call. The returned char** array is allocated 
+ * in dynamic memory; the caller must free it when not used any 
+ * more. Each entry is also allocated in dynamic memory and is a 
+ * NULL-terminated string of the form var=value; these must also be 
+ * released by the caller. 
+ * 
+ * \return A dynamically allocated char** array that represents 
+ *         the environment's content. Each array entry is a 
+ *         NULL-terminated string of the form var=value. 
+ */ 
+inline char **environment_to_envp(const environment &env) 
+{ 
+    char **envp = new char*[env.size() + 1]; 
+
+    environment::size_type i = 0; 
+    for (environment::const_iterator it = env.begin(); it != env.end(); ++it) 
+    { 
+        std::string s = it->first + "=" + it->second; 
+        envp[i] = new char[s.size() + 1]; 
+        std::strncpy(envp[i], s.c_str(), s.size() + 1); 
+        ++i; 
+    } 
+    envp[i] = 0; 
+
+    return envp; 
+} 
+
+/** 
+ * Holds a mapping between native file descriptors and their corresponding 
+ * pipes to set up communication between the parent and the %child process. 
+ */ 
+typedef std::map<int, stream_info> info_map; 
+
+/** 
+ * Helper class to configure a POSIX %child. 
+ * 
+ * This helper class is used to hold all the attributes that configure a 
+ * new POSIX %child process and to centralize all the actions needed to 
+ * make them effective. 
+ * 
+ * All its fields are public for simplicity. It is only intended for 
+ * internal use and it is heavily coupled with the Context 
+ * implementations. 
+ */ 
+struct posix_setup 
+{ 
+    /** 
+     * The work directory. 
+     * 
+     * This string specifies the directory in which the %child process 
+     * starts execution. It cannot be empty. 
+     */ 
+    std::string work_directory; 
+
+    /** 
+     * The chroot directory, if any. 
+     * 
+     * Specifies the directory in which the %child process is chrooted 
+     * before execution. Empty if this feature is not desired. 
+     */ 
+    std::string chroot; 
+
+    /** 
+     * The user credentials. 
+     * 
+     * UID that specifies the user credentials to use to run the %child 
+     * process. Defaults to the current UID. 
+     */ 
+    uid_t uid; 
+
+    /** 
+     * The effective user credentials. 
+     * 
+     * EUID that specifies the effective user credentials to use to run 
+     * the %child process. Defaults to the current EUID. 
+     */ 
+    uid_t euid; 
+
+    /** 
+     * The group credentials. 
+     * 
+     * GID that specifies the group credentials to use to run the %child 
+     * process. Defaults to the current GID. 
+     */ 
+    gid_t gid; 
+
+    /** 
+     * The effective group credentials. 
+     * 
+     * EGID that specifies the effective group credentials to use to run 
+     * the %child process. Defaults to the current EGID. 
+     */ 
+    gid_t egid; 
+
+    /** 
+     * Creates a new properties set. 
+     * 
+     * Creates a new object that has sensible default values for all the 
+     * properties. 
+     */ 
+    posix_setup() 
+        : uid(::getuid()), 
+        euid(::geteuid()), 
+        gid(::getgid()), 
+        egid(::getegid()) 
+    { 
+    } 
+
+    /** 
+     * Sets up the execution environment. 
+     * 
+     * Modifies the current execution environment (that of the %child) so 
+     * that the properties become effective. 
+     * 
+     * \throw boost::system::system_error If any error ocurred during 
+     *        environment configuration. The child process should abort 
+     *        execution if this happens because its start conditions 
+     *        cannot be met. 
+     */ 
+    void operator()() const 
+    { 
+        if (!chroot.empty() && ::chroot(chroot.c_str()) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: chroot(2) failed")); 
+
+        if (gid != ::getgid() && ::setgid(gid) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setgid(2) failed")); 
+
+        if (egid != ::getegid() && ::setegid(egid) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setegid(2) failed")); 
+
+        if (uid != ::getuid() && ::setuid(uid) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setuid(2) failed")); 
+
+        if (euid != ::geteuid() && ::seteuid(euid) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: seteuid(2) failed")); 
+
+        BOOST_ASSERT(!work_directory.empty()); 
+        if (::chdir(work_directory.c_str()) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: chdir(2) failed")); 
+    } 
+}; 
+
+/** 
+ * Configures child process' input streams. 
+ * 
+ * Sets up the current process' input streams to behave according to the 
+ * information in the \a info map. \a closeflags is modified to reflect 
+ * those descriptors that should not be closed because they where modified 
+ * by the function. 
+ * 
+ * Modifies the current execution environment, so this should only be run 
+ * on the child process after the fork(2) has happened. 
+ * 
+ * \throw boost::system::system_error If any error occurs during the 
+ *        configuration. 
+ */ 
+inline void setup_input(info_map &info, bool *closeflags, int maxdescs) 
+{ 
+    for (info_map::iterator it = info.begin(); it != info.end(); ++it) 
+    { 
+        int d = it->first; 
+        stream_info &si = it->second; 
+
+        BOOST_ASSERT(d < maxdescs); 
+        closeflags[d] = false; 
+
+        switch (si.type_) 
+        { 
+        case stream_info::use_file: 
+            { 
+                int fd = ::open(si.file_.c_str(), O_RDONLY); 
+                if (fd == -1) 
+                    boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_input: open(2) of " + si.file_ + " failed")); 
+                if (fd != d) 
+                { 
+                    file_handle h(fd); 
+                    h.posix_remap(d); 
+                    h.release(); 
+                } 
+                break; 
+            } 
+        case stream_info::use_handle: 
+            { 
+                if (si.handle_.get() != d) 
+                    si.handle_.posix_remap(d); 
+                break; 
+            } 
+        case stream_info::use_pipe: 
+            { 
+                si.pipe_->wend().close(); 
+                if (d != si.pipe_->rend().get()) 
+                    si.pipe_->rend().posix_remap(d); 
+                break; 
+            } 
+        default: 
+            { 
+                BOOST_ASSERT(si.type_ == stream_info::inherit); 
+                break; 
+            } 
+        } 
+    } 
+} 
+
+/** 
+ * Configures child process' output streams. 
+ * 
+ * Sets up the current process' output streams to behave according to the 
+ * information in the \a info map. \a closeflags is modified to reflect 
+ * those descriptors that should not be closed because they where 
+ * modified by the function. 
+ * 
+ * Modifies the current execution environment, so this should only be run 
+ * on the child process after the fork(2) has happened. 
+ * 
+ * \throw boost::system::system_error If any error occurs during the 
+ *        configuration. 
+ */ 
+inline void setup_output(info_map &info, bool *closeflags, int maxdescs) 
+{ 
+    for (info_map::iterator it = info.begin(); it != info.end(); ++it) 
+    { 
+        int d = it->first; 
+        stream_info &si = it->second; 
+
+        BOOST_ASSERT(d < maxdescs); 
+        closeflags[d] = false; 
+
+        switch (si.type_) 
+        { 
+        case stream_info::redirect: 
+            { 
+                break; 
+            } 
+        case stream_info::use_file: 
+            { 
+                int fd = ::open(si.file_.c_str(), O_WRONLY); 
+                if (fd == -1) 
+                    boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_output: open(2) of " + si.file_ + " failed")); 
+                if (fd != d) 
+                { 
+                    file_handle h(fd); 
+                    h.posix_remap(d); 
+                    h.release(); 
+                } 
+                break; 
+            } 
+        case stream_info::use_handle: 
+            { 
+                if (si.handle_.get() != d) 
+                    si.handle_.posix_remap(d); 
+                break; 
+            } 
+        case stream_info::use_pipe: 
+            { 
+                si.pipe_->rend().close(); 
+                if (d != si.pipe_->wend().get()) 
+                    si.pipe_->wend().posix_remap(d); 
+                break; 
+            } 
+        default: 
+            { 
+                BOOST_ASSERT(si.type_ == stream_info::inherit); 
+                break; 
+            } 
+        } 
+    } 
+
+    for (info_map::const_iterator it = info.begin(); it != info.end(); ++it) 
+    { 
+        int d = it->first; 
+        const stream_info &si = it->second; 
+
+        if (si.type_ == stream_info::redirect) 
+            file_handle::posix_dup(si.desc_to_, d).release(); 
+    } 
+} 
+
+/** 
+ * Starts a new child process in a POSIX operating system. 
+ * 
+ * This helper functions is provided to simplify the Context's task when 
+ * it comes to starting up a new process in a POSIX operating system. 
+ * The function hides all the details of the fork/exec pair of calls as 
+ * well as all the setup of communication pipes and execution environment. 
+ * 
+ * \param exe The executable to spawn the child process. 
+ * \param args The arguments for the executable. 
+ * \param env The environment variables that the new child process 
+ *        receives. 
+ * \param infoin A map describing all input file descriptors to be 
+ *        redirected. 
+ * \param infoout A map describing all output file descriptors to be 
+ *        redirected. 
+ * \param setup A helper object used to configure the child's execution 
+ *        environment. 
+ * \return The new process' PID. The caller is responsible of creating 
+ *         an appropriate Child representation for it. 
+ */ 
+template <class Executable, class Arguments> 
+inline pid_t posix_start(const Executable &exe, const Arguments &args, const environment &env, info_map &infoin, info_map &infoout, const posix_setup &setup) 
+{ 
+    pid_t pid = ::fork(); 
+    if (pid == -1) 
+        boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_start: fork(2) failed")); 
+    else if (pid == 0) 
+    { 
+#if defined(F_MAXFD) 
+        int maxdescs = ::fcntl(-1, F_MAXFD, 0); 
+        if (maxdescs == -1) 
+            maxdescs = ::sysconf(_SC_OPEN_MAX); 
+#else 
+        int maxdescs = ::sysconf(_SC_OPEN_MAX); 
+#endif 
+        if (maxdescs == -1) 
+            maxdescs = 1024; 
+        try 
+        { 
+            boost::scoped_array<bool> closeflags(new bool[maxdescs]); 
+            for (int i = 0; i < maxdescs; ++i) 
+                closeflags[i] = true; 
+
+            setup_input(infoin, closeflags.get(), maxdescs); 
+            setup_output(infoout, closeflags.get(), maxdescs); 
+
+            for (int i = 0; i < maxdescs; ++i) 
+            { 
+                if (closeflags[i]) 
+                    ::close(i); 
+            } 
+
+            setup(); 
+        } 
+        catch (const boost::system::system_error &e) 
+        { 
+            ::write(STDERR_FILENO, e.what(), std::strlen(e.what())); 
+            ::write(STDERR_FILENO, "\n", 1); 
+            std::exit(EXIT_FAILURE); 
+        } 
+
+        std::pair<std::size_t, char**> argcv = collection_to_posix_argv(args); 
+        char **envp = environment_to_envp(env); 
+
+        ::execve(exe.c_str(), argcv.second, envp); 
+        boost::system::system_error e(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_start: execve(2) failed"); 
+
+        for (std::size_t i = 0; i < argcv.first; ++i) 
+            delete[] argcv.second[i]; 
+        delete[] argcv.second; 
+
+        for (std::size_t i = 0; i < env.size(); ++i) 
+            delete[] envp[i]; 
+        delete[] envp; 
+
+        ::write(STDERR_FILENO, e.what(), std::strlen(e.what())); 
+        ::write(STDERR_FILENO, "\n", 1); 
+        std::exit(EXIT_FAILURE); 
+    } 
+
+    BOOST_ASSERT(pid > 0); 
+
+    for (info_map::iterator it = infoin.begin(); it != infoin.end(); ++it) 
+    { 
+        stream_info &si = it->second; 
+        if (si.type_ == stream_info::use_pipe) 
+            si.pipe_->rend().close(); 
+    } 
+
+    for (info_map::iterator it = infoout.begin(); it != infoout.end(); ++it) 
+    { 
+        stream_info &si = it->second; 
+        if (si.type_ == stream_info::use_pipe) 
+            si.pipe_->wend().close(); 
+    } 
+
+    return pid; 
+} 
+
+/** 
+ * Locates a communication pipe and returns one of its endpoints. 
+ * 
+ * Given a \a info map, and a file descriptor \a desc, searches for its 
+ * communicataion pipe in the map and returns one of its endpoints as 
+ * indicated by the \a out flag. This is intended to be used by a 
+ * parent process after a fork(2) call. 
+ * 
+ * \pre If the info map contains the given descriptor, it is configured 
+ *      to use a pipe. 
+ * \post The info map does not contain the given descriptor. 
+ * \return If the file descriptor is found in the map, returns the pipe's 
+ *         read end if out is true; otherwise its write end. If the 
+ *         descriptor is not found returns an invalid file handle. 
+ */ 
+inline file_handle posix_info_locate_pipe(info_map &info, int desc, bool out) 
+{ 
+    file_handle fh; 
+
+    info_map::iterator it = info.find(desc); 
+    if (it != info.end()) 
+    { 
+        stream_info &si = it->second; 
+        if (si.type_ == stream_info::use_pipe) 
+        { 
+            fh = out ? si.pipe_->rend().release() : si.pipe_->wend().release(); 
+            BOOST_ASSERT(fh.valid()); 
+        } 
+        info.erase(it); 
+    } 
+
+    return fh; 
+} 
+
+} 
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/details/stream_info.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/details/stream_info.hpp	2010-05-11 01:26:56 EDT (Tue, 11 May 2010)
@@ -0,0 +1,176 @@
+// 
+// Boost.Process 
+// ~~~~~~~~~~~~~ 
+// 
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal 
+// Copyright (c) 2008, 2009 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/stream_info.hpp 
+ * 
+ * Provides the definition of the stream_info structure. 
+ */ 
+
+#ifndef BOOST_PROCESS_DETAIL_STREAM_INFO_HPP 
+#define BOOST_PROCESS_DETAIL_STREAM_INFO_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <unistd.h> 
+#elif defined(BOOST_WINDOWS_API) 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/stream_behavior.hpp> 
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/process/detail/pipe.hpp> 
+#include <boost/optional.hpp> 
+#include <boost/assert.hpp> 
+#include <string> 
+
+namespace boost { 
+namespace process { 
+namespace detail { 
+
+/** 
+ * Configuration data for a file descriptor. 
+ * 
+ * This convenience structure provides a compact way to pass information 
+ * around on how to configure a file descriptor. It is a lower-level 
+ * representation of stream_behavior, as it can hold the same information 
+ * but in a way that can be used by the underlying operating system. 
+ */ 
+struct stream_info 
+{ 
+    /** 
+     * Supported stream types. 
+     */ 
+    enum type 
+    { 
+        /** 
+         * Matches stream_behavior::close. 
+         */ 
+        close, 
+
+        /** 
+         * Matches stream_behavior::inherit. 
+         */ 
+        inherit, 
+
+        /** 
+         * Matches stream_behavior::redirect_to_stdout and 
+         * stream_behavior::posix_redirect. 
+         */ 
+        redirect, 
+
+        /** 
+         * Matches stream_behavior::silence. 
+         */ 
+        use_file, 
+
+        /** 
+         * TODO: Matches nothing yet ... 
+         */ 
+        use_handle, 
+
+        /** 
+         * Matches stream_behavior::capture. 
+         */ 
+        use_pipe 
+    }; 
+
+    /** 
+     * Stream type. 
+     */ 
+    type type_; 
+
+    /** 
+     * Descriptor to use when stream type is set to \a redirect. 
+     */ 
+    int desc_to_; 
+
+    /** 
+     * File to use when stream type is set to \a use_file. 
+     */ 
+    std::string file_; 
+
+    /** 
+     * Handle to use when stream type is set to \a use_handle. 
+     */ 
+    file_handle handle_; 
+
+    /** 
+     * Pipe to use when stream type is set to \a use_pipe. 
+     */ 
+    boost::optional<pipe> pipe_; 
+
+    /** 
+     * Constructs a new stream_info object. 
+     */ 
+    stream_info(const stream_behavior &sb, bool out) 
+    { 
+        switch (sb.type_) 
+        { 
+        case stream_behavior::close: 
+            { 
+                type_ = close; 
+                break; 
+            } 
+        case stream_behavior::inherit: 
+            { 
+                type_ = inherit; 
+                break; 
+            } 
+        case stream_behavior::redirect_to_stdout: 
+            { 
+                type_ = redirect; 
+#if defined(BOOST_POSIX_API) 
+                desc_to_ = STDOUT_FILENO; 
+#elif defined(BOOST_WINDOWS_API) 
+                desc_to_ = 1; 
+#endif 
+                break; 
+            } 
+#if defined(BOOST_POSIX_API) 
+        case stream_behavior::posix_redirect: 
+            { 
+                type_ = redirect; 
+                desc_to_ = sb.desc_to_; 
+                break; 
+            } 
+#endif 
+        case stream_behavior::silence: 
+            { 
+                type_ = use_file; 
+#if defined(BOOST_POSIX_API) 
+                file_ = out ? "/dev/null" : "/dev/zero"; 
+#elif defined(BOOST_WINDOWS_API) 
+                file_ = "NUL"; 
+#endif 
+                break; 
+            } 
+        case stream_behavior::capture: 
+            { 
+                type_ = use_pipe; 
+                pipe_ = pipe(); 
+                break; 
+            } 
+        default: 
+            { 
+                BOOST_ASSERT(false); 
+            } 
+        } 
+    } 
+}; 
+
+} 
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/details/systembuf.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/details/systembuf.hpp	2010-05-11 01:26:56 EDT (Tue, 11 May 2010)
@@ -0,0 +1,231 @@
+// 
+// Boost.Process 
+// ~~~~~~~~~~~~~ 
+// 
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal 
+// Copyright (c) 2008, 2009 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/systembuf.hpp 
+ * 
+ * Includes the declaration of the systembuf class. This file is for 
+ * internal usage only and must not be included by the library user. 
+ */ 
+
+#ifndef BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP 
+#define BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <sys/types.h> 
+#  include <unistd.h> 
+#elif defined(BOOST_WINDOWS_API) 
+#  include <windows.h> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/noncopyable.hpp> 
+#include <boost/scoped_array.hpp> 
+#include <boost/assert.hpp> 
+#include <streambuf> 
+#include <cstddef> 
+
+namespace boost { 
+namespace process { 
+
+class postream; 
+
+namespace detail { 
+
+/** 
+ * std::streambuf implementation for system file 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 
+ * somewhere else. 
+ * 
+ * This class follows the expected semantics of a std::streambuf object. 
+ * However, it is not copyable to avoid introducing inconsistences with 
+ * the on-disk file and the in-memory buffers. 
+ */ 
+class systembuf : public std::streambuf, public boost::noncopyable 
+{ 
+    friend class ::boost::process::postream; 
+
+public: 
+#if defined(BOOST_PROCESS_DOXYGEN) 
+    /** 
+     * Opaque name for the native handle type. 
+     */ 
+    typedef NativeHandleType handle_type; 
+#elif defined(BOOST_POSIX_API) 
+    typedef int handle_type; 
+#elif defined(BOOST_WINDOWS_API) 
+    typedef HANDLE handle_type; 
+#endif 
+
+    /** 
+     * Constructs a new systembuf for the given file handle. 
+     * 
+     * This constructor creates a new systembuf object that reads or 
+     * writes data from/to the \a h native file handle. This handle 
+     * is \b not owned by the created systembuf object; the code 
+     * should take care of it externally. 
+     * 
+     * This class buffers input and output; the buffer size may be 
+     * tuned through the \a bufsize parameter, which defaults to 8192 
+     * bytes. 
+     * 
+     * \see pistream and postream 
+     */ 
+    explicit systembuf(handle_type h, std::size_t bufsize = 8192) 
+        : handle_(h), 
+        bufsize_(bufsize), 
+        read_buf_(new char[bufsize]), 
+        write_buf_(new char[bufsize]) 
+    { 
+#if defined(BOOST_POSIX_API) 
+        BOOST_ASSERT(handle_ >= 0); 
+#elif defined(BOOST_WINDOWS_API) 
+        BOOST_ASSERT(handle_ != INVALID_HANDLE_VALUE); 
+#endif 
+        BOOST_ASSERT(bufsize_ > 0); 
+
+        setp(write_buf_.get(), write_buf_.get() + bufsize_); 
+    } 
+
+protected: 
+    /** 
+     * Reads new data from the native file 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 
+     * data, if available. 
+     * 
+     * \pre All input positions are exhausted (gptr() >= egptr()). 
+     * \post The input buffer has new data, if available. 
+     * \returns traits_type::eof() if a read error occurrs or there are 
+     *          no more data to be read. Otherwise returns 
+     *          traits_type::to_int_type(*gptr()). 
+     */ 
+    virtual int_type underflow() 
+    { 
+        BOOST_ASSERT(gptr() >= egptr()); 
+
+        bool ok; 
+#if defined(BOOST_POSIX_API) 
+        ssize_t cnt = ::read(handle_, read_buf_.get(), bufsize_); 
+        ok = (cnt != -1 && cnt != 0); 
+#elif defined(BOOST_WINDOWS_API) 
+        DWORD cnt; 
+        BOOL res = ::ReadFile(handle_, read_buf_.get(), bufsize_, &cnt, NULL); 
+        ok = (res && cnt > 0); 
+#endif 
+
+        if (!ok) 
+            return traits_type::eof(); 
+        else 
+        { 
+            setg(read_buf_.get(), read_buf_.get(), read_buf_.get() + cnt); 
+            return traits_type::to_int_type(*gptr()); 
+        } 
+    } 
+
+    /** 
+     * Makes room in the write buffer for additional data. 
+     * 
+     * This operation is called by output methods when there is no more 
+     * space in the output buffer to hold a new element. The function 
+     * first flushes the buffer's contents to disk and then clears it to 
+     * leave room for more characters. The given \a c character is 
+     * stored at the beginning of the new space. 
+     * 
+     * \pre All output positions are exhausted (pptr() >= epptr()). 
+     * \post The output buffer has more space if no errors occurred 
+     *       during the write to disk. 
+     * \post *(pptr() - 1) is \a c. 
+     * \returns traits_type::eof() if a write error occurrs. Otherwise 
+     *          returns traits_type::not_eof(c). 
+     */ 
+    virtual int_type overflow(int c) 
+    { 
+        BOOST_ASSERT(pptr() >= epptr()); 
+
+        if (sync() == -1) 
+            return traits_type::eof(); 
+
+        if (!traits_type::eq_int_type(c, traits_type::eof())) 
+        { 
+            traits_type::assign(*pptr(), c); 
+            pbump(1); 
+        } 
+
+        return traits_type::not_eof(c); 
+    } 
+
+    /** 
+     * 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. 
+     * 
+     * \returns 0 on success, -1 if an error occurred. 
+     */ 
+    virtual int sync() 
+    { 
+#if defined(BOOST_POSIX_API) 
+        ssize_t cnt = pptr() - pbase(); 
+#elif defined(BOOST_WINDOWS_API) 
+        long cnt = pptr() - pbase(); 
+#endif 
+
+        bool ok; 
+#if defined(BOOST_POSIX_API) 
+        ok = ::write(handle_, pbase(), cnt) == cnt; 
+#elif defined(BOOST_WINDOWS_API) 
+        DWORD rcnt; 
+        BOOL res = ::WriteFile(handle_, pbase(), cnt, &rcnt, NULL); 
+        ok = (res && static_cast<long>(rcnt) == cnt); 
+#endif 
+
+        if (ok) 
+            pbump(-cnt); 
+        return ok ? 0 : -1; 
+    } 
+
+private: 
+    /** 
+     * Native file handle used by the systembuf object. 
+     */ 
+    handle_type handle_; 
+
+    /** 
+     * Internal buffer size used during read and write operations. 
+     */ 
+    std::size_t bufsize_; 
+
+    /** 
+     * Internal buffer used during read operations. 
+     */ 
+    boost::scoped_array<char> read_buf_; 
+
+    /** 
+     * Internal buffer used during write operations. 
+     */ 
+    boost::scoped_array<char> write_buf_; 
+}; 
+
+} 
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/details/win32_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/details/win32_ops.hpp	2010-05-11 01:26:56 EDT (Tue, 11 May 2010)
@@ -0,0 +1,355 @@
+// 
+// Boost.Process 
+// ~~~~~~~~~~~~~ 
+// 
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal 
+// Copyright (c) 2008, 2009 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/win32_ops.hpp 
+ * 
+ * Provides some convenience functions to start processes under 
+ * Windows-compatible operating systems. 
+ */ 
+
+#ifndef BOOST_PROCESS_DETAIL_WIN32_OPS_HPP 
+#define BOOST_PROCESS_DETAIL_WIN32_OPS_HPP 
+
+#include <boost/process/environment.hpp> 
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/process/detail/pipe.hpp> 
+#include <boost/process/detail/stream_info.hpp> 
+#include <boost/scoped_ptr.hpp> 
+#include <boost/shared_array.hpp> 
+#include <boost/scoped_array.hpp> 
+#include <boost/assert.hpp> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+#include <vector> 
+#include <string> 
+#include <cstddef> 
+#include <string.h> 
+#include <windows.h> 
+
+namespace boost { 
+namespace process { 
+namespace detail { 
+
+/** 
+ * Converts the command line to a plain string. Converts the command line's 
+ * list of arguments to the format expected by the \a lpCommandLine parameter 
+ * in the CreateProcess() system call. 
+ * 
+ * This operation is only available on Windows systems. 
+ * 
+ * \return A dynamically allocated string holding the command line 
+ *         to be passed to the executable. It is returned in a 
+ *         shared_array object to ensure its release at some point. 
+ */ 
+template <class Arguments> 
+inline boost::shared_array<char> collection_to_win32_cmdline(const Arguments &args) 
+{ 
+    typedef std::vector<std::string> arguments_t; 
+    arguments_t args2; 
+    typename Arguments::size_type i = 0; 
+    std::size_t size = 0; 
+    for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it) 
+    { 
+        std::string arg = *it; 
+
+        std::string::size_type pos = 0; 
+        while ( (pos = arg.find('"', pos)) != std::string::npos) 
+        { 
+            arg.replace(pos, 1, "\\\""); 
+            pos += 2; 
+        } 
+
+        if (arg.find(' ') != std::string::npos) 
+            arg = '\"' + arg + '\"'; 
+
+        if (i++ != args.size() - 1) 
+            arg += ' '; 
+
+        args2.push_back(arg); 
+        size += arg.size() + 1; 
+    } 
+
+    boost::shared_array<char> cmdline(new char[size]); 
+    cmdline.get()[0] = '\0'; 
+    for (arguments_t::size_type i = 0; i < args.size(); ++i) 
+#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE) 
+        ::strncat(cmdline.get(), args2[i].c_str(), args2[i].size()); 
+#else 
+        ::strcat_s(cmdline.get(), size, args2[i].c_str()); 
+#endif 
+
+    return cmdline; 
+} 
+
+/** 
+ * Converts an environment to a string used by CreateProcess(). 
+ * 
+ * Converts the environment's contents to the format used by the 
+ * CreateProcess() system call. The returned char* string is 
+ * allocated in dynamic memory; the caller must free it when not 
+ * used any more. This is enforced by the use of a shared pointer. 
+ * 
+ * \return A dynamically allocated char* string that represents 
+ *         the environment's content. This string is of the form 
+ *         var1=value1\\0var2=value2\\0\\0. 
+ */ 
+inline boost::shared_array<char> environment_to_win32_strings(const environment &env) 
+{ 
+    boost::shared_array<char> envp; 
+
+    if (env.empty()) 
+    { 
+        envp.reset(new char[2]); 
+        ::ZeroMemory(envp.get(), 2); 
+    } 
+    else 
+    { 
+        std::string s; 
+        for (environment::const_iterator it = env.begin(); it != env.end(); ++it) 
+        { 
+            s += it->first + "=" + it->second; 
+            s.push_back(0); 
+        } 
+
+        envp.reset(new char[s.size() + 1]); 
+#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE) 
+        ::memcpy(envp.get(), s.c_str(), s.size() + 1); 
+#else 
+        ::memcpy_s(envp.get(), s.size() + 1, s.c_str(), s.size() + 1); 
+#endif 
+    } 
+
+    return envp; 
+} 
+
+/** 
+ * Helper class to configure a Win32 %child. 
+ * 
+ * This helper class is used to hold all the attributes that configure a 
+ * new Win32 %child process. 
+ * 
+ * All its fields are public for simplicity. It is only intended for 
+ * internal use and it is heavily coupled with the Context 
+ * implementations. 
+ */ 
+struct win32_setup 
+{ 
+    /** 
+     * The work directory. 
+     * 
+     * This string specifies the directory in which the %child process 
+     * starts execution. It cannot be empty. 
+     */ 
+    std::string work_directory; 
+
+    /** 
+     * The process startup properties. 
+     * 
+     * This Win32-specific object holds a list of properties that describe 
+     * how the new process should be started. The \a STARTF_USESTDHANDLES 
+     * flag should not be set in it because it is automatically configured 
+     * by win32_start(). 
+     */ 
+    STARTUPINFOA *startupinfo; 
+}; 
+
+/** 
+ * Starts a new child process in a Win32 operating system. 
+ * 
+ * This helper functions is provided to simplify the Context's task when 
+ * it comes to starting up a new process in a Win32 operating system. 
+ * 
+ * \param exe The executable to spawn the child process. 
+ * \param args The arguments for the executable. 
+ * \param env The environment variables that the new child process 
+ *        receives. 
+ * \param infoin Information that describes stdin's behavior. 
+ * \param infoout Information that describes stdout's behavior. 
+ * \param infoerr Information that describes stderr's behavior. 
+ * \param setup A helper object holding extra child information. 
+ * \return The new process' information as returned by the CreateProcess() 
+ *         system call. The caller is responsible of creating an 
+ *         appropriate Child representation for it. 
+ * \pre \a setup.startupinfo_ cannot have the \a STARTF_USESTDHANDLES set 
+ *      in the \a dwFlags field. 
+ */ 
+template <class Executable, class Arguments> 
+inline PROCESS_INFORMATION win32_start(const Executable &exe, const Arguments &args, const environment &env, stream_info &infoin, stream_info &infoout, stream_info &infoerr, const win32_setup &setup) 
+{ 
+    file_handle chin, chout, cherr; 
+
+    BOOST_ASSERT(setup.startupinfo->cb >= sizeof(STARTUPINFOA)); 
+    BOOST_ASSERT(!(setup.startupinfo->dwFlags & STARTF_USESTDHANDLES)); 
+
+    boost::scoped_ptr<STARTUPINFOA> si(new STARTUPINFOA); 
+    ::CopyMemory(si.get(), setup.startupinfo, sizeof(*setup.startupinfo)); 
+    si->dwFlags |= STARTF_USESTDHANDLES; 
+
+    switch (infoin.type_) 
+    { 
+    case stream_info::close: 
+        { 
+            break; 
+        } 
+    case stream_info::inherit: 
+        { 
+            chin = file_handle::win32_std(STD_INPUT_HANDLE, true); 
+            break; 
+        } 
+    case stream_info::use_file: 
+        { 
+            HANDLE h = ::CreateFileA(infoin.file_.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
+            if (h == INVALID_HANDLE_VALUE) 
+                boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed")); 
+            chin = file_handle(h); 
+            break; 
+        } 
+    case stream_info::use_handle: 
+        { 
+            chin = infoin.handle_; 
+            chin.win32_set_inheritable(true); 
+            break; 
+        } 
+    case stream_info::use_pipe: 
+        { 
+            infoin.pipe_->rend().win32_set_inheritable(true); 
+            chin = infoin.pipe_->rend(); 
+            break; 
+        } 
+    default: 
+        { 
+            BOOST_ASSERT(false); 
+            break; 
+        } 
+    } 
+
+    si->hStdInput = chin.valid() ? chin.get() : INVALID_HANDLE_VALUE; 
+
+    switch (infoout.type_) 
+    { 
+    case stream_info::close: 
+        { 
+            break; 
+        } 
+    case stream_info::inherit: 
+        { 
+            chout = file_handle::win32_std(STD_OUTPUT_HANDLE, true); 
+            break; 
+        } 
+    case stream_info::use_file: 
+        { 
+            HANDLE h = ::CreateFileA(infoout.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
+            if (h == INVALID_HANDLE_VALUE) 
+                boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed")); 
+            chout = file_handle(h); 
+            break; 
+        } 
+    case stream_info::use_handle: 
+        { 
+            chout = infoout.handle_; 
+            chout.win32_set_inheritable(true); 
+            break; 
+        } 
+    case stream_info::use_pipe: 
+        { 
+            infoout.pipe_->wend().win32_set_inheritable(true); 
+            chout = infoout.pipe_->wend(); 
+            break; 
+        } 
+    default: 
+        { 
+            BOOST_ASSERT(false); 
+            break; 
+        } 
+    } 
+
+    si->hStdOutput = chout.valid() ? chout.get() : INVALID_HANDLE_VALUE; 
+
+    switch (infoerr.type_) 
+    { 
+    case stream_info::close: 
+        { 
+            break; 
+        } 
+    case stream_info::inherit: 
+        { 
+            cherr = file_handle::win32_std(STD_ERROR_HANDLE, true); 
+            break; 
+        } 
+    case stream_info::redirect: 
+        { 
+            BOOST_ASSERT(infoerr.desc_to_ == 1); 
+            BOOST_ASSERT(chout.valid()); 
+            cherr = file_handle::win32_dup(chout.get(), true); 
+            break; 
+        } 
+    case stream_info::use_file: 
+        { 
+            HANDLE h = ::CreateFileA(infoerr.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
+            if (h == INVALID_HANDLE_VALUE) 
+                boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed")); 
+            cherr = file_handle(h); 
+            break; 
+        } 
+    case stream_info::use_handle: 
+        { 
+            cherr = infoerr.handle_; 
+            cherr.win32_set_inheritable(true); 
+            break; 
+        } 
+    case stream_info::use_pipe: 
+        { 
+            infoerr.pipe_->wend().win32_set_inheritable(true); 
+            cherr = infoerr.pipe_->wend(); 
+            break; 
+        } 
+    default: 
+        { 
+            BOOST_ASSERT(false); 
+            break; 
+        } 
+    } 
+
+    si->hStdError = cherr.valid() ? cherr.get() : INVALID_HANDLE_VALUE; 
+
+    PROCESS_INFORMATION pi; 
+    ::ZeroMemory(&pi, sizeof(pi)); 
+
+    boost::shared_array<char> cmdline = collection_to_win32_cmdline(args); 
+
+    boost::scoped_array<char> executable(new char[exe.size() + 1]); 
+#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE) 
+    ::strcpy(executable.get(), exe.c_str()); 
+#else 
+    ::strcpy_s(executable.get(), exe.size() + 1, exe.c_str()); 
+#endif 
+
+    boost::scoped_array<char> workdir(new char[setup.work_directory.size() + 1]); 
+#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE) 
+    ::strcpy(workdir.get(), setup.work_directory.c_str()); 
+#else 
+    ::strcpy_s(workdir.get(), setup.work_directory.size() + 1, setup.work_directory.c_str()); 
+#endif 
+
+    boost::shared_array<char> envstrs = environment_to_win32_strings(env); 
+
+    if (!::CreateProcessA(executable.get(), cmdline.get(), NULL, NULL, TRUE, 0, envstrs.get(), workdir.get(), si.get(), &pi)) 
+        boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateProcess failed")); 
+
+    return pi; 
+} 
+
+} 
+} 
+} 
+
+#endif