$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61900 - in sandbox/SOC/2010/process/boost: . process
From: fotanus_at_[hidden]
Date: 2010-05-11 00:02:15
Author: fotanus
Date: 2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
New Revision: 61900
URL: http://svn.boost.org/trac/boost/changeset/61900
Log:
s is a snapshot from the previous work developed on boost.process.
We must select what code from this will be reused.
Added:
   sandbox/SOC/2010/process/boost/process.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/child.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/config.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/context.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/environment.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/operations.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/pistream.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/posix_child.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/posix_context.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/posix_operations.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/posix_status.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/postream.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/process.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/self.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/status.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/stream_behavior.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/win32_child.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/win32_context.hpp   (contents, props changed)
   sandbox/SOC/2010/process/boost/process/win32_operations.hpp   (contents, props changed)
Added: sandbox/SOC/2010/process/boost/process.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,50 @@
+// 
+// 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.hpp 
+ * 
+ * Convenience header that includes all other Boost.Process public header 
+ * files. It is important to note that those headers that are specific to 
+ * a given platform are only included if the library is being used in that 
+ * same platform. 
+ */ 
+
+#ifndef BOOST_PROCESS_HPP 
+#define BOOST_PROCESS_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <boost/process/posix_child.hpp> 
+#  include <boost/process/posix_context.hpp> 
+#  include <boost/process/posix_operations.hpp> 
+#  include <boost/process/posix_status.hpp> 
+#elif defined(BOOST_WINDOWS_API) 
+#  include <boost/process/win32_child.hpp> 
+#  include <boost/process/win32_context.hpp> 
+#  include <boost/process/win32_operations.hpp> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/child.hpp> 
+#include <boost/process/context.hpp> 
+#include <boost/process/environment.hpp> 
+#include <boost/process/operations.hpp> 
+#include <boost/process/pistream.hpp> 
+#include <boost/process/postream.hpp> 
+#include <boost/process/process.hpp> 
+#include <boost/process/self.hpp> 
+#include <boost/process/status.hpp> 
+#include <boost/process/stream_behavior.hpp> 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/child.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/child.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,200 @@
+// 
+// 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/child.hpp 
+ * 
+ * Includes the declaration of the child class. 
+ */ 
+
+#ifndef BOOST_PROCESS_CHILD_HPP 
+#define BOOST_PROCESS_CHILD_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <sys/types.h> 
+#  include <sys/wait.h> 
+#  include <cerrno> 
+#elif defined(BOOST_WINDOWS_API) 
+#  include <windows.h> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/process.hpp> 
+#include <boost/process/pistream.hpp> 
+#include <boost/process/postream.hpp> 
+#include <boost/process/status.hpp> 
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+#include <boost/shared_ptr.hpp> 
+#include <boost/assert.hpp> 
+#include <vector> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Generic implementation of the Child concept. 
+ * 
+ * The child class implements the Child concept in an operating system 
+ * agnostic way. 
+ */ 
+class child : public process 
+{ 
+public: 
+    /** 
+     * Gets a reference to the child's standard input stream. 
+     * 
+     * Returns a reference to a postream object that represents the 
+     * standard input communication channel with the child process. 
+     */ 
+    postream &get_stdin() const 
+    { 
+        BOOST_ASSERT(stdin_); 
+
+        return *stdin_; 
+    } 
+
+    /** 
+     * Gets a reference to the child's standard output stream. 
+     * 
+     * Returns a reference to a pistream object that represents the 
+     * standard output communication channel with the child process. 
+     */ 
+    pistream &get_stdout() const 
+    { 
+        BOOST_ASSERT(stdout_); 
+
+        return *stdout_; 
+    } 
+
+    /** 
+     * Gets a reference to the child's standard error stream. 
+     * 
+     * Returns a reference to a pistream object that represents the 
+     * standard error communication channel with the child process. 
+     */ 
+    pistream &get_stderr() const 
+    { 
+        BOOST_ASSERT(stderr_); 
+
+        return *stderr_; 
+    } 
+
+    /** 
+     * Blocks and waits for the child process to terminate. 
+     * 
+     * Returns a status object that represents the child process' 
+     * finalization condition. The child process object ceases to be 
+     * valid after this call. 
+     * 
+     * \remark Blocking remarks: This call blocks if the child 
+     *         process has not finalized execution and waits until 
+     *         it terminates. 
+     */ 
+    status wait() 
+    { 
+#if defined(BOOST_POSIX_API) 
+        int s; 
+        if (::waitpid(get_id(), &s, 0) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::child::wait: waitpid(2) failed")); 
+        return status(s); 
+#elif defined(BOOST_WINDOWS_API) 
+        ::WaitForSingleObject(process_handle_.get(), INFINITE); 
+        DWORD code; 
+        if (!::GetExitCodeProcess(process_handle_.get(), &code)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::child::wait: GetExitCodeProcess failed")); 
+        return status(code); 
+#endif 
+    } 
+
+    /** 
+     * Creates a new child object that represents the just spawned child 
+     * process \a id. 
+     * 
+     * The \a fhstdin, \a fhstdout and \a fhstderr file handles represent 
+     * the parent's handles used to communicate with the corresponding 
+     * data streams. They needn't be valid but their availability must 
+     * match the redirections configured by the launcher that spawned this 
+     * process. 
+     * 
+     * The \a fhprocess handle represents a handle to the child process. 
+     * It is only used on Windows as the implementation of wait() needs a 
+     * process handle. 
+     */ 
+    child(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr, detail::file_handle fhprocess = detail::file_handle()) 
+        : process(id) 
+#if defined(BOOST_WINDOWS_API) 
+        , process_handle_(fhprocess.release(), ::CloseHandle) 
+#endif 
+    { 
+        if (fhstdin.valid()) 
+            stdin_.reset(new postream(fhstdin)); 
+        if (fhstdout.valid()) 
+            stdout_.reset(new pistream(fhstdout)); 
+        if (fhstderr.valid()) 
+            stderr_.reset(new pistream(fhstderr)); 
+    } 
+
+private: 
+    /** 
+     * The standard input stream attached to the child process. 
+     * 
+     * This postream object holds the communication channel with the 
+     * child's process standard input. It is stored in a pointer because 
+     * this field is only valid when the user requested to redirect this 
+     * data stream. 
+     */ 
+    boost::shared_ptr<postream> stdin_; 
+
+    /** 
+     * The standard output stream attached to the child process. 
+     * 
+     * This postream object holds the communication channel with the 
+     * child's process standard output. It is stored in a pointer because 
+     * this field is only valid when the user requested to redirect this 
+     * data stream. 
+     */ 
+    boost::shared_ptr<pistream> stdout_; 
+
+    /** 
+     * The standard error stream attached to the child process. 
+     * 
+     * This postream object holds the communication channel with the 
+     * child's process standard error. It is stored in a pointer because 
+     * this field is only valid when the user requested to redirect this 
+     * data stream. 
+     */ 
+    boost::shared_ptr<pistream> stderr_; 
+
+#if defined(BOOST_WINDOWS_API) 
+    /** 
+     * Process handle owned by RAII object. 
+     */ 
+    boost::shared_ptr<void> process_handle_; 
+#endif 
+}; 
+
+/** 
+ * Collection of child objects. 
+ * 
+ * This convenience type represents a collection of child objects backed 
+ * by a vector. 
+ */ 
+typedef std::vector<child> children; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/config.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/config.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,41 @@
+// 
+// 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/config.hpp 
+ * 
+ * Defines macros that are used by the library's code to determine the 
+ * operating system it is running under and the features it supports. 
+ */ 
+
+#ifndef BOOST_PROCESS_CONFIG_HPP 
+#define BOOST_PROCESS_CONFIG_HPP 
+
+#include <boost/config.hpp> 
+#include <boost/system/config.hpp> 
+
+#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) 
+#  if !defined(BOOST_PROCESS_POSIX_PATH_MAX) 
+/** 
+ * The macro BOOST_PROCESS_POSIX_PATH_MAX is set to a positive integer 
+ * value which specifies the system's maximal supported path length. 
+ * By default it is set to 259. You should set the macro to PATH_MAX 
+ * which should be defined in limits.h provided by your operating system 
+ * if you experience problems when instantiating a context. The 
+ * constructor of basic_work_directory_context tries to find out 
+ * dynamically the maximal supported path length but uses 
+ * BOOST_PROCESS_POSIX_PATH_MAX if it fails. 
+ */ 
+#    define BOOST_PROCESS_POSIX_PATH_MAX 259 
+#  endif 
+#endif 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/context.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/context.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,209 @@
+// 
+// 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/context.hpp 
+ * 
+ * Includes the declaration of the context class and several accessory 
+ * base classes. 
+ */ 
+
+#ifndef BOOST_PROCESS_CONTEXT_HPP 
+#define BOOST_PROCESS_CONTEXT_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <boost/scoped_array.hpp> 
+#  include <cerrno> 
+#  include <unistd.h> 
+#elif defined(BOOST_WINDOWS_API) 
+#  include <windows.h> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/environment.hpp> 
+#include <boost/process/stream_behavior.hpp> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+#include <boost/assert.hpp> 
+#include <string> 
+#include <vector> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Base context class that defines the child's work directory. 
+ * 
+ * Base context class that defines the necessary fields to configure a 
+ * child's work directory. This class is useless on its own because no 
+ * function in the library will accept it as a valid Context 
+ * implementation. 
+ */ 
+template <class Path> 
+class basic_work_directory_context 
+{ 
+public: 
+    /** 
+     * Constructs a new work directory context. 
+     * 
+     * Constructs a new work directory context making the work directory 
+     * described by the new object point to the caller's current working 
+     * directory. 
+     */ 
+    basic_work_directory_context() 
+    { 
+#if defined(BOOST_POSIX_API) 
+        errno = 0; 
+        long size = ::pathconf(".", _PC_PATH_MAX); 
+        if (size == -1 && errno) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: pathconf(2) failed")); 
+        else if (size == -1) 
+            size = BOOST_PROCESS_POSIX_PATH_MAX; 
+        boost::scoped_array<char> cwd(new char[size]); 
+        if (!::getcwd(cwd.get(), size)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: getcwd(2) failed")); 
+        work_directory = cwd.get(); 
+#elif defined(BOOST_WINDOWS_API) 
+        char cwd[MAX_PATH]; 
+        if (!::GetCurrentDirectoryA(sizeof(cwd), cwd)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: GetCurrentDirectory failed")); 
+        work_directory = cwd; 
+#endif 
+        BOOST_ASSERT(!work_directory.empty()); 
+    } 
+
+    /** 
+     * The process' initial work directory. 
+     * 
+     * The work directory is the directory in which the process starts 
+     * execution. 
+     */ 
+    Path work_directory; 
+}; 
+
+/** 
+ * Base context class that defines the child's environment. 
+ * 
+ * Base context class that defines the necessary fields to configure a 
+ * child's environment variables. This class is useless on its own 
+ * because no function in the library will accept it as a valid Context 
+ * implementation. 
+ */ 
+class environment_context 
+{ 
+public: 
+    /** 
+     * The process' environment. 
+     * 
+     * Contains the list of environment variables, alongside with their 
+     * values, that will be passed to the spawned child process. 
+     */ 
+    boost::process::environment environment; 
+}; 
+
+/** 
+ * Process startup execution context. 
+ * 
+ * The context class groups all the parameters needed to configure a 
+ * process' environment during its creation. 
+ */ 
+template <class Path> 
+class basic_context : public basic_work_directory_context<Path>, public environment_context 
+{ 
+public: 
+    /** 
+     * Child's stdin behavior. 
+     */ 
+    stream_behavior stdin_behavior; 
+
+    /** 
+     * Child's stdout behavior. 
+     */ 
+    stream_behavior stdout_behavior; 
+
+    /** 
+     * Child's stderr behavior. 
+     */ 
+    stream_behavior stderr_behavior; 
+}; 
+
+typedef basic_context<std::string> context; 
+
+/** 
+ * Represents a child process in a pipeline. 
+ * 
+ * This convenience class is a triplet that holds all the data required 
+ * to spawn a new child process in a pipeline. 
+ */ 
+template <class Executable, class Arguments, class Context> 
+class basic_pipeline_entry 
+{ 
+public: 
+    /** 
+     * The executable to launch. 
+     */ 
+    Executable executable; 
+
+    /** 
+     * The set of arguments to pass to the executable. 
+     */ 
+    Arguments arguments; 
+
+    /** 
+     * The child's execution context. 
+     */ 
+    Context context; 
+
+    /** 
+     * The type of the Executable concept used in this template 
+     * instantiation. 
+     */ 
+    typedef Executable executable_type; 
+
+    /** 
+     * The type of the Arguments concept used in this template 
+     * instantiation. 
+     */ 
+    typedef Arguments arguments_type; 
+
+    /** 
+     * The type of the Context concept used in this template 
+     * instantiation. 
+     */ 
+    typedef Context context_type; 
+
+    /** 
+     * Constructs a new pipeline_entry object. 
+     * 
+     * Given the executable, set of arguments and execution triplet, 
+     * constructs a new pipeline_entry object that holds the three 
+     * values. 
+     */ 
+    basic_pipeline_entry(const Executable &exe, const Arguments &args, const Context &ctx) 
+        : executable(exe), 
+        arguments(args), 
+        context(ctx) 
+    { 
+    } 
+}; 
+
+/** 
+ * Default instantiation of basic_pipeline_entry. 
+ */ 
+typedef basic_pipeline_entry<std::string, std::vector<std::string>, context> pipeline_entry; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/environment.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/environment.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,50 @@
+// 
+// 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/environment.hpp 
+ * 
+ * Includes the declaration of the environment class. 
+ */ 
+
+#ifndef BOOST_PROCESS_ENVIRONMENT_HPP 
+#define BOOST_PROCESS_ENVIRONMENT_HPP 
+
+#include <string> 
+#include <map> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Representation of a process' environment variables. 
+ * 
+ * The environment is a map that stablishes an unidirectional 
+ * association between variable names and their values and is 
+ * represented by a string to string map. 
+ * 
+ * Variables may be defined to the empty string. Be aware that doing so 
+ * is not portable: POSIX systems will treat such variables as being 
+ * defined to the empty value, but Windows systems are not able to 
+ * distinguish them from undefined variables. 
+ * 
+ * Neither POSIX nor Windows systems support a variable with no name. 
+ * 
+ * It is worthy to note that the environment is sorted alphabetically. 
+ * This is provided for-free by the map container used to implement this 
+ * type, and this behavior is required by Windows systems. 
+ */ 
+typedef std::map<std::string, std::string> environment; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/operations.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/operations.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,583 @@
+// 
+// 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/operations.hpp 
+ * 
+ * Provides miscellaneous free functions. 
+ */ 
+
+#ifndef BOOST_PROCESS_OPERATIONS_HPP 
+#define BOOST_PROCESS_OPERATIONS_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <boost/process/detail/posix_ops.hpp> 
+#  include <stdlib.h> 
+#  include <unistd.h> 
+#  if defined(__CYGWIN__) 
+#    include <boost/scoped_array.hpp> 
+#    include <sys/cygwin.h> 
+#  endif 
+#elif defined(BOOST_WINDOWS_API) 
+#  include <boost/process/detail/win32_ops.hpp> 
+#  include <boost/algorithm/string/predicate.hpp> 
+#  include <windows.h> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/child.hpp> 
+#include <boost/process/stream_behavior.hpp> 
+#include <boost/process/status.hpp> 
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/process/detail/pipe.hpp> 
+#include <boost/process/detail/stream_info.hpp> 
+#include <boost/filesystem/path.hpp> 
+#include <boost/algorithm/string/predicate.hpp> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+#include <boost/scoped_array.hpp> 
+#include <boost/assert.hpp> 
+#include <string> 
+#include <vector> 
+#include <stdexcept> 
+#include <cstddef> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Locates the executable program \a file in all the directory components 
+ * specified in \a path. If \a path is empty, the value of the PATH 
+ * environment variable is used. 
+ * 
+ * The path variable is interpreted following the same conventions used 
+ * to parse the PATH environment variable in the underlying platform. 
+ * 
+ * \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 = "") 
+{ 
+#if defined(BOOST_POSIX_API) 
+    BOOST_ASSERT(file.find('/') == std::string::npos); 
+#elif defined(BOOST_WINDOWS_API) 
+    BOOST_ASSERT(file.find_first_of("\\/") == std::string::npos); 
+#endif 
+
+    std::string result; 
+
+#if defined(BOOST_POSIX_API) 
+    if (path.empty()) 
+    { 
+        const char *envpath = ::getenv("PATH"); 
+        if (!envpath) 
+            boost::throw_exception(boost::filesystem::filesystem_error("boost::process::find_executable_in_path: retrieving PATH failed", file, boost::system::errc::make_error_code(boost::system::errc::no_such_file_or_directory))); 
+
+        path = envpath; 
+    } 
+    BOOST_ASSERT(!path.empty()); 
+
+#if defined(__CYGWIN__) 
+    if (!::cygwin_posix_path_list_p(path.c_str())) 
+    { 
+        int size = ::cygwin_win32_to_posix_path_list_buf_size(path.c_str()); 
+        boost::scoped_array<char> cygpath(new char[size]); 
+        ::cygwin_win32_to_posix_path_list(path.c_str(), cygpath.get()); 
+        path = cygpath.get(); 
+    } 
+#endif 
+
+    std::string::size_type pos1 = 0, pos2; 
+    do 
+    { 
+        pos2 = path.find(':', pos1); 
+        std::string dir = (pos2 != std::string::npos) ? path.substr(pos1, pos2 - pos1) : path.substr(pos1); 
+        std::string f = dir + (boost::algorithm::ends_with(dir, "/") ? "" : "/") + file; 
+        if (!::access(f.c_str(), X_OK)) 
+            result = f; 
+        pos1 = pos2 + 1; 
+    } while (pos2 != std::string::npos && result.empty()); 
+#elif defined(BOOST_WINDOWS_API) 
+    const char *exts[] = { "", ".exe", ".com", ".bat", NULL }; 
+    const char **ext = exts; 
+    while (*ext) 
+    { 
+        char buf[MAX_PATH]; 
+        char *dummy; 
+        DWORD size = ::SearchPathA(path.empty() ? NULL : path.c_str(), file.c_str(), *ext, MAX_PATH, buf, &dummy); 
+        BOOST_ASSERT(size < MAX_PATH); 
+        if (size > 0) 
+        { 
+            result = buf; 
+            break; 
+        } 
+        ++ext; 
+    } 
+#endif 
+
+    if (result.empty()) 
+        boost::throw_exception(boost::filesystem::filesystem_error("boost::process::find_executable_in_path: file not found", file, boost::system::errc::make_error_code(boost::system::errc::no_such_file_or_directory))); 
+
+    return result; 
+} 
+
+/** 
+ * Extracts the program name from a given executable. 
+ * 
+ * \return The program name. On Windows the program name 
+ *         is returned without a file extension. 
+ */ 
+inline std::string executable_to_progname(const std::string &exe) 
+{ 
+    std::string::size_type begin = 0; 
+    std::string::size_type end = std::string::npos; 
+
+#if defined(BOOST_POSIX_API) 
+    std::string::size_type slash = exe.rfind('/'); 
+#elif defined(BOOST_WINDOWS_API) 
+    std::string::size_type slash = exe.find_last_of("/\\"); 
+#endif 
+    if (slash != std::string::npos) 
+        begin = slash + 1; 
+
+#if defined(BOOST_WINDOWS_API) 
+    if (exe.size() > 4 && 
+        (boost::algorithm::iends_with(exe, ".exe") || boost::algorithm::iends_with(exe, ".com") || boost::algorithm::iends_with(exe, ".bat"))) 
+        end = exe.size() - 4; 
+#endif 
+
+    return exe.substr(begin, end - begin); 
+} 
+
+/** 
+ * Starts a new child process. 
+ * 
+ * Launches a new process based on the binary image specified by the 
+ * executable, the set of arguments to be passed to it and several 
+ * parameters that describe the execution context. 
+ * 
+ * \remark Blocking remarks: This function may block if the device 
+ * holding the executable blocks when loading the image. This might 
+ * happen if, e.g., the binary is being loaded from a network share. 
+ * 
+ * \return A handle to the new child process. 
+ */ 
+template <class Executable, class Arguments, class Context> 
+inline child launch(const Executable &exe, const Arguments &args, const Context &ctx) 
+{ 
+    detail::file_handle fhstdin, fhstdout, fhstderr; 
+
+    BOOST_ASSERT(!args.empty()); 
+    BOOST_ASSERT(!ctx.work_directory.empty()); 
+
+#if defined(BOOST_POSIX_API) 
+    detail::info_map infoin, infoout; 
+
+    if (ctx.stdin_behavior.get_type() != stream_behavior::close) 
+    { 
+        detail::stream_info si = detail::stream_info(ctx.stdin_behavior, false); 
+        infoin.insert(detail::info_map::value_type(STDIN_FILENO, si)); 
+    } 
+
+    if (ctx.stdout_behavior.get_type() != stream_behavior::close) 
+    { 
+        detail::stream_info si = detail::stream_info(ctx.stdout_behavior, true); 
+        infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si)); 
+    } 
+
+    if (ctx.stderr_behavior.get_type() != stream_behavior::close) 
+    { 
+        detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); 
+        infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); 
+    } 
+
+    detail::posix_setup s; 
+    s.work_directory = ctx.work_directory; 
+
+    child::id_type pid = detail::posix_start(exe, args, ctx.environment, infoin, infoout, s); 
+
+    if (ctx.stdin_behavior.get_type() == stream_behavior::capture) 
+    { 
+        fhstdin = detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false); 
+        BOOST_ASSERT(fhstdin.valid()); 
+    } 
+
+    if (ctx.stdout_behavior.get_type() == stream_behavior::capture) 
+    { 
+        fhstdout = detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true); 
+        BOOST_ASSERT(fhstdout.valid()); 
+    } 
+
+    if (ctx.stderr_behavior.get_type() == stream_behavior::capture) 
+    { 
+        fhstderr = detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true); 
+        BOOST_ASSERT(fhstderr.valid()); 
+    } 
+
+    return child(pid, fhstdin, fhstdout, fhstderr); 
+#elif defined(BOOST_WINDOWS_API) 
+    detail::stream_info behin = detail::stream_info(ctx.stdin_behavior, false); 
+    if (behin.type_ == detail::stream_info::use_pipe) 
+        fhstdin = behin.pipe_->wend(); 
+    detail::stream_info behout = detail::stream_info(ctx.stdout_behavior, true); 
+    if (behout.type_ == detail::stream_info::use_pipe) 
+        fhstdout = behout.pipe_->rend(); 
+    detail::stream_info beherr = detail::stream_info(ctx.stderr_behavior, true); 
+    if (beherr.type_ == detail::stream_info::use_pipe) 
+        fhstderr = beherr.pipe_->rend(); 
+
+    STARTUPINFOA si; 
+    ::ZeroMemory(&si, sizeof(si)); 
+    si.cb = sizeof(si); 
+
+    detail::win32_setup s; 
+    s.work_directory = ctx.work_directory; 
+    s.startupinfo = &si; 
+
+    PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s); 
+
+    if (!::CloseHandle(pi.hThread)) 
+        boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch: CloseHandle failed")); 
+
+    return child(pi.dwProcessId, fhstdin, fhstdout, fhstderr, detail::file_handle(pi.hProcess)); 
+#endif 
+} 
+
+/** 
+ * Launches a shell-based command. 
+ * 
+ * Executes the given command through the default system shell. The 
+ * command is subject to pattern expansion, redirection and pipelining. 
+ * The shell is launched as described by the parameters in the execution 
+ * context. 
+ * 
+ * This function behaves similarly to the system(3) system call. In a 
+ * POSIX system, the command is fed to /bin/sh whereas under a Windows 
+ * system, it is fed to cmd.exe. It is difficult to write portable 
+ * commands as the first parameter, but this function comes in handy in 
+ * multiple situations. 
+ */ 
+template <class Context> 
+inline child launch_shell(const std::string &command, const Context &ctx) 
+{ 
+    std::string exe; 
+    std::vector<std::string> args; 
+
+#if defined(BOOST_POSIX_API) 
+    exe = "/bin/sh"; 
+    args.push_back("sh"); 
+    args.push_back("-c"); 
+    args.push_back(command); 
+#elif defined(BOOST_WINDOWS_API) 
+    char sysdir[MAX_PATH]; 
+    UINT size = ::GetSystemDirectoryA(sysdir, sizeof(sysdir)); 
+    if (!size) 
+        boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_shell: GetWindowsDirectory failed")); 
+    BOOST_ASSERT(size < MAX_PATH); 
+
+    exe = std::string(sysdir) + (sysdir[size - 1] != '\\' ? "\\cmd.exe" : "cmd.exe"); 
+    args.push_back("cmd"); 
+    args.push_back("/c"); 
+    args.push_back(command); 
+#endif 
+
+    return launch(exe, args, ctx); 
+} 
+
+/** 
+ * Launches a pipelined set of child processes. 
+ * 
+ * Given a collection of pipeline_entry objects describing how to launch 
+ * a set of child processes, spawns them all and connects their inputs and 
+ * outputs in a way that permits pipelined communication. 
+ * 
+ * \pre Let 1..N be the processes in the collection: the input behavior of 
+ *      the 2..N processes must be set to close_stream(). 
+ * \pre Let 1..N be the processes in the collection: the output behavior of 
+ *      the 1..N-1 processes must be set to close_stream(). 
+ * \remark Blocking remarks: This function may block if the device holding 
+ *         the executable of one of the entries blocks when loading the 
+ *         image. This might happen if, e.g., the binary is being loaded 
+ *         from a network share. 
+ * \return A set of Child objects that represent all the processes spawned 
+ *         by this call. You should use wait_children() to wait for their 
+ *         termination. 
+ */ 
+template <class Entries> 
+inline children launch_pipeline(const Entries &entries) 
+{ 
+    BOOST_ASSERT(entries.size() >= 2); 
+
+    children cs; 
+    detail::file_handle fhinvalid; 
+
+    boost::scoped_array<detail::pipe> pipes(new detail::pipe[entries.size() - 1]); 
+
+#if defined(BOOST_POSIX_API) 
+    { 
+        typename Entries::size_type i = 0; 
+        const typename Entries::value_type::context_type &ctx = entries[i].context; 
+
+        detail::info_map infoin, infoout; 
+
+        if (ctx.stdin_behavior.get_type() != stream_behavior::close) 
+        { 
+            detail::stream_info si = detail::stream_info(ctx.stdin_behavior, false); 
+            infoin.insert(detail::info_map::value_type(STDIN_FILENO, si)); 
+        } 
+
+        BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); 
+        detail::stream_info si2(close_stream(), true); 
+        si2.type_ = detail::stream_info::use_handle; 
+        si2.handle_ = pipes[i].wend().release(); 
+        infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2)); 
+
+        if (ctx.stderr_behavior.get_type() != stream_behavior::close) 
+        { 
+            detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); 
+            infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); 
+        } 
+
+        detail::posix_setup s; 
+        s.work_directory = ctx.work_directory; 
+
+        pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); 
+
+        detail::file_handle fhstdin; 
+
+        if (ctx.stdin_behavior.get_type() == stream_behavior::capture) 
+        { 
+            fhstdin = detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false); 
+            BOOST_ASSERT(fhstdin.valid()); 
+        } 
+
+        cs.push_back(child(pid, fhstdin, fhinvalid, fhinvalid)); 
+    } 
+
+    for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i) 
+    { 
+        const typename Entries::value_type::context_type &ctx = entries[i].context; 
+        detail::info_map infoin, infoout; 
+
+        BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); 
+        detail::stream_info si1(close_stream(), false); 
+        si1.type_ = detail::stream_info::use_handle; 
+        si1.handle_ = pipes[i - 1].rend().release(); 
+        infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1)); 
+
+        BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); 
+        detail::stream_info si2(close_stream(), true); 
+        si2.type_ = detail::stream_info::use_handle; 
+        si2.handle_ = pipes[i].wend().release(); 
+        infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2)); 
+
+        if (ctx.stderr_behavior.get_type() != stream_behavior::close) 
+        { 
+            detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); 
+            infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); 
+        } 
+
+        detail::posix_setup s; 
+        s.work_directory = ctx.work_directory; 
+
+        pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); 
+
+        cs.push_back(child(pid, fhinvalid, fhinvalid, fhinvalid)); 
+    } 
+
+    { 
+        typename Entries::size_type i = entries.size() - 1; 
+        const typename Entries::value_type::context_type &ctx = entries[i].context; 
+
+        detail::info_map infoin, infoout; 
+
+        BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); 
+        detail::stream_info si1(close_stream(), false); 
+        si1.type_ = detail::stream_info::use_handle; 
+        si1.handle_ = pipes[i - 1].rend().release(); 
+        infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1)); 
+
+        if (ctx.stdout_behavior.get_type() != stream_behavior::close) 
+        { 
+            detail::stream_info si = detail::stream_info(ctx.stdout_behavior, true); 
+            infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si)); 
+        } 
+
+        if (ctx.stderr_behavior.get_type() != stream_behavior::close) 
+        { 
+            detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); 
+            infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); 
+        } 
+
+        detail::posix_setup s; 
+        s.work_directory = ctx.work_directory; 
+
+        pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); 
+
+        detail::file_handle fhstdout, fhstderr; 
+
+        if (ctx.stdout_behavior.get_type() == stream_behavior::capture) 
+        { 
+            fhstdout = detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true); 
+            BOOST_ASSERT(fhstdout.valid()); 
+        } 
+
+        if (ctx.stderr_behavior.get_type() == stream_behavior::capture) 
+        { 
+            fhstderr = detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true); 
+            BOOST_ASSERT(fhstderr.valid()); 
+        } 
+
+        cs.push_back(child(pid, fhinvalid, fhstdout, fhstderr)); 
+    } 
+#elif defined(BOOST_WINDOWS_API) 
+    STARTUPINFOA si; 
+    detail::win32_setup s; 
+    s.startupinfo = &si; 
+
+    { 
+        typename Entries::size_type i = 0; 
+        const typename Entries::value_type::context_type &ctx = entries[i].context; 
+
+        detail::stream_info sii = detail::stream_info(ctx.stdin_behavior, false); 
+        detail::file_handle fhstdin; 
+        if (sii.type_ == detail::stream_info::use_pipe) 
+            fhstdin = sii.pipe_->wend(); 
+
+        BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); 
+        detail::stream_info sio(close_stream(), true); 
+        sio.type_ = detail::stream_info::use_handle; 
+        sio.handle_ = pipes[i].wend().release(); 
+
+        detail::stream_info sie(ctx.stderr_behavior, true); 
+
+        s.work_directory = ctx.work_directory; 
+
+        ::ZeroMemory(&si, sizeof(si)); 
+        si.cb = sizeof(si); 
+        PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); 
+
+        if (!::CloseHandle(pi.hThread)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); 
+
+        cs.push_back(child(pi.dwProcessId, fhstdin, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess))); 
+    } 
+
+    for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i) 
+    { 
+        const typename Entries::value_type::context_type &ctx = entries[i].context; 
+
+        BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); 
+        detail::stream_info sii(close_stream(), false); 
+        sii.type_ = detail::stream_info::use_handle; 
+        sii.handle_ = pipes[i - 1].rend().release(); 
+
+        detail::stream_info sio(close_stream(), true); 
+        sio.type_ = detail::stream_info::use_handle; 
+        sio.handle_ = pipes[i].wend().release(); 
+
+        detail::stream_info sie(ctx.stderr_behavior, true); 
+
+        s.work_directory = ctx.work_directory; 
+
+        ::ZeroMemory(&si, sizeof(si)); 
+        si.cb = sizeof(si); 
+        PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); 
+
+        if (!::CloseHandle(pi.hThread)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); 
+
+        cs.push_back(child(pi.dwProcessId, fhinvalid, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess))); 
+    } 
+
+    { 
+        typename Entries::size_type i = entries.size() - 1; 
+        const typename Entries::value_type::context_type &ctx = entries[i].context; 
+
+        BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); 
+        detail::stream_info sii(close_stream(), false); 
+        sii.type_ = detail::stream_info::use_handle; 
+        sii.handle_ = pipes[i - 1].rend().release(); 
+
+        detail::file_handle fhstdout, fhstderr; 
+
+        detail::stream_info sio(ctx.stdout_behavior, true); 
+        if (sio.type_ == detail::stream_info::use_pipe) 
+            fhstdout = sio.pipe_->rend(); 
+        detail::stream_info sie(ctx.stderr_behavior, true); 
+        if (sie.type_ == detail::stream_info::use_pipe) 
+            fhstderr = sie.pipe_->rend(); 
+
+        s.work_directory = ctx.work_directory; 
+
+        ::ZeroMemory(&si, sizeof(si)); 
+        si.cb = sizeof(si); 
+        PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); 
+
+        if (!::CloseHandle(pi.hThread)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); 
+
+        cs.push_back(child(pi.dwProcessId, fhinvalid, fhstdout, fhstderr, detail::file_handle(pi.hProcess))); 
+    } 
+#endif 
+
+    return cs; 
+} 
+
+/** 
+ * Waits for a collection of children to terminate. 
+ * 
+ * Given a collection of Child objects (such as std::vector<child> or 
+ * the convenience children type), waits for the termination of all of 
+ * them. 
+ * 
+ * \remark Blocking remarks: This call blocks if any of the children 
+ *         processes in the collection has not finalized execution and 
+ *         waits until it terminates. 
+ * 
+ * \return The exit status of the first process that returns an error 
+ *         code or, if all of them executed correctly, the exit status 
+ *         of the last process in the collection. 
+ */ 
+template <class Children> 
+inline status wait_children(Children &cs) 
+{ 
+    BOOST_ASSERT(cs.size() >= 2); 
+
+    typename Children::iterator it = cs.begin(); 
+    while (it != cs.end()) 
+    { 
+        const status s = it->wait(); 
+        ++it; 
+        if (it == cs.end()) 
+            return s; 
+        else if (!s.exited() || s.exit_status() != EXIT_SUCCESS) 
+        { 
+            while (it != cs.end()) 
+            { 
+                it->wait(); 
+                ++it; 
+            } 
+            return s; 
+        } 
+    } 
+
+    BOOST_ASSERT(false); 
+    return cs.begin()->wait(); 
+} 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/pistream.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/pistream.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,116 @@
+// 
+// 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/pistream.hpp 
+ * 
+ * Includes the declaration of the pistream class. 
+ */ 
+
+#ifndef BOOST_PROCESS_PISTREAM_HPP 
+#define BOOST_PROCESS_PISTREAM_HPP 
+
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/process/detail/systembuf.hpp> 
+#include <boost/noncopyable.hpp> 
+#include <istream> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Child process' output stream. 
+ * 
+ * The pistream class represents an output communication channel with the 
+ * child process. The child process writes data to this stream and the 
+ * parent process can read it through the pistream object. In other 
+ * words, from the child's point of view, the communication channel is an 
+ * 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 
+ * that flows through the communication channel. 
+ * 
+ * A pistream object behaves as a std::istream 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 read data from this 
+ *         stream can block if the associated file 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 
+ *         the pipe's system buffer. When this happens, the buffer 
+ *         eventually empties and the system blocks until the writer 
+ *         generates some data. 
+ */ 
+class pistream : public std::istream, public boost::noncopyable 
+{ 
+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) 
+        : std::istream(0), 
+        handle_(fh), 
+        systembuf_(handle_.get()) 
+    { 
+        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. 
+     */ 
+    detail::file_handle &handle() 
+    { 
+        return handle_; 
+    } 
+
+    /** 
+     * Closes the file handle managed by this stream. 
+     * 
+     * Explicitly closes the file 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. 
+     */ 
+    void close() 
+    { 
+        handle_.close(); 
+    } 
+
+private: 
+    /** 
+     * The file handle managed by this stream. 
+     */ 
+    detail::file_handle handle_; 
+
+    /** 
+     * The systembuf object used to manage this stream's data. 
+     */ 
+    detail::systembuf systembuf_; 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/posix_child.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/posix_child.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,178 @@
+// 
+// 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/posix_child.hpp 
+ * 
+ * Includes the declaration of the posix_child class. 
+ */ 
+
+#ifndef BOOST_PROCESS_POSIX_CHILD_HPP 
+#define BOOST_PROCESS_POSIX_CHILD_HPP 
+
+#include <boost/process/child.hpp> 
+#include <boost/process/pistream.hpp> 
+#include <boost/process/postream.hpp> 
+#include <boost/process/detail/pipe.hpp> 
+#include <boost/process/detail/posix_ops.hpp> 
+#include <boost/process/detail/stream_info.hpp> 
+#include <boost/shared_ptr.hpp> 
+#include <boost/assert.hpp> 
+#include <map> 
+#include <unistd.h> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * POSIX implementation of the Child concept. 
+ * 
+ * The posix_child class implements the Child concept in a POSIX 
+ * operating system. 
+ * 
+ * A POSIX child differs from a regular child (represented by a 
+ * child object) in that it supports more than three communication 
+ * channels with its parent. These channels are identified by regular 
+ * file descriptors (integers). 
+ * 
+ * This class is built on top of the generic child so as to allow its 
+ * trivial adoption. When a program is changed to use the POSIX-specific 
+ * context (posix_context), it will most certainly need to migrate its 
+ * use of the child class to posix_child. Doing so is only a matter of 
+ * redefining the appropriate object and later using the required extra 
+ * features: there should be no need to modify the existing code (e.g. 
+ * method calls) in any other way. 
+ */ 
+class posix_child : public child 
+{ 
+public: 
+    /** 
+     * Gets a reference to the child's input stream \a desc. 
+     * 
+     * Returns a reference to a postream object that represents one of 
+     * the multiple input communication channels with the child process. 
+     * The channel is identified by \a desc as seen from the child's 
+     * point of view. The parent can use the returned stream to send 
+     * data to the child. 
+     * 
+     * Giving this function the STDIN_FILENO constant (defined in 
+     * unistd.h) is a synonym for the get_stdin() call inherited from 
+     * child. 
+     */ 
+    postream &get_input(int desc) const 
+    { 
+        if (desc == STDIN_FILENO) 
+            return posix_child::get_stdin(); 
+        else 
+        { 
+            input_map_t::const_iterator it = input_map_.find(desc); 
+            BOOST_ASSERT(it != input_map_.end()); 
+            return *it->second; 
+        } 
+    } 
+
+    /** 
+     * Gets a reference to the child's output stream \a desc. 
+     * 
+     * Returns a reference to a pistream object that represents one of 
+     * the multiple output communication channels with the child process. 
+     * The channel is identified by \a desc as seen from the child's 
+     * point of view. The parent can use the returned stream to retrieve 
+     * data from the child. 
+     * 
+     * Giving this function the STDOUT_FILENO or STDERR_FILENO constants 
+     * (both defined in unistd.h) are synonyms for the get_stdout() and 
+     * get_stderr() calls inherited from child, respectively. 
+     */ 
+    pistream &get_output(int desc) const 
+    { 
+        if (desc == STDOUT_FILENO) 
+            return posix_child::get_stdout(); 
+        else if (desc == STDERR_FILENO) 
+            return posix_child::get_stderr(); 
+        else 
+        { 
+            output_map_t::const_iterator it = output_map_.find(desc); 
+            BOOST_ASSERT(it != output_map_.end()); 
+            return *it->second; 
+        } 
+    } 
+
+    /** 
+     * Constructs a new POSIX child object representing a just 
+     * spawned child process. 
+     * 
+     * Creates a new child object that represents the just spawned process 
+     * \a id. 
+     * 
+     * The \a infoin and \a infoout maps contain the pipes used to handle 
+     * the redirections of the child process; at the moment, no other 
+     * stream_info types are supported. If the launcher was asked to 
+     * redirect any of the three standard flows, their pipes must be 
+     * present in these maps. 
+     */ 
+    posix_child(id_type id, detail::info_map &infoin, detail::info_map &infoout) 
+        : child(id, 
+        detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false), 
+        detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true), 
+        detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true)) 
+    { 
+        for (detail::info_map::iterator it = infoin.begin(); it != infoin.end(); ++it) 
+        { 
+            detail::stream_info &si = it->second; 
+            if (si.type_ == detail::stream_info::use_pipe) 
+            { 
+                BOOST_ASSERT(si.pipe_->wend().valid()); 
+                boost::shared_ptr<postream> st(new postream(si.pipe_->wend())); 
+                input_map_.insert(input_map_t::value_type(it->first, st)); 
+            } 
+        } 
+
+        for (detail::info_map::iterator it = infoout.begin(); it != infoout.end(); ++it) 
+        { 
+            detail::stream_info &si = it->second; 
+            if (si.type_ == detail::stream_info::use_pipe) 
+            { 
+                BOOST_ASSERT(si.pipe_->rend().valid()); 
+                boost::shared_ptr<pistream> st(new pistream(si.pipe_->rend())); 
+                output_map_.insert(output_map_t::value_type(it->first, st)); 
+            } 
+        } 
+    } 
+
+private: 
+    /** 
+     * Maps child's file descriptors to postream objects. 
+     */ 
+    typedef std::map<int, boost::shared_ptr<postream> > input_map_t; 
+
+    /** 
+     * Contains all relationships between child's input file 
+     * descriptors and their corresponding postream objects. 
+     */ 
+    input_map_t input_map_; 
+
+    /** 
+     * Maps child's file descriptors to pistream objects. 
+     */ 
+    typedef std::map<int, boost::shared_ptr<pistream> > output_map_t; 
+
+    /** 
+     * Contains all relationships between child's output file 
+     * descriptors and their corresponding pistream objects. 
+     */ 
+    output_map_t output_map_; 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/posix_context.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/posix_context.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,118 @@
+// 
+// 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/posix_context.hpp 
+ * 
+ * Includes the declaration of the posix_context class. 
+ */ 
+
+#ifndef BOOST_PROCESS_POSIX_CONTEXT_HPP 
+#define BOOST_PROCESS_POSIX_CONTEXT_HPP 
+
+#include <boost/process/context.hpp> 
+#include <boost/process/stream_behavior.hpp> 
+#include <map> 
+#include <string> 
+#include <unistd.h> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * 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_behavior> behavior_map; 
+
+template <class Path> 
+class posix_basic_context : public basic_work_directory_context<Path>, public environment_context 
+{ 
+public: 
+    /** 
+     * Constructs a new POSIX-specific context. 
+     * 
+     * Constructs a new context. It is configured as follows: 
+     * * All communcation channels with the child process are closed. 
+     * * There are no channel mergings. 
+     * * The initial work directory of the child processes is set to the 
+     *   current working directory. 
+     * * The environment variables table is empty. 
+     * * The credentials are the same as those of the current process. 
+     */ 
+    posix_basic_context() 
+        : uid(::getuid()), 
+        euid(::geteuid()), 
+        gid(::getgid()), 
+        egid(::getegid()) 
+    { 
+    } 
+
+    /** 
+     * List of input streams that will be redirected. 
+     */ 
+    behavior_map input_behavior; 
+
+    /** 
+     * List of output streams that will be redirected. 
+     */ 
+    behavior_map output_behavior; 
+
+    /** 
+     * 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; 
+
+    /** 
+     * The chroot directory, if any. 
+     * 
+     * Specifies the directory in which the %child process is chrooted 
+     * before execution. Empty if this feature is not desired. 
+     */ 
+    Path chroot; 
+}; 
+
+/** 
+ * Default instantiation of posix_basic_context. 
+ */ 
+typedef posix_basic_context<std::string> posix_context; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/posix_operations.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/posix_operations.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,81 @@
+// 
+// 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/posix_operations.hpp 
+ * 
+ * Provides miscellaneous free functions specific to POSIX operating 
+ * systems. 
+ */ 
+
+#ifndef BOOST_PROCESS_POSIX_OPERATIONS_HPP 
+#define BOOST_PROCESS_POSIX_OPERATIONS_HPP 
+
+#include <boost/process/posix_child.hpp> 
+#include <boost/process/posix_context.hpp> 
+#include <boost/process/stream_behavior.hpp> 
+#include <boost/process/detail/stream_info.hpp> 
+#include <boost/process/detail/posix_ops.hpp> 
+#include <sys/types.h> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Starts a new child process. 
+ * 
+ * Given an executable and the set of arguments passed to it, starts 
+ * a new process with all the parameters configured in the context. 
+ * The context can be reused afterwards to launch other different 
+ * processes. 
+ * 
+ * \return A handle to the new child process. 
+ */ 
+template <class Executable, class Arguments, class Posix_Context> 
+inline posix_child posix_launch(const Executable &exe, const Arguments &args, const Posix_Context &ctx) 
+{ 
+    detail::info_map input_info; 
+    for (behavior_map::const_iterator it = ctx.input_behavior.begin(); it != ctx.input_behavior.end(); ++it) 
+    { 
+        if (it->second.get_type() != stream_behavior::close) 
+        { 
+            detail::stream_info si = detail::stream_info(it->second, false); 
+            input_info.insert(detail::info_map::value_type(it->first, si)); 
+        } 
+    } 
+
+    detail::info_map output_info; 
+    for (behavior_map::const_iterator it = ctx.output_behavior.begin(); it != ctx.output_behavior.end(); ++it) 
+    { 
+        if (it->second.get_type() != stream_behavior::close) 
+        { 
+            detail::stream_info si = detail::stream_info(it->second, true); 
+            output_info.insert(detail::info_map::value_type(it->first, si)); 
+        } 
+    } 
+
+    detail::posix_setup s; 
+    s.work_directory = ctx.work_directory; 
+    s.uid = ctx.uid; 
+    s.euid = ctx.euid; 
+    s.gid = ctx.gid; 
+    s.egid = ctx.egid; 
+    s.chroot = ctx.chroot; 
+
+    pid_t pid = detail::posix_start(exe, args, ctx.environment, input_info, output_info, s); 
+
+    return posix_child(pid, input_info, output_info); 
+} 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/posix_status.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/posix_status.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,128 @@
+// 
+// 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/posix_status.hpp 
+ * 
+ * Includes the declaration of the posix_status class. 
+ */ 
+
+#ifndef BOOST_PROCESS_POSIX_STATUS_HPP 
+#define BOOST_PROCESS_POSIX_STATUS_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <sys/wait.h> 
+#elif defined(BOOST_WINDOWS_API) 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/status.hpp> 
+#include <boost/assert.hpp> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Status returned by a finalized %child process on a POSIX system. 
+ * 
+ * This class represents the %status returned by a child process after it 
+ * has terminated. It contains some methods not available in the status 
+ * class that provide information only available in POSIX systems. 
+ */ 
+class posix_status : public status 
+{ 
+public: 
+    /** 
+     * Creates a posix_status object from an existing status object. 
+     * 
+     * Creates a new status object representing the exit status of a 
+     * child process. The construction is done based on an existing 
+     * status object which already contains all the available 
+     * information: this class only provides controlled access to it. 
+     */ 
+    posix_status(const status &s) 
+        : status(s) 
+    { 
+    } 
+
+    /** 
+     * Returns whether the process exited due to an external 
+     * signal. 
+     */ 
+    bool signaled() const 
+    { 
+        return WIFSIGNALED(flags_); 
+    } 
+
+    /** 
+     * If signaled, returns the terminating signal code. 
+     * 
+     * If the process was signaled, returns the terminating signal code. 
+     * 
+     * \pre signaled() is true. 
+     */ 
+    int term_signal() const 
+    { 
+        BOOST_ASSERT(signaled()); 
+
+        return WTERMSIG(flags_); 
+    } 
+
+    /** 
+     * If signaled, returns whether the process dumped core. 
+     * 
+     * If the process was signaled, returns whether the process 
+     * produced a core dump. 
+     * 
+     * \pre signaled() is true. 
+     */ 
+    bool dumped_core() const 
+    { 
+        BOOST_ASSERT(signaled()); 
+
+#ifdef WCOREDUMP 
+        return WCOREDUMP(flags_); 
+#else 
+        return false; 
+#endif 
+    } 
+
+    /** 
+     * Returns whether the process was stopped by an external 
+     * signal. 
+     */ 
+    bool stopped() const 
+    { 
+        return WIFSTOPPED(flags_); 
+    } 
+
+    /** 
+     * If stopped, returns the stop signal code. 
+     * 
+     * If the process was stopped, returns the stop signal code. 
+     * 
+     * \pre stopped() is true. 
+     */ 
+    int stop_signal() const 
+    { 
+        BOOST_ASSERT(stopped()); 
+
+        return WSTOPSIG(flags_); 
+    } 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/postream.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/postream.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,117 @@
+// 
+// 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/postream.hpp 
+ * 
+ * Includes the declaration of the postream class. 
+ */ 
+
+#ifndef BOOST_PROCESS_POSTREAM_HPP 
+#define BOOST_PROCESS_POSTREAM_HPP 
+
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/process/detail/systembuf.hpp> 
+#include <boost/noncopyable.hpp> 
+#include <ostream> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Child process' input stream. 
+ * 
+ * The postream class represents an input communication channel with the 
+ * child process. The child process reads data from this stream and the 
+ * parent process can write to it through the postream object. In other 
+ * words, from the child's point of view, the communication channel is an 
+ * 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. 
+ * 
+ * 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 
+ *         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 
+ *         in the pipe's system buffer. When this happens, the buffer 
+ *         eventually fills up and the system blocks until the reader 
+ *         consumes some data, leaving some new room. 
+ */ 
+class postream : public std::ostream, public boost::noncopyable 
+{ 
+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) 
+        : std::ostream(0), 
+        handle_(fh), 
+        systembuf_(handle_.get()) 
+    { 
+        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. 
+     */ 
+    detail::file_handle &handle() 
+    { 
+        return handle_; 
+    } 
+
+    /** 
+     * Closes the file handle managed by this stream. 
+     * 
+     * Explicitly closes the file 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. 
+     */ 
+    void close() 
+    { 
+        systembuf_.sync(); 
+        handle_.close(); 
+    } 
+
+private: 
+    /** 
+     * The file handle managed by this stream. 
+     */ 
+    detail::file_handle handle_; 
+
+    /** 
+     * The systembuf object used to manage this stream's data. 
+     */ 
+    detail::systembuf systembuf_; 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/process.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/process.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,130 @@
+// 
+// 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/process.hpp 
+ * 
+ * Includes the declaration of the process class. 
+ */ 
+
+#ifndef BOOST_PROCESS_PROCESS_HPP 
+#define BOOST_PROCESS_PROCESS_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <cerrno> 
+#  include <signal.h> 
+#elif defined(BOOST_WINDOWS_API) 
+#  include <cstdlib> 
+#  include <windows.h> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Generic implementation of the Process concept. 
+ * 
+ * The process class implements the Process concept in an operating system 
+ * agnostic way. 
+ */ 
+class process 
+{ 
+public: 
+#if defined(BOOST_PROCESS_DOXYGEN) 
+    /** 
+     * Opaque name for the native process' identifier type. 
+     * 
+     * Each operating system identifies processes using a specific type. 
+     * The \a id_type type is used to transparently refer to a process 
+     * regardless of the operating system in which this class is used. 
+     * 
+     * This type is guaranteed to be an integral type on all supported 
+     * platforms. 
+     */ 
+    typedef NativeProcessId id_type; 
+#elif defined(BOOST_POSIX_API) 
+    typedef pid_t id_type; 
+#elif defined(BOOST_WINDOWS_API) 
+    typedef DWORD id_type; 
+#endif 
+
+    /** 
+     * Constructs a new process object. 
+     * 
+     * Creates a new process object that represents a running process 
+     * within the system. 
+     */ 
+    process(id_type id) 
+        : id_(id) 
+    { 
+    } 
+
+    /** 
+     * Returns the process' identifier. 
+     */ 
+    id_type get_id() const 
+    { 
+        return id_; 
+    } 
+
+    /** 
+     * Terminates the process execution. 
+     * 
+     * Forces the termination of the process execution. Some platforms 
+     * allow processes to ignore some external termination notifications 
+     * or to capture them for a proper exit cleanup. You can set the 
+     * \a force flag to true in them to force their termination regardless 
+     * of any exit handler. 
+     * 
+     * After this call, accessing this object can be dangerous because the 
+     * process identifier may have been reused by a different process. It 
+     * might still be valid, though, if the process has refused to die. 
+     * 
+     * \throw boost::system::system_error If the system call used to 
+     *        terminate the process fails. 
+     */ 
+    void terminate(bool force = false) const 
+    { 
+#if defined(BOOST_POSIX_API) 
+        if (::kill(id_, force ? SIGKILL : SIGTERM) == -1) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::process::terminate: kill(2) failed")); 
+#elif defined(BOOST_WINDOWS_API) 
+        HANDLE h = ::OpenProcess(PROCESS_TERMINATE, FALSE, id_); 
+        if (h == NULL) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: OpenProcess failed")); 
+        if (!::TerminateProcess(h, EXIT_FAILURE)) 
+        { 
+            ::CloseHandle(h); 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: TerminateProcess failed")); 
+        } 
+        if (!::CloseHandle(h)) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: CloseHandle failed")); 
+#endif 
+    } 
+
+private: 
+    /** 
+     * The process' identifier. 
+     */ 
+    id_type id_; 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/self.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/self.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,141 @@
+// 
+// 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/self.hpp 
+ * 
+ * Includes the declaration of the self class. 
+ */ 
+
+#ifndef BOOST_PROCESS_SELF_HPP 
+#define BOOST_PROCESS_SELF_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <unistd.h> 
+#  if defined(__APPLE__) 
+#    include <crt_externs.h> 
+#  endif 
+#elif defined(BOOST_WINDOWS_API) 
+#  include <windows.h> 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/process/process.hpp> 
+#include <boost/process/environment.hpp> 
+#include <boost/system/system_error.hpp> 
+#include <boost/throw_exception.hpp> 
+#include <boost/noncopyable.hpp> 
+#include <string> 
+
+#if defined(BOOST_POSIX_API) 
+extern "C" 
+{ 
+    extern char **environ; 
+} 
+#endif 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Generic implementation of the Process concept. 
+ * 
+ * The self singleton provides access to the current process. 
+ */ 
+class self : public process, boost::noncopyable 
+{ 
+public: 
+    /** 
+     * Returns the self instance representing the caller's process. 
+     */ 
+    static self &get_instance() 
+    { 
+        static self *instance = 0; 
+        if (!instance) 
+            instance = new self; 
+        return *instance; 
+    } 
+
+    /** 
+     * Returns the current environment. 
+     * 
+     * Returns the current process' environment variables. Modifying the 
+     * returned object has no effect on the current environment. 
+     */ 
+    static environment get_environment() 
+    { 
+        environment e; 
+
+#if defined(BOOST_POSIX_API) 
+#  if defined(__APPLE__) 
+        char **env = *_NSGetEnviron(); 
+#  else 
+        char **env = ::environ; 
+#  endif 
+        while (*env) 
+        { 
+            std::string s = *env; 
+            std::string::size_type pos = s.find('='); 
+            e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1))); 
+            ++env; 
+        } 
+#elif defined(BOOST_WINDOWS_API) 
+#ifdef GetEnvironmentStrings 
+#undef GetEnvironmentStrings 
+#endif 
+        char *ms_environ = ::GetEnvironmentStrings(); 
+        if (!ms_environ) 
+            boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::self::get_environment: GetEnvironmentStrings failed")); 
+        try 
+        { 
+            char *env = ms_environ; 
+            while (*env) 
+            { 
+                std::string s = env; 
+                std::string::size_type pos = s.find('='); 
+                e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1))); 
+                env += s.size() + 1; 
+            } 
+        } 
+        catch (...) 
+        { 
+            ::FreeEnvironmentStringsA(ms_environ); 
+            throw; 
+        } 
+        ::FreeEnvironmentStringsA(ms_environ); 
+#endif 
+
+        return e; 
+    } 
+
+private: 
+    /** 
+     * Constructs a new self object. 
+     * 
+     * Creates a new self object that represents the current process. 
+     */ 
+    self() : 
+#if defined(BOOST_POSIX_API) 
+       process(::getpid()) 
+#elif defined(BOOST_WINDOWS_API) 
+       process(::GetCurrentProcessId()) 
+#endif 
+       { 
+       } 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/status.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/status.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,105 @@
+// 
+// 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/status.hpp 
+ * 
+ * Includes the declaration of the status class. 
+ */ 
+
+#ifndef BOOST_PROCESS_STATUS_HPP 
+#define BOOST_PROCESS_STATUS_HPP 
+
+#include <boost/process/config.hpp> 
+
+#if defined(BOOST_POSIX_API) 
+#  include <sys/wait.h> 
+#elif defined(BOOST_WINDOWS_API) 
+#else 
+#  error "Unsupported platform." 
+#endif 
+
+#include <boost/assert.hpp> 
+
+namespace boost { 
+namespace process { 
+
+class child; 
+
+/** 
+ * Status returned by a finalized %child process. 
+ * 
+ * This class represents the %status returned by a child process after it 
+ * has terminated. It only provides that information available under all 
+ * supported platforms. 
+ * 
+ * \see posix_status 
+ */ 
+class status 
+{ 
+    friend class child; 
+
+public: 
+    /** 
+     * Returns whether the process exited gracefully or not. 
+     */ 
+    bool exited() const 
+    { 
+#if defined(BOOST_POSIX_API) 
+        return WIFEXITED(flags_); 
+#elif defined(BOOST_WINDOWS_API) 
+        return true; 
+#endif 
+    } 
+
+    /** 
+     * If exited, returns the exit code. 
+     * 
+     * If the process exited, returns the exit code it returned. 
+     * 
+     * \pre exited() is true. 
+     */ 
+    int exit_status() const 
+    { 
+        BOOST_ASSERT(exited()); 
+#if defined(BOOST_POSIX_API) 
+        return WEXITSTATUS(flags_); 
+#elif defined(BOOST_WINDOWS_API) 
+        return flags_; 
+#endif 
+    } 
+
+protected: 
+    /** 
+     * Creates a status object based on exit information. 
+     * 
+     * Creates a new status object representing the exit status of a 
+     * child process. 
+     * 
+     * \param flags In a POSIX system this parameter contains the 
+     *        flags returned by the ::waitpid() call. In a 
+     *        Windows system it contains the exit code only. 
+     */ 
+    status(int flags) 
+        : flags_(flags) 
+    { 
+    } 
+
+    /** 
+     * OS-specific codification of exit status. 
+     */ 
+    int flags_; 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/stream_behavior.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/stream_behavior.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,234 @@
+// 
+// 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/stream_behavior.hpp 
+ * 
+ * Includes the declaration of the stream_behavior class and associated 
+ * free functions. 
+ */ 
+
+#ifndef BOOST_PROCESS_STREAM_BEHAVIOR_HPP 
+#define BOOST_PROCESS_STREAM_BEHAVIOR_HPP 
+
+#include <boost/process/config.hpp> 
+
+namespace boost { 
+namespace process { 
+
+namespace detail { 
+    struct stream_info; 
+} 
+
+/** 
+ * Describes the possible states for a communication stream. 
+ */ 
+class stream_behavior 
+{ 
+public: 
+    friend struct detail::stream_info; 
+    friend stream_behavior capture_stream(); 
+    friend stream_behavior close_stream(); 
+    friend stream_behavior inherit_stream(); 
+    friend stream_behavior redirect_stream_to_stdout(); 
+    friend stream_behavior silence_stream(); 
+#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) 
+    friend stream_behavior posix_redirect_stream(int to); 
+#endif 
+
+    /** 
+     * Describes the possible states for a communication stream. 
+     */ 
+    enum type 
+    { 
+        /** 
+         * The child's stream is connected to the parent by using an 
+         * anonymous pipe so that they can send and receive data to/from 
+         * each other. 
+         */ 
+        capture, 
+
+        /** 
+         * The child's stream is closed upon startup so that it will not 
+         * have any access to it. 
+         */ 
+        close, 
+
+        /** 
+         * The child's stream is connected to the same stream used by the 
+         * parent. In other words, the corresponding parent's stream is 
+         * inherited. 
+         */ 
+        inherit, 
+
+        /** 
+         * The child's stream is connected to child's standard output. 
+         * This is typically used when configuring the standard error 
+         * stream. 
+         */ 
+        redirect_to_stdout, 
+
+        /** 
+         * The child's stream is redirected to a null device so that its 
+         * input is always zero or its output is lost, depending on 
+         * whether the stream is an input or an output one. It is 
+         * important to notice that this is different from close because 
+         * the child is still able to write data. If we closed, e.g. 
+         * stdout, the child might not work at all! 
+         */ 
+        silence, 
+
+#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) 
+        /** 
+         * The child redirects the stream's output to the provided file 
+         * descriptor. This is a generalization of the portable 
+         * redirect_to_stdout behavior. 
+         */ 
+        posix_redirect 
+#endif 
+    }; 
+
+    /** 
+     * Constructs a new stream behavior of type close. 
+     * 
+     * The public constructor creates a new stream behavior that defaults 
+     * to the close behavior. In general, you will want to use the 
+     * available free functions to construct a stream behavior (including 
+     * the close one). 
+     */ 
+    stream_behavior() 
+        : type_(stream_behavior::close) 
+    { 
+    } 
+
+    /** 
+     * Returns this stream's behavior type. 
+     */ 
+    type get_type() const 
+    { 
+        return type_; 
+    } 
+
+private: 
+    /** 
+     * Constructs a new stream behavior of type \a t. 
+     * 
+     * Constructs a new stream behavior of type \a t. It is the 
+     * responsibility of the caller to fill in any other attributes 
+     * required by the specified type, if any. 
+     */ 
+    stream_behavior(type t) 
+        : type_(t) 
+    { 
+    } 
+
+    /** 
+     * This stream's behavior type. 
+     */ 
+    type type_; 
+
+#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) 
+    /** 
+     * File descriptor the stream is redirected to. 
+     */ 
+    int desc_to_; 
+#endif 
+}; 
+
+/** 
+ * Creates a new stream_behavior of type stream_behavior::capture. 
+ * 
+ * Creates a new stream_behavior of type stream_behavior::capture, 
+ * meaning that the child's stream is connected to the parent by using an 
+ * anonymous pipe so that they can send and receive data to/from each 
+ * other. 
+ */ 
+inline stream_behavior capture_stream() 
+{ 
+    return stream_behavior(stream_behavior::capture); 
+} 
+
+/** 
+ * Creates a new stream_behavior of type stream_behavior::close. 
+ * 
+ * Creates a new stream_behavior of type stream_behavior::close, 
+ * meaning that the child's stream is closed upon startup so that it 
+ * will not have any access to it. 
+ */ 
+inline stream_behavior close_stream() 
+{ 
+    return stream_behavior(stream_behavior::close); 
+} 
+
+/** 
+ * Creates a new stream_behavior of type stream_behavior::inherit. 
+ * 
+ * Creates a new stream_behavior of type stream_behavior::inherit, 
+ * meaning that the child's stream is connected to the same stream used 
+ * by the parent. In other words, the corresponding parent's stream is 
+ * inherited. 
+ */ 
+inline stream_behavior inherit_stream() 
+{ 
+    return stream_behavior(stream_behavior::inherit); 
+} 
+
+/** 
+ * Creates a new stream_behavior of type 
+ * stream_behavior::redirect_to_stdout. 
+ * 
+ * Creates a new stream_behavior of type 
+ * stream_behavior::redirect_to_stdout, meaning that the child's stream is 
+ * connected to child's standard output. This is typically used when 
+ * configuring the standard error stream. 
+ */ 
+inline stream_behavior redirect_stream_to_stdout() 
+{ 
+    return stream_behavior(stream_behavior::redirect_to_stdout); 
+} 
+
+/** 
+ * Creates a new stream_behavior of type stream_behavior::silence. 
+ * 
+ * Creates a new stream_behavior of type stream_behavior::silence, 
+ * meaning that the child's stream is redirected to a null device so that 
+ * its input is always zero or its output is lost, depending on whether 
+ * the stream is an input or an output one. It is important to notice 
+ * that this is different from close because the child is still able to 
+ * write data. If we closed, e.g. stdout, the child might not work at 
+ * all! 
+ */ 
+inline stream_behavior silence_stream() 
+{ 
+    return stream_behavior(stream_behavior::silence); 
+} 
+
+#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) 
+/** 
+ * Creates a new stream_behavior of type stream_behavior::posix_redirect. 
+ * 
+ * Creates a new stream_behavior of type stream_behavior::posix_redirect, 
+ * meaning that the child's stream is redirected to the \a to child's 
+ * file descriptor. This is a generalization of the portable 
+ * redirect_stream_to_stdout() behavior. 
+ */ 
+inline stream_behavior posix_redirect_stream(int to) 
+{ 
+    stream_behavior sb(stream_behavior::posix_redirect); 
+    sb.desc_to_ = to; 
+    return sb; 
+} 
+#endif 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/win32_child.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/win32_child.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,128 @@
+// 
+// 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/win32_child.hpp 
+ * 
+ * Includes the declaration of the win32_child class. 
+ */ 
+
+#ifndef BOOST_PROCESS_WIN32_CHILD_HPP 
+#define BOOST_PROCESS_WIN32_CHILD_HPP 
+
+#include <boost/process/child.hpp> 
+#include <boost/process/detail/file_handle.hpp> 
+#include <windows.h> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Windows implementation of the Child concept. 
+ * 
+ * The win32_child class implements the Child concept in a Windows 
+ * operating system. 
+ * 
+ * A Windows child differs from a regular %child (represented by a 
+ * child object) in that it holds additional information about a process. 
+ * Aside from the standard handle, it also includes a handle to the 
+ * process' main thread, together with identifiers to both entities. 
+ * 
+ * This class is built on top of the generic child so as to allow its 
+ * trivial adoption. When a program is changed to use the 
+ * Windows-specific context (win32_context), it will most certainly need 
+ * to migrate its use of the child class to win32_child. Doing so is only 
+ * a matter of redefining the appropriate object and later using the 
+ * required extra features: there should be no need to modify the existing 
+ * code (e.g. method calls) in any other way. 
+ */ 
+class win32_child : public child 
+{ 
+public: 
+    /** 
+     * Constructs a new Windows child object representing a just 
+     * spawned %child process. 
+     * 
+     * Creates a new %child object that represents the process described by 
+     * the \a pi structure. 
+     * 
+     * The \a fhstdin, \a fhstdout and \a fhstderr parameters hold the 
+     * communication streams used to interact with the %child process if 
+     * the launcher configured redirections. See the parent class' 
+     * constructor for more details on these. 
+     * 
+     * \see child 
+     */ 
+    win32_child(const PROCESS_INFORMATION &pi, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr) 
+        : child(pi.dwProcessId, fhstdin, fhstdout, fhstderr, pi.hProcess), 
+        process_information_(pi), 
+        thread_handle_(process_information_.hThread) 
+    { 
+    } 
+
+    /** 
+     * Returns the process handle. 
+     * 
+     * Returns a process-specific handle that can be used to access the 
+     * process. This is the value of the \a hProcess field in the 
+     * PROCESS_INFORMATION structure returned by CreateProcess(). 
+     * 
+     * \see get_id() 
+     */ 
+    HANDLE get_handle() const 
+    { 
+        return process_information_.hProcess; 
+    } 
+
+    /** 
+     * Returns the primary thread's handle. 
+     * 
+     * Returns a handle to the primary thread of the new process. This is 
+     * the value of the \a hThread field in the PROCESS_INFORMATION 
+     * structure returned by CreateProcess(). 
+     * 
+     * \see get_primary_thread_id() 
+     */ 
+    HANDLE get_primary_thread_handle() const 
+    { 
+        return process_information_.hThread; 
+    } 
+
+    /** 
+     * Returns the primary thread's identifier. 
+     * 
+     * Returns a system-wide value that identifies the process's primary 
+     * thread. This is the value of the \a dwThreadId field in the 
+     * PROCESS_INFORMATION structure returned by CreateProcess(). 
+     * 
+     * \see get_primary_thread_handle() 
+     */ 
+    DWORD get_primary_thread_id() const 
+    { 
+        return process_information_.dwThreadId; 
+    } 
+
+private: 
+    /** 
+     * Windows-specific process information. 
+     */ 
+    PROCESS_INFORMATION process_information_; 
+
+    /** 
+     * Thread handle owned by RAII object. 
+     */ 
+    detail::file_handle thread_handle_; 
+}; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/win32_context.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/win32_context.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,61 @@
+// 
+// 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/win_32context.hpp 
+ * 
+ * Includes the declaration of the win32_context class. 
+ */ 
+
+#ifndef BOOST_PROCESS_WIN32_CONTEXT_HPP 
+#define BOOST_PROCESS_WIN32_CONTEXT_HPP 
+
+#include <boost/process/context.hpp> 
+#include <string> 
+#include <windows.h> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Generic implementation of the Context concept. 
+ * 
+ * The context class implements the Context concept in an operating 
+ * system agnostic way; it allows spawning new child processes using 
+ * a single and common interface across different systems. 
+ */ 
+template <class String> 
+class win32_basic_context : public basic_context<String> 
+{ 
+public: 
+    /** 
+     * Initializes the Win32-specific process startup information with NULL. 
+     */ 
+    win32_basic_context() 
+        : startupinfo(NULL) 
+    { 
+    } 
+
+    /** 
+     * Win32-specific process startup information. 
+     */ 
+    STARTUPINFOA *startupinfo; 
+}; 
+
+/** 
+ * Default instantiation of win32_basic_context. 
+ */ 
+typedef win32_basic_context<std::string> win32_context; 
+
+} 
+} 
+
+#endif 
Added: sandbox/SOC/2010/process/boost/process/win32_operations.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/win32_operations.hpp	2010-05-11 00:02:11 EDT (Tue, 11 May 2010)
@@ -0,0 +1,77 @@
+// 
+// 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/win32_operations.hpp 
+ * 
+ * Provides miscellaneous free functions specific to Windows operating 
+ * systems. 
+ */ 
+
+#ifndef BOOST_PROCESS_WIN32_OPERATIONS_HPP 
+#define BOOST_PROCESS_WIN32_OPERATIONS_HPP 
+
+#include <boost/process/win32_child.hpp> 
+#include <boost/process/detail/file_handle.hpp> 
+#include <boost/process/detail/stream_info.hpp> 
+#include <boost/process/detail/win32_ops.hpp> 
+#include <windows.h> 
+
+namespace boost { 
+namespace process { 
+
+/** 
+ * Starts a new child process. 
+ * 
+ * Given an executable and the set of arguments passed to it, starts 
+ * a new process with all the parameters configured in the context. 
+ * The context can be reused afterwards to launch other different 
+ * processes. 
+ * 
+ * \return A handle to the new child process. 
+ */ 
+template <class Executable, class Arguments, class Win32_Context> 
+inline win32_child win32_launch(const Executable &exe, const Arguments &args, const Win32_Context &ctx) 
+{ 
+    detail::file_handle fhstdin, fhstdout, fhstderr; 
+
+    detail::stream_info behin = detail::stream_info(ctx.stdin_behavior, false); 
+    if (behin.type_ == detail::stream_info::use_pipe) 
+        fhstdin = behin.pipe_->wend(); 
+    detail::stream_info behout = detail::stream_info(ctx.stdout_behavior, true); 
+    if (behout.type_ == detail::stream_info::use_pipe) 
+        fhstdout = behout.pipe_->rend(); 
+    detail::stream_info beherr = detail::stream_info(ctx.stderr_behavior, true); 
+    if (beherr.type_ == detail::stream_info::use_pipe) 
+        fhstderr = beherr.pipe_->rend(); 
+
+    detail::win32_setup s; 
+    s.work_directory = ctx.work_directory; 
+
+    STARTUPINFOA si; 
+    if (!ctx.startupinfo) 
+    { 
+        ::ZeroMemory(&si, sizeof(si)); 
+        si.cb = sizeof(si); 
+        s.startupinfo = &si; 
+    } 
+    else 
+        s.startupinfo = ctx.startupinfo; 
+
+    PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s); 
+
+    return win32_child(pi, fhstdin, fhstdout, fhstderr); 
+} 
+
+} 
+} 
+
+#endif