|
Boost-Commit : |
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
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk