|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61999 - in sandbox/SOC/2010/process: boost boost/process boost/process/detail libs/process/example
From: fotanus_at_[hidden]
Date: 2010-05-15 13:52:41
Author: fotanus
Date: 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
New Revision: 61999
URL: http://svn.boost.org/trac/boost/changeset/61999
Log:
Added sample codes;
Modified the internal structure from context and stream_info;
removed the files that are not been used.
create_child working on POSIX, but not on windows.
Added:
sandbox/SOC/2010/process/boost/process/detail/helper_functions.hpp (contents, props changed)
sandbox/SOC/2010/process/boost/process/detail/stream_detail.hpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/
sandbox/SOC/2010/process/libs/process/example/child_stdin.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/child_stdout.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/create_process.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/process_factory.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/read_async_from_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/read_async_from_parent.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/read_from_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/read_from_parent.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/read_info_from_process.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/terminate_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/wait_async_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/wait_async_process.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/wait_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/wait_process.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/write_async_to_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/write_async_to_parent.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/write_info_to_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/write_info_to_self.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/write_to_child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/example/write_to_parent.cpp (contents, props changed)
Removed:
sandbox/SOC/2010/process/boost/process/detail/stream_info.hpp
sandbox/SOC/2010/process/boost/process/detail/win32_ops.hpp
sandbox/SOC/2010/process/boost/process/environment.hpp
sandbox/SOC/2010/process/boost/process/posix_context.hpp
sandbox/SOC/2010/process/boost/process/posix_operations.hpp
sandbox/SOC/2010/process/boost/process/posix_status.hpp
sandbox/SOC/2010/process/boost/process/self.hpp
sandbox/SOC/2010/process/boost/process/win32_child.hpp
sandbox/SOC/2010/process/boost/process/win32_context.hpp
sandbox/SOC/2010/process/boost/process/win32_operations.hpp
Text files modified:
sandbox/SOC/2010/process/boost/process.hpp | 8
sandbox/SOC/2010/process/boost/process/child.hpp | 242 +++++++-------
sandbox/SOC/2010/process/boost/process/context.hpp | 239 +++-----------
sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp | 659 ++++++++++++++++++++-------------------
sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp | 379 +++++++++++-----------
sandbox/SOC/2010/process/boost/process/operations.hpp | 621 ++++++++++--------------------------
sandbox/SOC/2010/process/boost/process/postream.hpp | 118 +++---
sandbox/SOC/2010/process/boost/process/stream_behavior.hpp | 227 +------------
8 files changed, 959 insertions(+), 1534 deletions(-)
Modified: sandbox/SOC/2010/process/boost/process.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process.hpp (original)
+++ sandbox/SOC/2010/process/boost/process.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -24,18 +24,22 @@
#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>
@@ -46,5 +50,5 @@
#include <boost/process/self.hpp>
#include <boost/process/status.hpp>
#include <boost/process/stream_behavior.hpp>
-
+*/
#endif
Modified: sandbox/SOC/2010/process/boost/process/child.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/child.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/child.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -31,6 +31,8 @@
#endif
#include <boost/process/process.hpp>
+
+
#include <boost/process/pistream.hpp>
#include <boost/process/postream.hpp>
#include <boost/process/status.hpp>
@@ -53,136 +55,136 @@
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()
- {
+ /**
+ * 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);
+ 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);
+ ::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)
+ /**
+ * 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)
+ , 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));
- }
+ {
+ 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_;
+ /**
+ * 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_;
+ /**
+ * Process handle owned by RAII object.
+ */
+ boost::shared_ptr<void> process_handle_;
#endif
};
Modified: sandbox/SOC/2010/process/boost/process/context.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/context.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/context.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -4,6 +4,7 @@
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Boris Schaeling, Felipe Tanus
//
// 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)
@@ -12,198 +13,70 @@
/**
* \file boost/process/context.hpp
*
- * Includes the declaration of the context class and several accessory
- * base classes.
+ * Includes the declaration of the context struct.
+ *
*/
-#ifndef BOOST_PROCESS_CONTEXT_HPP
-#define BOOST_PROCESS_CONTEXT_HPP
-
#include <boost/process/config.hpp>
+#include <map>
+#include <boost/process/stream_behavior.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;
-};
+#ifndef BOOST_PROCESS_CONTEXT_HPP
+#define BOOST_PROCESS_CONTEXT_HPP
+namespace boost{
+namespace process{
-/**
- * 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;
-};
+ /*
+ * This is the declaration of context struct.
+ *
+ * The context struct defines a context for a processes
+ * that will be created. It can defines the stream behaviors,
+ * process name, the base directory for the process, and others.
+ *
+ * environment: It's a map from environment variables and it's values.
+ * process_name: Define a name (argv[0]) of the process
+ * io_service: TODO: Check when async is implemented
+ * work_dir: The base dir for the new process.
+ * stdin_behavior: Defines how the stdin of the process will be handled
+ * stdout_behavior: Defines how the stdout of the process will be handled
+ * stderr_behavior: ...
+ *
+ */
+struct context{
+
+ std::map<std::string,std::string> environment; //default: empty
+
+ std::string process_name; //default: empty
+ //io_service *ioservice; //default: NULL
+ std::string work_dir; //default: self::get_work_dir();
+
+ stream_behavior stdin_behavior; //default: inherit
+ stream_behavior stdout_behavior; //default: inherit
+ stream_behavior stderr_behavior; //default: inherit
+
+ context(std::string work_d, stream_behavior def_behavior){
+ stdin_behavior = def_behavior;
+ stdout_behavior = def_behavior;
+ stderr_behavior = def_behavior;
+ work_dir = work_d;
+ }
+ context(){};
+
+};
+
+/*
+ * This is the DEFALT_CONTEXT constant.
+ * It represents a context with default values that will be
+ * assign to a process if no context is passed by parameter.
+ */
-typedef basic_context<std::string> context;
+static struct context DEFAULT_CONTEXT("",inherit);
-/**
- * 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
+#endif
Modified: sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -22,12 +22,12 @@
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
-# include <cerrno>
-# include <unistd.h>
+ #include <cerrno>
+ #include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
-# include <windows.h>
+ #include <windows.h>
#else
-# error "Unsupported platform."
+ #error "Unsupported platform."
#endif
#include <boost/assert.hpp>
@@ -56,347 +56,352 @@
* operations under their respective platforms.
*/
class file_handle
-{
-public:
-#if defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Opaque name for the native handle type.
- *
- * Each operating system identifies file handles using a specific type.
- * The \a handle_type type is used to transparently refer to file
- * handles regarless of the operating system in which this class is
- * used.
- *
- * If this class is used on a POSIX system, \a NativeSystemHandle is
- * an integer type while it is a \a HANDLE on a Windows system.
- */
- typedef NativeSystemHandle handle_type;
+{
+public:
+#if defined(BOOST_PROCESS_DOXYGEN)
+ /**
+ * Opaque name for the native handle type.
+ *
+ * Each operating system identifies file handles using a specific type.
+ * The \a handle_type type is used to transparently refer to file
+ * handles regarless of the operating system in which this class is
+ * used.
+ *
+ * If this class is used on a POSIX system, \a NativeSystemHandle is
+ * an integer type while it is a \a HANDLE on a Windows system.
+ */
+ typedef NativeSystemHandle handle_type;
#elif defined(BOOST_POSIX_API)
- typedef int handle_type;
+ typedef int handle_type;
#elif defined(BOOST_WINDOWS_API)
- typedef HANDLE handle_type;
+ typedef HANDLE handle_type;
#endif
- /**
- * Constructs an invalid file handle.
- *
- * This constructor creates a new \a file_handle object that represents
- * an invalid file handle. An invalid file handle can be copied but
- * cannot be manipulated in any way (except checking for its validity).
- *
- * \see valid()
- */
- file_handle()
- : handle_(invalid_value())
- {
- }
-
- /**
- * Constructs a new file handle from a native file handle.
- *
- * This constructor creates a new \a file_handle object that takes
- * ownership of the given \a h native file handle. The user must not
- * close \a h on his own during the lifetime of the new object.
- * Ownership can be reclaimed using release().
- *
- * \pre The native file handle must be valid; a close operation must
- * succeed on it.
- * \see release()
- */
- file_handle(handle_type h)
- : handle_(h)
- {
- BOOST_ASSERT(handle_ != invalid_value());
- }
-
- /**
- * Copy constructor; invalidates the source handle.
- *
- * This copy constructor creates a new file handle from a given one.
- * Ownership of the native file handle is transferred to the new
- * object, effectively invalidating the source file handle. This
- * avoids having two live \a file_handle objects referring to the
- * same native file handle. The source file handle needs not be
- * valid in the name of simplicity.
- *
- * \post The source file handle is invalid.
- * \post The new file handle owns the source's native file handle.
- */
- file_handle(const file_handle &fh)
- : handle_(fh.handle_)
- {
- fh.handle_ = invalid_value();
- }
-
- /**
- * Releases resources if the handle is valid.
- *
- * If the file handle is valid, the destructor closes it.
- *
- * \see valid()
- */
- ~file_handle()
- {
- if (valid())
- close();
- }
-
- /**
- * Assignment operator; invalidates the source handle.
- *
- * This assignment operator transfers ownership of the RHS file
- * handle to the LHS one, effectively invalidating the source file
- * handle. This avoids having two live \a file_handle objects
- * referring to the same native file handle. The source file
- * handle needs not be valid in the name of simplicity.
- *
- * \post The RHS file handle is invalid.
- * \post The LHS file handle owns RHS' native file handle.
- * \return A reference to the LHS file handle.
- */
- file_handle &operator=(const file_handle &fh)
- {
- handle_ = fh.handle_;
- fh.handle_ = invalid_value();
- return *this;
- }
-
- /**
- * Checks whether the file handle is valid or not.
- *
- * Returns a boolean indicating whether the file handle is valid or
- * not. If the file handle is invalid, no other methods can be
- * executed other than the destructor.
- *
- * \return true if the file handle is valid; false otherwise.
- */
- bool valid() const
- {
- return handle_ != invalid_value();
- }
-
- /**
- * Closes the file handle.
- *
- * Explicitly closes the file handle, which must be valid. Upon
- * exit, the handle is not valid any more.
- *
- * \pre The file handle is valid.
- * \post The file handle is invalid.
- * \post The native file handle is closed.
- */
- void close()
- {
- BOOST_ASSERT(valid());
+ /**
+ * Constructs an invalid file handle.
+ *
+ * This constructor creates a new \a file_handle object that represents
+ * an invalid file handle. An invalid file handle can be copied but
+ * cannot be manipulated in any way (except checking for its validity).
+ *
+ * \see valid()
+ */
+ file_handle()
+ : handle_(invalid_value()){
+ }
-#if defined(BOOST_POSIX_API)
- ::close(handle_);
-#elif defined(BOOST_WINDOWS_API)
- ::CloseHandle(handle_);
-#endif
+ /**
+ * Constructs a new file handle from a native file handle.
+ *
+ * This constructor creates a new \a file_handle object that takes
+ * ownership of the given \a h native file handle. The user must not
+ * close \a h on his own during the lifetime of the new object.
+ * Ownership can be reclaimed using release().
+ *
+ * \pre The native file handle must be valid; a close operation must
+ * succeed on it.
+ * \see release()
+ */
+ file_handle(handle_type h)
+ : handle_(h){
+ BOOST_ASSERT(handle_ != invalid_value());
+ }
+
+ /**
+ * Copy constructor; invalidates the source handle.
+ *
+ * This copy constructor creates a new file handle from a given one.
+ * Ownership of the native file handle is transferred to the new
+ * object, effectively invalidating the source file handle. This
+ * avoids having two live \a file_handle objects referring to the
+ * same native file handle. The source file handle needs not be
+ * valid in the name of simplicity.
+ *
+ * \post The source file handle is invalid.
+ * \post The new file handle owns the source's native file handle.
+ */
+ file_handle(const file_handle &fh)
+ : handle_(fh.handle_){
+ fh.handle_ = invalid_value();
+ }
- handle_ = invalid_value();
- }
+ /**
+ * Releases resources if the handle is valid.
+ *
+ * If the file handle is valid, the destructor closes it.
+ *
+ * \see valid()
+ */
+ ~file_handle(){
+ if (valid())
+ close();
+ }
+
+ /**
+ * Assignment operator; invalidates the source handle.
+ *
+ * This assignment operator transfers ownership of the RHS file
+ * handle to the LHS one, effectively invalidating the source file
+ * handle. This avoids having two live \a file_handle objects
+ * referring to the same native file handle. The source file
+ * handle needs not be valid in the name of simplicity.
+ *
+ * \post The RHS file handle is invalid.
+ * \post The LHS file handle owns RHS' native file handle.
+ * \return A reference to the LHS file handle.
+ */
+ file_handle &operator=(const file_handle &fh){
+ handle_ = fh.handle_;
+ fh.handle_ = invalid_value();
+ return *this;
+ }
+
+ /**
+ * Checks whether the file handle is valid or not.
+ *
+ * Returns a boolean indicating whether the file handle is valid or
+ * not. If the file handle is invalid, no other methods can be
+ * executed other than the destructor.
+ *
+ * \return true if the file handle is valid; false otherwise.
+ */
+ bool valid(){
+ return handle_ != invalid_value();
+ }
- /**
- * Reclaims ownership of the native file handle.
- *
- * Explicitly reclaims ownership of the native file handle contained
- * in the \a file_handle object, returning the native file handle.
- * The caller is responsible of closing it later on.
- *
- * \pre The file handle is valid.
- * \post The file handle is invalid.
- * \return The native file handle.
- */
- handle_type release()
- {
- BOOST_ASSERT(valid());
-
- handle_type h = handle_;
- handle_ = invalid_value();
- return h;
- }
-
- /**
- * Gets the native file handle.
- *
- * Returns the native file handle for the \a file_handle object.
- * The caller can issue any operation on it except closing it.
- * If closing is required, release() shall be used.
- *
- * \pre The file handle is valid.
- * \post The file handle is valid.
- * \return The native file handle.
- */
- handle_type get() const
- {
- BOOST_ASSERT(valid());
-
- return handle_;
- }
-
-#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Changes the native file handle to the given one.
- *
- * Given a new native file handle \a h, this operation assigns this
- * handle to the current object, closing its old native file handle.
- * In other words, it first calls dup2() to remap the old handle to
- * the new one and then closes the old handle.
- *
- * If \a h is open, it is automatically closed by dup2().
- *
- * This operation is only available in POSIX systems.
- *
- * \pre The file handle is valid.
- * \pre The native file handle \a h is valid; i.e., it must be
- * closeable.
- * \post The file handle's native file handle is \a h.
- * \throw boost::system::system_error If the internal remapping
- * operation fails.
- */
- void posix_remap(handle_type h)
- {
- BOOST_ASSERT(valid());
- if (::dup2(handle_, h) == -1)
- boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: dup2(2) failed"));
+ /**
+ * Reclaims ownership of the native file handle.
+ *
+ * Explicitly reclaims ownership of the native file handle contained
+ * in the \a file_handle object, returning the native file handle.
+ * The caller is responsible of closing it later on.
+ *
+ * \pre The file handle is valid.
+ * \post The file handle is invalid.
+ * \return The native file handle.
+ */
+ handle_type release(){
+ BOOST_ASSERT(valid());
+
+ handle_type h = handle_;
+ handle_ = invalid_value();
+ return h;
+ }
+
+ /**
+ * Gets the native file handle.
+ *
+ * Returns the native file handle for the \a file_handle object.
+ * The caller can issue any operation on it except closing it.
+ * If closing is required, release() shall be used.
+ *
+ * \pre The file handle is valid.
+ * \post The file handle is valid.
+ * \return The native file handle.
+ */
+ handle_type get(){
+ BOOST_ASSERT(valid());
- if (::close(handle_) == -1)
- {
- ::close(h);
- boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: close(2) failed"));
+ return handle_;
}
- handle_ = h;
- }
+#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Duplicates an open native file handle.
- *
- * Given a native file handle \a h1, this routine duplicates it so
- * that it ends up being identified by the native file handle \a h2
- * and returns a new \a file_handle owning \a h2.
- *
- * This operation is only available in POSIX systems.
- *
- * \pre The native file handle \a h1 is open.
- * \pre The native file handle \a h2 is valid (non-negative).
- * \post The native file handle \a h1 is closed.
- * \post The native file handle \a h2 is the same as the old \a h1
- * from the operating system's point of view.
- * \return A new \a file_handle object that owns \a h2.
- * \throw boost::system::system_error If dup2() fails.
- */
- static file_handle posix_dup(int h1, int h2)
- {
- if (::dup2(h1, h2) == -1)
- boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_dup: dup2(2) failed"));
+ /**
+ * Closes the file handle.
+ *
+ * Explicitly closes the file handle, which must be valid. Upon
+ * exit, the handle is not valid any more.
+ *
+ * \pre The file handle is valid.
+ * \post The file handle is invalid.
+ * \post The native file handle is closed.
+ */
+ void close(){
+ BOOST_ASSERT(valid());
+ ::close(handle_);
+ handle_ = invalid_value();
+ }
- return file_handle(h2);
- }
-#endif
+ /**
+ * Changes the native file handle to the given one.
+ *
+ * Given a new native file handle \a h, this operation assigns this
+ * handle to the current object, closing its old native file handle.
+ * In other words, it first calls dup2() to remap the old handle to
+ * the new one and then closes the old handle.
+ *
+ * If \a h is open, it is automatically closed by dup2().
+ *
+ * This operation is only available in POSIX systems.
+ *
+ * \pre The file handle is valid.
+ * \pre The native file handle \a h is valid; i.e., it must be
+ * closeable.
+ * \post The file handle's native file handle is \a h.
+ * \throw boost::system::system_error If the internal remapping
+ * operation fails.
+ */
+ void posix_remap(handle_type h){
+
+ BOOST_ASSERT(valid());
+
+ if (::dup2(handle_, h) == -1)
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: dup2(2) failed"));
+
+ if (::close(handle_) == -1){
+ ::close(h);
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: close(2) failed"));
+ }
+
+ handle_ = h;
+ }
+
+ /**
+ * Duplicates an open native file handle.
+ *
+ * Given a native file handle \a h1, this routine duplicates it so
+ * that it ends up being identified by the native file handle \a h2
+ * and returns a new \a file_handle owning \a h2.
+ *
+ * This operation is only available in POSIX systems.
+ *
+ * \pre The native file handle \a h1 is open.
+ * \pre The native file handle \a h2 is valid (non-negative).
+ * \post The native file handle \a h1 is closed.
+ * \post The native file handle \a h2 is the same as the old \a h1
+ * from the operating system's point of view.
+ * \return A new \a file_handle object that owns \a h2.
+ * \throw boost::system::system_error If dup2() fails.
+ */
+ static file_handle duplicate(int h1, int h2)
+ {
+ if (::dup2(h1, h2) == -1)
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_dup: dup2(2) failed"));
+ return file_handle(h2);
+ }
+#endif
#if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Duplicates the \a h native file handle.
- *
- * Given a native file handle \a h, this routine constructs a new
- * \a file_handle object that owns a new duplicate of \a h. The
- * duplicate's inheritable flag is set to the value of \a inheritable.
- *
- * This operation is only available in Windows systems.
- *
- * \pre The native file handle \a h is valid.
- * \return A file handle owning a duplicate of \a h.
- * \throw boost::system::system_error If DuplicateHandle() fails.
- */
- static file_handle win32_dup(HANDLE h, bool inheritable)
- {
- HANDLE h2;
- if (!::DuplicateHandle(::GetCurrentProcess(), h, ::GetCurrentProcess(), &h2, 0, inheritable ? TRUE : FALSE, DUPLICATE_SAME_ACCESS))
- boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_dup: DuplicateHandle failed"));
-
- return file_handle(h2);
- }
-
- /**
- * Creates a new duplicate of a standard file handle.
- *
- * Constructs a new \a file_handle object that owns a duplicate of a
- * standard file handle. The \a d parameter specifies which standard
- * file handle to duplicate and can be one of \a STD_INPUT_HANDLE,
- * \a STD_OUTPUT_HANDLE or \a STD_ERROR_HANDLE. The duplicate's
- * inheritable flag is set to the value of \a inheritable.
- *
- * This operation is only available in Windows systems.
- *
- * \pre \a d refers to one of the standard handles as described above.
- * \return A file handle owning a duplicate of the standard handle
- * referred to by \a d.
- * \throw boost::system::system_error If GetStdHandle() or
- * DuplicateHandle() fails.
- */
- static file_handle win32_std(DWORD d, bool inheritable)
- {
- BOOST_ASSERT(d == STD_INPUT_HANDLE || d == STD_OUTPUT_HANDLE || d == STD_ERROR_HANDLE);
-
- HANDLE h = ::GetStdHandle(d);
- if (h == INVALID_HANDLE_VALUE)
- boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_std: GetStdHandle failed"));
-
- return win32_dup(h, inheritable);
- }
-
- /**
- * Changes the file handle's inheritable flag.
- *
- * Changes the file handle's inheritable flag to \a i. It is not
- * necessary for the file handle's flag to be different than \a i.
- *
- * This operation is only available in Windows systems.
- *
- * \pre The file handle is valid.
- * \post The native file handle's inheritable flag is set to \a i.
- * \throw boost::system::system_error If the property change fails.
- */
- void win32_set_inheritable(bool i)
- {
- BOOST_ASSERT(valid());
-
- if (!::SetHandleInformation(handle_, HANDLE_FLAG_INHERIT, i ? HANDLE_FLAG_INHERIT : 0))
- boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_set_inheritable: SetHandleInformation failed"));
- }
+
+ /**
+ * Closes the file handle.
+ *
+ * Explicitly closes the file handle, which must be valid. Upon
+ * exit, the handle is not valid any more.
+ *
+ * \pre The file handle is valid.
+ * \post The file handle is invalid.
+ * \post The native file handle is closed.
+ */
+ void close(){
+ BOOST_ASSERT(valid());
+ ::CloseHandle(handle_);
+ handle_ = invalid_value();
+ }
+
+ /**
+ * Duplicates the \a h native file handle.
+ *
+ * Given a native file handle \a h, this routine constructs a new
+ * \a file_handle object that owns a new duplicate of \a h. The
+ * duplicate's inheritable flag is set to the value of \a inheritable.
+ *
+ * This operation is only available in Windows systems.
+ *
+ * \pre The native file handle \a h is valid.
+ * \return A file handle owning a duplicate of \a h.
+ * \throw boost::system::system_error If DuplicateHandle() fails.
+ */
+ static file_handle win32_dup(HANDLE h, bool inheritable){
+ HANDLE h2;
+
+ if (!::DuplicateHandle(::GetCurrentProcess(), h,
+ ::GetCurrentProcess(), &h2, 0,
+ inheritable ? TRUE : FALSE,
+ DUPLICATE_SAME_ACCESS))
+
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_dup: DuplicateHandle failed"));
+
+ return file_handle(h2);
+ }
+
+ /**
+ * Creates a new duplicate of a standard file handle.
+ *
+ * Constructs a new \a file_handle object that owns a duplicate of a
+ * standard file handle. The \a d parameter specifies which standard
+ * file handle to duplicate and can be one of \a STD_INPUT_HANDLE,
+ * \a STD_OUTPUT_HANDLE or \a STD_ERROR_HANDLE. The duplicate's
+ * inheritable flag is set to the value of \a inheritable.
+ *
+ * This operation is only available in Windows systems.
+ *
+ * \pre \a d refers to one of the standard handles as described above.
+ * \return A file handle owning a duplicate of the standard handle
+ * referred to by \a d.
+ * \throw boost::system::system_error If GetStdHandle() or
+ * DuplicateHandle() fails.
+ */
+
+ static file_handle win32_std(DWORD d, bool inheritable){
+ BOOST_ASSERT(d == STD_INPUT_HANDLE || d == STD_OUTPUT_HANDLE || d == STD_ERROR_HANDLE);
+
+ HANDLE h = ::GetStdHandle(d);
+ if (h == INVALID_HANDLE_VALUE)
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_std: GetStdHandle failed"));
+
+ return win32_dup(h, inheritable);
+ }
+
+ /**
+ * Changes the file handle's inheritable flag.
+ *
+ * Changes the file handle's inheritable flag to \a i. It is not
+ * necessary for the file handle's flag to be different than \a i.
+ *
+ * This operation is only available in Windows systems.
+ *
+ * \pre The file handle is valid.
+ * \post The native file handle's inheritable flag is set to \a i.
+ * \throw boost::system::system_error If the property change fails.
+ */
+ void win32_set_inheritable(bool i)
+ {
+ BOOST_ASSERT(valid());
+
+ if (!::SetHandleInformation(handle_, HANDLE_FLAG_INHERIT, i ? HANDLE_FLAG_INHERIT : 0))
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_set_inheritable: SetHandleInformation failed"));
+ }
#endif
private:
- /**
- * Internal handle value.
- *
- * This variable holds the native handle value for the file handle
- * hold by this object. It is interesting to note that this needs
- * to be mutable because the copy constructor and the assignment
- * operator invalidate the source object.
- */
- mutable handle_type handle_;
-
- /**
- * Constant function representing an invalid handle value.
- *
- * Returns the platform-specific handle value that represents an
- * invalid handle. This is a constant function rather than a regular
- * constant because, in the latter case, we cannot define it under
- * Windows due to the value being of a complex type.
- */
- static const handle_type invalid_value()
- {
-#if defined(BOOST_POSIX_API)
- return -1;
-#elif defined(BOOST_WINDOWS_API)
- return INVALID_HANDLE_VALUE;
-#endif
- }
+ /**
+ * Internal handle value.
+ *
+ * This variable holds the native handle value for the file handle
+ * hold by this object. It is interesting to note that this needs
+ * to be mutable because the copy constructor and the assignment
+ * operator invalidate the source object.
+ */
+ mutable handle_type handle_;
+
+ /**
+ * Constant function representing an invalid handle value.
+ *
+ * Returns the platform-specific handle value that represents an
+ * invalid handle. This is a constant function rather than a regular
+ * constant because, in the latter case, we cannot define it under
+ * Windows due to the value being of a complex type.
+ */
+ static const handle_type invalid_value(){
+ #if defined(BOOST_POSIX_API)
+ return -1;
+ #elif defined(BOOST_WINDOWS_API)
+ return INVALID_HANDLE_VALUE;
+ #endif
+ }
};
}
Added: sandbox/SOC/2010/process/boost/process/detail/helper_functions.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/detail/helper_functions.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,168 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Boris Schaeling, Felipe Tanus
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * \file boost/process/detail/helper_functions.hpp
+ *
+ * Includes the declaration of helper functions for the operations.
+ * It's for internal purposes.
+ *
+ */
+
+#if defined(BOOST_POSIX_API)
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+#endif
+#include <map>
+#include <string.h>
+#include <boost/optional.hpp>
+#include <boost/process/stream_behavior.hpp>
+
+
+
+#ifndef BOOST_PROCESS_HELPER_FUNCTIONS_HPP
+#define BOOST_PROCESS_HELPER_FUNCTIONS_HPP
+namespace boost{
+namespace process{
+namespace detail{
+
+
+
+/*
+ * This is the declaration of configure_stream function.
+ * This function, given an stream_detail inherit from the current process
+ * father, configure the stream.
+ *
+ * Note that this function is meant to be called on a brand-new child.
+ *
+ */
+inline configure_stream(stream_detail &s){
+
+ switch(s.behavior){
+ case dummy:{
+
+ #if defined(BOOST_POSIX_API)
+ char * null_file = "/dev/zero";
+ #elif defined(BOOST_WINDOWS_API)
+ char * null_file = "NUL";
+ #endif
+
+ int fd;
+ if(s.stream_type == stdin_type)
+ fd = ::open(null_file, O_RDONLY);
+ else
+ fd = ::open(null_file, O_WRONLY);
+
+ if (fd == -1)
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_input: open(2) of " + s.object.file_ + " failed"));
+
+ s.object.handle_ = file_handle(fd);
+ s.object.handle_.posix_remap(s.stream_handler);
+ s.object.handle_.release();
+
+ break;
+ }
+
+ case closed:
+ //?
+ break;
+
+ case inherit:
+ //do nothing since is default?
+ break;
+
+ case capture:
+ s.object.pipe_ = pipe();
+ if(s.stream_type == stdin_type){
+ s.object.pipe_->wend().close();
+ s.object.pipe_->rend().posix_remap(s.stream_handler);
+ }
+ else{
+ s.object.pipe_->rend().close();
+ s.object.pipe_->wend().posix_remap(s.stream_handler);
+ }
+ break;
+
+ default:
+ BOOST_ASSERT(false);
+ }
+
+}
+
+
+/**
+ * Converts an environment to a char** table as used by execve().
+ *
+ * Converts the environment's contents to the format used by the
+ * execve() system call. The returned char** array is allocated
+ * in dynamic memory; the caller must free it when not used any
+ * more. Each entry is also allocated in dynamic memory and is a
+ * NULL-terminated string of the form var=value; these must also be
+ * released by the caller.
+ *
+ * \return A dynamically allocated char** array that represents
+ * the environment's content. Each array entry is a
+ * NULL-terminated string of the form var=value.
+ */
+inline char ** environment_to_envp( std::map<std::string,std::string> env){
+ char **envp = new char*[env.size() + 1];
+
+ unsigned int i = 0;
+ for (std::map<std::string,std::string>::const_iterator it = env.begin(); it != env.end(); ++it){
+ std::string s = (*it).first + "=" + (*it).second;
+ envp[i] = new char[s.size() + 1];
+ ::strncpy(envp[i], s.c_str(), s.size() + 1);
+ ++i;
+ }
+ envp[i] = 0;
+ return envp;
+}
+
+/**
+ * Converts the command line to an array of C strings.
+ *
+ * Converts the command line's list of arguments to the format expected
+ * by the \a argv parameter in the POSIX execve() system call.
+ *
+ * This operation is only available on POSIX systems.
+ *
+ * \return The first argument of the pair is an integer that indicates
+ * how many strings are stored in the second argument. The
+ * second argument is a NULL-terminated, dynamically allocated
+ * array of dynamically allocated strings holding the arguments
+ * to the executable. The caller is responsible of freeing them.
+ */
+template <class Arguments>
+inline std::pair<std::size_t, char**> collection_to_posix_argv(const Arguments &args)
+{
+ std::size_t nargs = args.size();
+ BOOST_ASSERT(nargs >= 0);
+
+ char **argv = new char*[nargs + 1];
+ typename Arguments::size_type i = 0;
+ for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it)
+ {
+ argv[i] = new char[it->size() + 1];
+ ::strncpy(argv[i], it->c_str(), it->size() + 1);
+ ++i;
+ }
+ argv[nargs] = 0;
+
+ return std::pair<std::size_t, char**>(nargs, argv);
+}
+}
+}
+}
+
+
+#endif
Added: sandbox/SOC/2010/process/boost/process/detail/stream_detail.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/detail/stream_detail.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,83 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Boris Schaeling, Felipe Tanus
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * \file boost/process/detail/stream_detail.hpp
+ *
+ * Includes the declaration of the stream_detail struct.
+ * It's for internal purposes
+ *
+ */
+
+#include <boost/process/config.hpp>
+#include <map>
+#include <boost/optional.hpp>
+#include <boost/process/stream_behavior.hpp>
+#include <boost/process/detail/pipe.hpp>
+
+
+
+#ifndef BOOST_PROCESS_STREAM_DETAIL_HPP
+#define BOOST_PROCESS_STREAM_DETAIL_HPP
+namespace boost{
+namespace process{
+namespace detail{
+
+
+/*
+ * This is the declaration of stream_object.
+ * It represents all types that can be assign of an stream object
+ * representation. For example, it can point to another stream or
+ * to a pipe.
+ */
+
+struct stream_object {
+ int desc_to;
+ std::string file_;
+ file_handle handle_;
+ boost::optional<pipe> pipe_;
+};
+
+
+/*
+ * This defines the std_stream_type enum.
+ * It lists all possible std stream types.
+ */
+enum std_stream_type {stdin_type, stdout_type, stderr_type};
+
+
+/*
+ * This is the declaration of a stream detail.
+ * A stream detail contains all details from one standard stream
+ * (in, out or err) that are needed for adjust it
+ * when a new process is created.
+ *
+ * stream_end: The adress of the stream
+ * stream_type: Defines if the stream is a stdin, out or error.
+ * behavior: The behavior this stream will assume
+ * object: The object required to this behavior (see stream_object above)
+ *
+ */
+
+struct stream_detail {
+ int stream_handler;
+ struct stream_object object;
+ std_stream_type stream_type;
+ stream_behavior behavior;
+};
+
+}
+}
+}
+
+
+#endif
Deleted: sandbox/SOC/2010/process/boost/process/detail/stream_info.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/stream_info.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,176 +0,0 @@
-//
-// Boost.Process
-// ~~~~~~~~~~~~~
-//
-// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-/**
- * \file boost/process/detail/stream_info.hpp
- *
- * Provides the definition of the stream_info structure.
- */
-
-#ifndef BOOST_PROCESS_DETAIL_STREAM_INFO_HPP
-#define BOOST_PROCESS_DETAIL_STREAM_INFO_HPP
-
-#include <boost/process/config.hpp>
-
-#if defined(BOOST_POSIX_API)
-# include <unistd.h>
-#elif defined(BOOST_WINDOWS_API)
-#else
-# error "Unsupported platform."
-#endif
-
-#include <boost/process/stream_behavior.hpp>
-#include <boost/process/detail/file_handle.hpp>
-#include <boost/process/detail/pipe.hpp>
-#include <boost/optional.hpp>
-#include <boost/assert.hpp>
-#include <string>
-
-namespace boost {
-namespace process {
-namespace detail {
-
-/**
- * Configuration data for a file descriptor.
- *
- * This convenience structure provides a compact way to pass information
- * around on how to configure a file descriptor. It is a lower-level
- * representation of stream_behavior, as it can hold the same information
- * but in a way that can be used by the underlying operating system.
- */
-struct stream_info
-{
- /**
- * Supported stream types.
- */
- enum type
- {
- /**
- * Matches stream_behavior::close.
- */
- close,
-
- /**
- * Matches stream_behavior::inherit.
- */
- inherit,
-
- /**
- * Matches stream_behavior::redirect_to_stdout and
- * stream_behavior::posix_redirect.
- */
- redirect,
-
- /**
- * Matches stream_behavior::silence.
- */
- use_file,
-
- /**
- * TODO: Matches nothing yet ...
- */
- use_handle,
-
- /**
- * Matches stream_behavior::capture.
- */
- use_pipe
- };
-
- /**
- * Stream type.
- */
- type type_;
-
- /**
- * Descriptor to use when stream type is set to \a redirect.
- */
- int desc_to_;
-
- /**
- * File to use when stream type is set to \a use_file.
- */
- std::string file_;
-
- /**
- * Handle to use when stream type is set to \a use_handle.
- */
- file_handle handle_;
-
- /**
- * Pipe to use when stream type is set to \a use_pipe.
- */
- boost::optional<pipe> pipe_;
-
- /**
- * Constructs a new stream_info object.
- */
- stream_info(const stream_behavior &sb, bool out)
- {
- switch (sb.type_)
- {
- case stream_behavior::close:
- {
- type_ = close;
- break;
- }
- case stream_behavior::inherit:
- {
- type_ = inherit;
- break;
- }
- case stream_behavior::redirect_to_stdout:
- {
- type_ = redirect;
-#if defined(BOOST_POSIX_API)
- desc_to_ = STDOUT_FILENO;
-#elif defined(BOOST_WINDOWS_API)
- desc_to_ = 1;
-#endif
- break;
- }
-#if defined(BOOST_POSIX_API)
- case stream_behavior::posix_redirect:
- {
- type_ = redirect;
- desc_to_ = sb.desc_to_;
- break;
- }
-#endif
- case stream_behavior::silence:
- {
- type_ = use_file;
-#if defined(BOOST_POSIX_API)
- file_ = out ? "/dev/null" : "/dev/zero";
-#elif defined(BOOST_WINDOWS_API)
- file_ = "NUL";
-#endif
- break;
- }
- case stream_behavior::capture:
- {
- type_ = use_pipe;
- pipe_ = pipe();
- break;
- }
- default:
- {
- BOOST_ASSERT(false);
- }
- }
- }
-};
-
-}
-}
-}
-
-#endif
Modified: sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -19,15 +19,16 @@
#ifndef BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP
#define BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP
-#include <boost/process/config.hpp>
+#include <boost/process/config.hpp>
-#if defined(BOOST_POSIX_API)
-# include <sys/types.h>
-# include <unistd.h>
-#elif defined(BOOST_WINDOWS_API)
-# include <windows.h>
+#if defined(BOOST_POSIX_API)
+ #include <sys/types.h>
+ #include <unistd.h>
+
+#elif defined(BOOST_WINDOWS_API)
+ #include <windows.h>
#else
-# error "Unsupported platform."
+ #error "Unsupported platform."
#endif
#include <boost/noncopyable.hpp>
@@ -44,188 +45,188 @@
namespace detail {
/**
- * std::streambuf implementation for system file handles.
- *
- * systembuf provides a std::streambuf implementation for system file
- * handles. Contrarywise to file_handle, this class does \b not take
- * ownership of the native file handle; this should be taken care of
- * somewhere else.
+ * std::streambuf implementation for system file handles.
*
- * This class follows the expected semantics of a std::streambuf object.
- * However, it is not copyable to avoid introducing inconsistences with
- * the on-disk file and the in-memory buffers.
- */
-class systembuf : public std::streambuf, public boost::noncopyable
-{
- friend class ::boost::process::postream;
-
-public:
-#if defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Opaque name for the native handle type.
- */
- typedef NativeHandleType handle_type;
-#elif defined(BOOST_POSIX_API)
- typedef int handle_type;
-#elif defined(BOOST_WINDOWS_API)
- typedef HANDLE handle_type;
-#endif
-
- /**
- * Constructs a new systembuf for the given file handle.
- *
- * This constructor creates a new systembuf object that reads or
- * writes data from/to the \a h native file handle. This handle
- * is \b not owned by the created systembuf object; the code
- * should take care of it externally.
- *
- * This class buffers input and output; the buffer size may be
- * tuned through the \a bufsize parameter, which defaults to 8192
- * bytes.
- *
- * \see pistream and postream
- */
- explicit systembuf(handle_type h, std::size_t bufsize = 8192)
- : handle_(h),
- bufsize_(bufsize),
- read_buf_(new char[bufsize]),
- write_buf_(new char[bufsize])
- {
-#if defined(BOOST_POSIX_API)
- BOOST_ASSERT(handle_ >= 0);
-#elif defined(BOOST_WINDOWS_API)
- BOOST_ASSERT(handle_ != INVALID_HANDLE_VALUE);
-#endif
- BOOST_ASSERT(bufsize_ > 0);
-
- setp(write_buf_.get(), write_buf_.get() + bufsize_);
- }
-
-protected:
- /**
- * Reads new data from the native file handle.
- *
- * This operation is called by input methods when there is no more
- * data in the input buffer. The function fills the buffer with new
- * data, if available.
- *
- * \pre All input positions are exhausted (gptr() >= egptr()).
- * \post The input buffer has new data, if available.
- * \returns traits_type::eof() if a read error occurrs or there are
- * no more data to be read. Otherwise returns
- * traits_type::to_int_type(*gptr()).
- */
- virtual int_type underflow()
- {
- BOOST_ASSERT(gptr() >= egptr());
-
- bool ok;
-#if defined(BOOST_POSIX_API)
- ssize_t cnt = ::read(handle_, read_buf_.get(), bufsize_);
- ok = (cnt != -1 && cnt != 0);
-#elif defined(BOOST_WINDOWS_API)
- DWORD cnt;
- BOOL res = ::ReadFile(handle_, read_buf_.get(), bufsize_, &cnt, NULL);
- ok = (res && cnt > 0);
-#endif
-
- if (!ok)
- return traits_type::eof();
- else
- {
- setg(read_buf_.get(), read_buf_.get(), read_buf_.get() + cnt);
- return traits_type::to_int_type(*gptr());
- }
- }
-
- /**
- * Makes room in the write buffer for additional data.
- *
- * This operation is called by output methods when there is no more
- * space in the output buffer to hold a new element. The function
- * first flushes the buffer's contents to disk and then clears it to
- * leave room for more characters. The given \a c character is
- * stored at the beginning of the new space.
- *
- * \pre All output positions are exhausted (pptr() >= epptr()).
- * \post The output buffer has more space if no errors occurred
- * during the write to disk.
- * \post *(pptr() - 1) is \a c.
- * \returns traits_type::eof() if a write error occurrs. Otherwise
- * returns traits_type::not_eof(c).
- */
- virtual int_type overflow(int c)
- {
- BOOST_ASSERT(pptr() >= epptr());
-
- if (sync() == -1)
- return traits_type::eof();
-
- if (!traits_type::eq_int_type(c, traits_type::eof()))
- {
- traits_type::assign(*pptr(), c);
- pbump(1);
- }
-
- return traits_type::not_eof(c);
- }
-
- /**
- * Flushes the output buffer to disk.
- *
- * Synchronizes the systembuf buffers with the contents of the file
- * associated to this object through the native file handle. The
- * output buffer is flushed to disk and cleared to leave new room
- * for more data.
- *
- * \returns 0 on success, -1 if an error occurred.
- */
- virtual int sync()
- {
-#if defined(BOOST_POSIX_API)
- ssize_t cnt = pptr() - pbase();
-#elif defined(BOOST_WINDOWS_API)
- long cnt = pptr() - pbase();
-#endif
-
- bool ok;
-#if defined(BOOST_POSIX_API)
- ok = ::write(handle_, pbase(), cnt) == cnt;
-#elif defined(BOOST_WINDOWS_API)
- DWORD rcnt;
- BOOL res = ::WriteFile(handle_, pbase(), cnt, &rcnt, NULL);
- ok = (res && static_cast<long>(rcnt) == cnt);
-#endif
-
- if (ok)
- pbump(-cnt);
- return ok ? 0 : -1;
- }
-
-private:
- /**
- * Native file handle used by the systembuf object.
- */
- handle_type handle_;
-
- /**
- * Internal buffer size used during read and write operations.
- */
- std::size_t bufsize_;
-
- /**
- * Internal buffer used during read operations.
- */
- boost::scoped_array<char> read_buf_;
-
- /**
- * Internal buffer used during write operations.
- */
- boost::scoped_array<char> write_buf_;
-};
-
-}
-}
-}
+ * systembuf provides a std::streambuf implementation for system file
+ * handles. Contrarywise to file_handle, this class does \b not take
+ * ownership of the native file handle; this should be taken care of
+ * somewhere else.
+ *
+ * This class follows the expected semantics of a std::streambuf object.
+ * However, it is not copyable to avoid introducing inconsistences with
+ * the on-disk file and the in-memory buffers.
+ */
+class systembuf : public std::streambuf, public boost::noncopyable {
+
+ friend class ::boost::process::postream;
+
+public:
+ #if defined(BOOST_PROCESS_DOXYGEN)
+ /**
+ * Opaque name for the native handle type.
+ */
+ typedef NativeHandleType handle_type;
+ #elif defined(BOOST_POSIX_API)
+ typedef int handle_type;
+ #elif defined(BOOST_WINDOWS_API)
+ typedef HANDLE handle_type;
+ #endif
+
+ /**
+ * Constructs a new systembuf for the given file handle.
+ *
+ * This constructor creates a new systembuf object that reads or
+ * writes data from/to the \a h native file handle. This handle
+ * is \b not owned by the created systembuf object; the code
+ * should take care of it externally.
+ *
+ * This class buffers input and output; the buffer size may be
+ * tuned through the \a bufsize parameter, which defaults to 8192
+ * bytes.
+ *
+ * \see pistream and postream
+ */
+
+ explicit systembuf(handle_type h, std::size_t bufsize = 8192)
+ : handle_(h),
+ bufsize_(bufsize),
+ read_buf_(new char[bufsize]),
+ write_buf_(new char[bufsize]){
+ #if defined(BOOST_POSIX_API)
+ BOOST_ASSERT(handle_ >= 0);
+ #elif defined(BOOST_WINDOWS_API)
+ BOOST_ASSERT(handle_ != INVALID_HANDLE_VALUE);
+ #endif
+ BOOST_ASSERT(bufsize_ > 0);
+
+ setp(write_buf_.get(), write_buf_.get() + bufsize_);
+ }
+
+protected:
+ /**
+ * Reads new data from the native file handle.
+ *
+ * This operation is called by input methods when there is no more
+ * data in the input buffer. The function fills the buffer with new
+ * data, if available.
+ *
+ * \pre All input positions are exhausted (gptr() >= egptr()).
+ * \post The input buffer has new data, if available.
+ * \returns traits_type::eof() if a read error occurrs or there are
+ * no more data to be read. Otherwise returns
+ * traits_type::to_int_type(*gptr()).
+ */
+ virtual int_type underflow(){
+ BOOST_ASSERT(gptr() >= egptr());
+
+ bool ok;
+ #if defined(BOOST_POSIX_API)
+ ssize_t cnt = ::read(handle_, read_buf_.get(), bufsize_);
+ ok = (cnt != -1 && cnt != 0);
+ #elif defined(BOOST_WINDOWS_API)
+ DWORD cnt;
+ BOOL res = ::ReadFile(handle_, read_buf_.get(), bufsize_, &cnt, NULL);
+ ok = (res && cnt > 0);
+ #endif
+
+ if (!ok)
+ return traits_type::eof();
+ else{
+ setg(read_buf_.get(), read_buf_.get(), read_buf_.get() + cnt);
+ return traits_type::to_int_type(*gptr());
+ }
+ }
+
+ /**
+ * Makes room in the write buffer for additional data.
+ *
+ * This operation is called by output methods when there is no more
+ * space in the output buffer to hold a new element. The function
+ * first flushes the buffer's contents to disk and then clears it to
+ * leave room for more characters. The given \a c character is
+ * stored at the beginning of the new space.
+ *
+ * \pre All output positions are exhausted (pptr() >= epptr()).
+ * \post The output buffer has more space if no errors occurred
+ * during the write to disk.
+ * \post *(pptr() - 1) is \a c.
+ * \returns traits_type::eof() if a write error occurrs. Otherwise
+ * returns traits_type::not_eof(c).
+ */
+ virtual int_type overflow(int c){
+ BOOST_ASSERT(pptr() >= epptr());
+
+ if (sync() == -1)
+ return traits_type::eof();
+
+ if (!traits_type::eq_int_type(c, traits_type::eof())){
+ traits_type::assign(*pptr(), c);
+ pbump(1);
+ }
+
+ return traits_type::not_eof(c);
+ }
+
+ /**
+ * Flushes the output buffer to disk.
+ *
+ * Synchronizes the systembuf buffers with the contents of the file
+ * associated to this object through the native file handle. The
+ * output buffer is flushed to disk and cleared to leave new room
+ * for more data.
+ *
+ * \returns 0 on success, -1 if an error occurred.
+ */
+
+
+ #if defined(BOOST_POSIX_API)
+ virtual int sync(){
+ ssize_t cnt = pptr() - pbase();
+ bool ok;
+
+ ok = (::write(handle_, pbase(), cnt) == cnt);
+ if (ok)
+ pbump(-cnt);
+ return ok ? 0 : -1;
+ }
+ #elif defined(BOOST_WINDOWS_API)
+ virtual int sync(){
+ long cnt = pptr() - pbase();
+ bool ok;
+ DWORD rcnt;
+ BOOL res = ::WriteFile(handle_, pbase(), cnt, &rcnt, NULL);
+
+ ok = (res && static_cast<long>(rcnt) == cnt);
+ if (ok)
+ pbump(-cnt);
+ return ok ? 0 : -1;
+ }
+ #endif
+
+private:
+ /**
+ * Native file handle used by the systembuf object.
+ */
+ handle_type handle_;
+
+ /**
+ * Internal buffer size used during read and write operations.
+ */
+ std::size_t bufsize_;
+
+ /**
+ * Internal buffer used during read operations.
+ */
+ boost::scoped_array<char> read_buf_;
+
+ /**
+ * Internal buffer used during write operations.
+ */
+ boost::scoped_array<char> write_buf_;
+};
+
+}
+}
+}
#endif
Deleted: sandbox/SOC/2010/process/boost/process/detail/win32_ops.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/win32_ops.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,355 +0,0 @@
-//
-// Boost.Process
-// ~~~~~~~~~~~~~
-//
-// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-/**
- * \file boost/process/detail/win32_ops.hpp
- *
- * Provides some convenience functions to start processes under
- * Windows-compatible operating systems.
- */
-
-#ifndef BOOST_PROCESS_DETAIL_WIN32_OPS_HPP
-#define BOOST_PROCESS_DETAIL_WIN32_OPS_HPP
-
-#include <boost/process/environment.hpp>
-#include <boost/process/detail/file_handle.hpp>
-#include <boost/process/detail/pipe.hpp>
-#include <boost/process/detail/stream_info.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/shared_array.hpp>
-#include <boost/scoped_array.hpp>
-#include <boost/assert.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/throw_exception.hpp>
-#include <vector>
-#include <string>
-#include <cstddef>
-#include <string.h>
-#include <windows.h>
-
-namespace boost {
-namespace process {
-namespace detail {
-
-/**
- * Converts the command line to a plain string. Converts the command line's
- * list of arguments to the format expected by the \a lpCommandLine parameter
- * in the CreateProcess() system call.
- *
- * This operation is only available on Windows systems.
- *
- * \return A dynamically allocated string holding the command line
- * to be passed to the executable. It is returned in a
- * shared_array object to ensure its release at some point.
- */
-template <class Arguments>
-inline boost::shared_array<char> collection_to_win32_cmdline(const Arguments &args)
-{
- typedef std::vector<std::string> arguments_t;
- arguments_t args2;
- typename Arguments::size_type i = 0;
- std::size_t size = 0;
- for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it)
- {
- std::string arg = *it;
-
- std::string::size_type pos = 0;
- while ( (pos = arg.find('"', pos)) != std::string::npos)
- {
- arg.replace(pos, 1, "\\\"");
- pos += 2;
- }
-
- if (arg.find(' ') != std::string::npos)
- arg = '\"' + arg + '\"';
-
- if (i++ != args.size() - 1)
- arg += ' ';
-
- args2.push_back(arg);
- size += arg.size() + 1;
- }
-
- boost::shared_array<char> cmdline(new char[size]);
- cmdline.get()[0] = '\0';
- for (arguments_t::size_type i = 0; i < args.size(); ++i)
-#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE)
- ::strncat(cmdline.get(), args2[i].c_str(), args2[i].size());
-#else
- ::strcat_s(cmdline.get(), size, args2[i].c_str());
-#endif
-
- return cmdline;
-}
-
-/**
- * Converts an environment to a string used by CreateProcess().
- *
- * Converts the environment's contents to the format used by the
- * CreateProcess() system call. The returned char* string is
- * allocated in dynamic memory; the caller must free it when not
- * used any more. This is enforced by the use of a shared pointer.
- *
- * \return A dynamically allocated char* string that represents
- * the environment's content. This string is of the form
- * var1=value1\\0var2=value2\\0\\0.
- */
-inline boost::shared_array<char> environment_to_win32_strings(const environment &env)
-{
- boost::shared_array<char> envp;
-
- if (env.empty())
- {
- envp.reset(new char[2]);
- ::ZeroMemory(envp.get(), 2);
- }
- else
- {
- std::string s;
- for (environment::const_iterator it = env.begin(); it != env.end(); ++it)
- {
- s += it->first + "=" + it->second;
- s.push_back(0);
- }
-
- envp.reset(new char[s.size() + 1]);
-#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE)
- ::memcpy(envp.get(), s.c_str(), s.size() + 1);
-#else
- ::memcpy_s(envp.get(), s.size() + 1, s.c_str(), s.size() + 1);
-#endif
- }
-
- return envp;
-}
-
-/**
- * Helper class to configure a Win32 %child.
- *
- * This helper class is used to hold all the attributes that configure a
- * new Win32 %child process.
- *
- * All its fields are public for simplicity. It is only intended for
- * internal use and it is heavily coupled with the Context
- * implementations.
- */
-struct win32_setup
-{
- /**
- * The work directory.
- *
- * This string specifies the directory in which the %child process
- * starts execution. It cannot be empty.
- */
- std::string work_directory;
-
- /**
- * The process startup properties.
- *
- * This Win32-specific object holds a list of properties that describe
- * how the new process should be started. The \a STARTF_USESTDHANDLES
- * flag should not be set in it because it is automatically configured
- * by win32_start().
- */
- STARTUPINFOA *startupinfo;
-};
-
-/**
- * Starts a new child process in a Win32 operating system.
- *
- * This helper functions is provided to simplify the Context's task when
- * it comes to starting up a new process in a Win32 operating system.
- *
- * \param exe The executable to spawn the child process.
- * \param args The arguments for the executable.
- * \param env The environment variables that the new child process
- * receives.
- * \param infoin Information that describes stdin's behavior.
- * \param infoout Information that describes stdout's behavior.
- * \param infoerr Information that describes stderr's behavior.
- * \param setup A helper object holding extra child information.
- * \return The new process' information as returned by the CreateProcess()
- * system call. The caller is responsible of creating an
- * appropriate Child representation for it.
- * \pre \a setup.startupinfo_ cannot have the \a STARTF_USESTDHANDLES set
- * in the \a dwFlags field.
- */
-template <class Executable, class Arguments>
-inline PROCESS_INFORMATION win32_start(const Executable &exe, const Arguments &args, const environment &env, stream_info &infoin, stream_info &infoout, stream_info &infoerr, const win32_setup &setup)
-{
- file_handle chin, chout, cherr;
-
- BOOST_ASSERT(setup.startupinfo->cb >= sizeof(STARTUPINFOA));
- BOOST_ASSERT(!(setup.startupinfo->dwFlags & STARTF_USESTDHANDLES));
-
- boost::scoped_ptr<STARTUPINFOA> si(new STARTUPINFOA);
- ::CopyMemory(si.get(), setup.startupinfo, sizeof(*setup.startupinfo));
- si->dwFlags |= STARTF_USESTDHANDLES;
-
- switch (infoin.type_)
- {
- case stream_info::close:
- {
- break;
- }
- case stream_info::inherit:
- {
- chin = file_handle::win32_std(STD_INPUT_HANDLE, true);
- break;
- }
- case stream_info::use_file:
- {
- HANDLE h = ::CreateFileA(infoin.file_.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE)
- boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed"));
- chin = file_handle(h);
- break;
- }
- case stream_info::use_handle:
- {
- chin = infoin.handle_;
- chin.win32_set_inheritable(true);
- break;
- }
- case stream_info::use_pipe:
- {
- infoin.pipe_->rend().win32_set_inheritable(true);
- chin = infoin.pipe_->rend();
- break;
- }
- default:
- {
- BOOST_ASSERT(false);
- break;
- }
- }
-
- si->hStdInput = chin.valid() ? chin.get() : INVALID_HANDLE_VALUE;
-
- switch (infoout.type_)
- {
- case stream_info::close:
- {
- break;
- }
- case stream_info::inherit:
- {
- chout = file_handle::win32_std(STD_OUTPUT_HANDLE, true);
- break;
- }
- case stream_info::use_file:
- {
- HANDLE h = ::CreateFileA(infoout.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE)
- boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed"));
- chout = file_handle(h);
- break;
- }
- case stream_info::use_handle:
- {
- chout = infoout.handle_;
- chout.win32_set_inheritable(true);
- break;
- }
- case stream_info::use_pipe:
- {
- infoout.pipe_->wend().win32_set_inheritable(true);
- chout = infoout.pipe_->wend();
- break;
- }
- default:
- {
- BOOST_ASSERT(false);
- break;
- }
- }
-
- si->hStdOutput = chout.valid() ? chout.get() : INVALID_HANDLE_VALUE;
-
- switch (infoerr.type_)
- {
- case stream_info::close:
- {
- break;
- }
- case stream_info::inherit:
- {
- cherr = file_handle::win32_std(STD_ERROR_HANDLE, true);
- break;
- }
- case stream_info::redirect:
- {
- BOOST_ASSERT(infoerr.desc_to_ == 1);
- BOOST_ASSERT(chout.valid());
- cherr = file_handle::win32_dup(chout.get(), true);
- break;
- }
- case stream_info::use_file:
- {
- HANDLE h = ::CreateFileA(infoerr.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE)
- boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed"));
- cherr = file_handle(h);
- break;
- }
- case stream_info::use_handle:
- {
- cherr = infoerr.handle_;
- cherr.win32_set_inheritable(true);
- break;
- }
- case stream_info::use_pipe:
- {
- infoerr.pipe_->wend().win32_set_inheritable(true);
- cherr = infoerr.pipe_->wend();
- break;
- }
- default:
- {
- BOOST_ASSERT(false);
- break;
- }
- }
-
- si->hStdError = cherr.valid() ? cherr.get() : INVALID_HANDLE_VALUE;
-
- PROCESS_INFORMATION pi;
- ::ZeroMemory(&pi, sizeof(pi));
-
- boost::shared_array<char> cmdline = collection_to_win32_cmdline(args);
-
- boost::scoped_array<char> executable(new char[exe.size() + 1]);
-#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE)
- ::strcpy(executable.get(), exe.c_str());
-#else
- ::strcpy_s(executable.get(), exe.size() + 1, exe.c_str());
-#endif
-
- boost::scoped_array<char> workdir(new char[setup.work_directory.size() + 1]);
-#if defined(__CYGWIN__) || defined(_SCL_SECURE_NO_DEPRECATE)
- ::strcpy(workdir.get(), setup.work_directory.c_str());
-#else
- ::strcpy_s(workdir.get(), setup.work_directory.size() + 1, setup.work_directory.c_str());
-#endif
-
- boost::shared_array<char> envstrs = environment_to_win32_strings(env);
-
- if (!::CreateProcessA(executable.get(), cmdline.get(), NULL, NULL, TRUE, 0, envstrs.get(), workdir.get(), si.get(), &pi))
- boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateProcess failed"));
-
- return pi;
-}
-
-}
-}
-}
-
-#endif
Deleted: sandbox/SOC/2010/process/boost/process/environment.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/environment.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,50 +0,0 @@
-//
-// 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
Modified: sandbox/SOC/2010/process/boost/process/operations.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/operations.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/operations.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -21,7 +21,7 @@
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
-# include <boost/process/detail/posix_ops.hpp>
+//# include <boost/process/detail/posix_ops.hpp>
# include <stdlib.h>
# include <unistd.h>
# if defined(__CYGWIN__)
@@ -36,12 +36,22 @@
# 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/process/child.hpp>
+#include <boost/process/context.hpp>
+#include <boost/process/stream_behavior.hpp>
+#include <boost/process/status.hpp>
+#include <boost/process/detail/file_handle.hpp>
+#include <boost/process/detail/stream_detail.hpp>
+#include <boost/process/detail/helper_functions.hpp>
+
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/system/system_error.hpp>
@@ -67,69 +77,80 @@
* \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;
+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;
+ if(pos2 != std::string::npos)
+ dir = path.substr(pos1, pos2 - pos1);
+ else
+ 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)));
-#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;
+ return result;
}
/**
@@ -140,22 +161,27 @@
*/
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;
+ std::string::size_type begin = 0;
+ std::string::size_type end = std::string::npos;
-#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
+ #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);
}
@@ -173,411 +199,120 @@
*
* \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());
- }
+template<class Arguments>
+inline child create_child(const std::string &executable, Arguments args, context &ctx = DEFAULT_CONTEXT){
+ detail::file_handle fhstdin, fhstdout, fhstderr;
+ detail::stream_detail stdin_stream, stdout_stream, stderr_stream;
- 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;
+ stdin_stream.behavior = ctx.stdin_behavior;
+ stdin_stream.stream_handler = STDIN_FILENO;
- PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s);
+ stdout_stream.behavior = ctx.stdout_behavior;
+ stdout_stream.stream_handler = STDOUT_FILENO;
- 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"));
+ stderr_stream.behavior = ctx.stderr_behavior;
+ stderr_stream.stream_handler = STDERR_FILENO;
- 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)
-#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
+ //adjust_output_behavior(ctx); //adjusts the std streams after child lanched
- return launch(exe, args, ctx);
-}
+ std::string p_name = ctx.process_name.empty() ? executable : ctx.process_name;
+ args.insert(args.begin(),p_name);
-/**
- * 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));
- }
+ std::pair<std::size_t, char**> argcv = detail::collection_to_posix_argv(args);
+ char **envp = detail::environment_to_envp(ctx.environment);
- 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;
+ /*
+ detail::posix_setup s;
+ 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(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s);
+ child::id_type pid = ::fork();
+ if (pid == -1)
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_start: fork(2) failed"));
- detail::file_handle fhstdout, fhstderr;
+ else if (pid == 0){
- 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());
- }
+ detail::configure_stream(stdin_stream);
+ detail::configure_stream(stdout_stream);
+ detail::configure_stream(stderr_stream);
- 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();
+ ::execve(executable.c_str(), argcv.second, envp);
- detail::stream_info sie(ctx.stderr_behavior, true);
+ BOOST_ASSERT(false);
- 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);
+ BOOST_ASSERT(pid > 0);
- 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"));
+ if(ctx.stdin_behavior == capture){
+ stdin_stream.object.pipe_->rend().close();
+ fhstdin = stdin_stream.object.pipe_->rend().release();
+ BOOST_ASSERT(fhstdin.valid());
+ }
- cs.push_back(child(pi.dwProcessId, fhstdin, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess)));
- }
+ if(ctx.stdout_behavior == capture){
+ stdout_stream.object.pipe_->wend().close();
+ fhstdout = stdout_stream.object.pipe_->wend().release();
+ BOOST_ASSERT(fhstdout.valid());
+ }
- for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i)
- {
- const typename Entries::value_type::context_type &ctx = entries[i].context;
+ if(ctx.stderr_behavior == capture){
+ stderr_stream.object.pipe_->wend().close();
+ fhstderr = stderr_stream.object.pipe_->wend().release();
+ BOOST_ASSERT(fhstderr.valid());
+ }
- 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();
+ return child(pid, fhstdin, fhstdout, fhstderr);
- detail::stream_info sie(ctx.stderr_behavior, true);
- s.work_directory = ctx.work_directory;
+#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);
- 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();
+ detail::win32_setup s;
s.work_directory = ctx.work_directory;
+ s.startupinfo = &si;
- ::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);
+ 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_pipeline: CloseHandle failed"));
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch: CloseHandle failed"));
- cs.push_back(child(pi.dwProcessId, fhinvalid, fhstdout, fhstderr, detail::file_handle(pi.hProcess)));
- }
+ return child(pi.dwProcessId, fhstdin, 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();
-}
-
-}
-}
+inline child create_child(const std::string &executable, context &ctx = DEFAULT_CONTEXT){
+ std::vector<std::string> args ;
+ return create_child(executable,args,ctx);
+}
+}
+}
#endif
Deleted: sandbox/SOC/2010/process/boost/process/posix_context.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/posix_context.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,118 +0,0 @@
-//
-// 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
Deleted: sandbox/SOC/2010/process/boost/process/posix_operations.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/posix_operations.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,81 +0,0 @@
-//
-// 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
Deleted: sandbox/SOC/2010/process/boost/process/posix_status.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/posix_status.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,128 +0,0 @@
-//
-// 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
Modified: sandbox/SOC/2010/process/boost/process/postream.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/postream.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/postream.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -45,70 +45,66 @@
* 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.
+ * 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();
- }
+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_;
+ /**
+ * The file handle managed by this stream.
+ */
+ detail::file_handle handle_;
+
+ /**
+ * The systembuf object used to manage this stream's data.
+ */
+ detail::systembuf systembuf_;
};
}
Deleted: sandbox/SOC/2010/process/boost/process/self.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/self.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,141 +0,0 @@
-//
-// 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
Modified: sandbox/SOC/2010/process/boost/process/stream_behavior.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/stream_behavior.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/stream_behavior.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -12,8 +12,8 @@
/**
* \file boost/process/stream_behavior.hpp
*
- * Includes the declaration of the stream_behavior class and associated
- * free functions.
+ * Includes the declaration of the stream_behavior
+ *
*/
#ifndef BOOST_PROCESS_STREAM_BEHAVIOR_HPP
@@ -21,214 +21,23 @@
#include <boost/process/config.hpp>
-namespace boost {
-namespace process {
+namespace boost {
+namespace process {
-namespace detail {
- struct stream_info;
-}
+ /*
+ *
+ * stream_behavior defines how a stream should behavior
+ * from a brand-new child.
+ *
+ * inherit: The stream are inherit from it's father
+ * capture: The stream is connected with an anonymous pipe
+ * closed: The stream is closed as soon as the process is created
+ * dummy: Dummy data will be writed or read from this stream
+ *
+ */
+ enum stream_behavior { inherit, capture, closed, dummy};
-/**
- * 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
Deleted: sandbox/SOC/2010/process/boost/process/win32_child.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/win32_child.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,128 +0,0 @@
-//
-// 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
Deleted: sandbox/SOC/2010/process/boost/process/win32_context.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/win32_context.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,61 +0,0 @@
-//
-// 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
Deleted: sandbox/SOC/2010/process/boost/process/win32_operations.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/win32_operations.hpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
+++ (empty file)
@@ -1,77 +0,0 @@
-//
-// 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
Added: sandbox/SOC/2010/process/libs/process/example/child_stdin.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/child_stdin.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,20 @@
+// creates a child process and writes synchronously
+
+#include <boost/all/process.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::string exe = find_executable_in_path("ftp");
+ context ctx;
+ // by default streams are inherited; if this process wants to write
+ // to child's stdin the stream must be redirected (= captured)
+ ctx.stdin_behavior = capture;
+ child c = create_child(exe, ctx);
+ postream &os = c.get_stdin();
+ os << "quit" << std::endl;
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/child_stdout.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/child_stdout.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,20 @@
+// creates a child process and reads synchronously
+
+#include <boost/all/process.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::string exe = find_executable_in_path("hostname");
+ context ctx;
+ // by default streams are inherited; if this process wants to read
+ // from child's stdout the stream must be redirected (= captured)
+ ctx.stdout_behavior = capture;
+ child c = create_child(exe, ctx);
+ pistream &is = c.get_stdout();
+ std::cout << is.rdbuf();
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/create_process.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/create_process.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,35 @@
+/*
+ * Creating process with child_create()
+ */
+
+#include <boost/process/operations.hpp>
+#include <vector>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ //simple usage
+ child c1 = create_child( find_executable_in_path("hostname") );
+
+ //usage with arguments
+ std::vector<std::string> args;
+
+ args.push_back("-a");
+ args.push_back("-a");
+ child c2 = create_child(find_executable_in_path("hostname"), args);
+
+ //complete usage
+ struct context ctx;
+ ctx.environment.insert(std::make_pair("NEW_ENV_VARIABLE", "VALUE"));
+ ctx.process_name = "My_process_name";
+ ctx.stdin_behavior = inherit;
+ ctx.stdout_behavior = closed;
+ ctx.stderr_behavior = closed;
+
+ child c3 = create_child(find_executable_in_path("hostname"), args,ctx);
+
+ return 0;
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/process_factory.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/process_factory.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,16 @@
+// creates a child process using the high-level API
+
+#include <boost/process/all.hpp>
+#include <boost/assign/list_of.hpp>
+#include <string>
+#include <utility>
+
+using namespace boost::process;
+
+int main()
+{
+ process_factory f("C:\\Windows\\notepad.exe");
+ f.environment.insert(std::make_pair("NEW_ENV_VARIABLE", "VALUE"));
+ child = f.create();
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/read_async_from_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/read_async_from_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,50 @@
+// creates a child process and reads asynchronously
+
+#include <boost/all/process.hpp>
+#include <boost/asio.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+using namespace boost::asio;
+
+io_service ioservice;
+pistream *is;
+boost::array<char, 4096> buf;
+
+void begin_read();
+void end_read(const boost::system::error_code &ec, std::size_t bytes_transferred);
+
+int main()
+{
+ std::string exe = find_executable_in_path("hostname");
+ context ctx;
+ // if we want to use asynchronous I/O we must pass a pointer to an
+ // I/O service object; the I/O service object is used to initialize
+ // I/O objects of type pistream and postream within the child object
+ ctx.io_service = &ioservice;
+ // by default streams are inherited; if this process wants to read
+ // from child's stdout the stream must be redirected (= captured)
+ ctx.stdout_behavior = capture;
+ child c = create_child(exe, ctx);
+ is = &c.get_stdout();
+ begin_read();
+ ioservice.run();
+}
+
+void begin_read()
+{
+ is->async_read_some(buffer(buf), boost::bind(&end_read, placeholders::error, placeholders::bytes_transferred));
+}
+
+void end_read(const boost::system::error_code &ec, std::size_t bytes_transferred)
+{
+ if (!ec)
+ {
+ std::cout << std::string(buf.data(), bytes_transferred) << std::flush;
+ begin_read();
+ }
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/read_async_from_parent.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/read_async_from_parent.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,32 @@
+// read asynchronously to parent process (suppose this program is always started as a child process)
+
+#include <boost/all/process.hpp>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+
+using namespace boost::process;
+using namespace boost::asio;
+
+io_service ioservice;
+
+void end_write(const boost::system::error_code &ec);
+
+int main()
+{
+ // Boris: ctx.io_service doesn't make much sense; or are there any other
+ // context settings to configure for a parent?
+ //
+ // Felipe: Maybe as a member of parent?
+
+ parent p(ioservice);
+ String buffer;
+ pistream &is = p.get_stdout();
+
+ async_read(os, &buffer, boost::bind(&end_read, placeholders::error));
+ ioservice.run();
+}
+
+void end_read(const boost::system::error_code &ec)
+{
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/read_from_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/read_from_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,16 @@
+// creates a child process and reads synchronously
+
+#include <boost/all/process.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::string exe = find_executable_in_path("hostname");
+ child c = create_child(exe);
+ pistream &is = c.get_stdout();
+ std::cout << is.rdbuf();
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/read_from_parent.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/read_from_parent.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,14 @@
+// reads synchronously from parent process (suppose this program is always started as a child process)
+
+#include <boost/all/process.hpp>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ parent p;
+ pistream &is = p.get_stdout();
+ std::cout << is.rdbuf();
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/read_info_from_process.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/read_info_from_process.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,25 @@
+// access unrelated processes and read an attribute
+
+#include <boost/process/all.hpp>
+#include <boost/foreach.hpp>
+#include <vector>
+#include <iterator>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::vector<process> processes;
+
+ options opts;
+ opts.children_only = true;
+ // without any option the snapshot contains all processes;
+ // if and how many options Boost.Process is going to support
+ // depends on how much time there is to implement them
+ create_snapshot(std::back_inserter(processes), opts);
+
+ BOOST_FOREACH(process &p, processes)
+ std::cout << p.name() << std::endl;
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/terminate_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/terminate_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,15 @@
+// creates a child and terminates it
+
+#include <boost/all/process.hpp>
+#include <string>
+
+using namespace boost::process;
+
+int main()
+{
+ std::string exe = find_executable_in_path("hostname");
+ child c = create_child(exe);
+ c.terminate();
+}
+
+
Added: sandbox/SOC/2010/process/libs/process/example/wait_async_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/wait_async_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,45 @@
+// creates a child process and reads asynchronously
+
+#include <boost/all/process.hpp>
+#include <boost/asio.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+using namespace boost::asio;
+
+io_service ioservice;
+pistream *is;
+boost::array<char, 4096> buf;
+
+void begin_read();
+void end_read(const boost::system::error_code &ec, std::size_t bytes_transferred);
+
+int main()
+{
+ std::string exe = find_executable_in_path("hostname");
+ context ctx;
+ ctx.io_service = &ioservice;
+ child c = create_child(exe, ctx);
+ is = &c.get_stdout();
+ begin_read();
+ ioservice.run();
+}
+
+void begin_read()
+{
+ is->async_read_some(buffer(buf), boost::bind(&end_read, placeholders::error, placeholders::bytes_transferred));
+}
+
+void end_read(const boost::system::error_code &ec, std::size_t bytes_transferred)
+{
+ if (!ec)
+ {
+ std::cout << std::string(buf.data(), bytes_transferred) << std::flush;
+ begin_read();
+ }
+}
+
+
Added: sandbox/SOC/2010/process/libs/process/example/wait_async_process.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/wait_async_process.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,36 @@
+// access an unrelated process and wait asynchronously
+
+#include <boost/process/all.hpp>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <vector>
+#include <iterator>
+#include <iostream>
+
+using namespace boost::process;
+using namespace boost::asio;
+
+io_service ioservice;
+status s(ioservice);
+
+void end_wait(const boost::system::error_code &ec);
+
+int main()
+{
+ std::vector<process> processes;
+ create_snapshot(std::back_inserter(processes));
+ process p = processes.front();
+ // if status is an I/O object it must be bound to an I/O service object;
+ // we pass ioservice as a parameter to bind the status object which is
+ // created within the status() method to the I/O service object;
+ status &s = p.status(ioservice);
+ s.async_wait(boost::bind(&end_wait, placeholders::error));
+ ioservice.run();
+}
+
+void end_wait(const boost::system::error_code &ec)
+{
+ if (!ec)
+ std::cout << "process exited" << std::endl;
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/wait_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/wait_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,17 @@
+// creates a child process and waits synchronously
+
+#include <boost/process/all.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::string exe = find_executable_in_path("hostname");
+ child c = create_child(exe);
+ status s = c.wait();
+ if (s.exited())
+ std::cout << s.exit_code() << std::endl;
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/wait_process.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/wait_process.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,19 @@
+// access an unrelated process and wait synchronously
+
+#include <boost/process/all.hpp>
+#include <vector>
+#include <iterator>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::vector<process> processes;
+ create_snapshot(std::back_inserter(processes));
+ process p = processes.front();
+ status s = p.wait();
+ if (s.exited())
+ std::cout << s.exit_code() << std::endl;
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/write_async_to_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/write_async_to_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,36 @@
+// creates a child process and writes asynchronously
+
+#include <boost/all/process.hpp>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+using namespace boost::asio;
+
+io_service ioservice;
+
+void end_write(const boost::system::error_code &ec);
+
+int main()
+{
+ std::string exe = find_executable_in_path("ftp");
+ context ctx;
+ // if we want to use asynchronous I/O we must pass a pointer to an
+ // I/O service object; the I/O service object is used to initialize
+ // I/O objects of type pistream and postream within the child object
+ context.io_service = &ioservice;
+ // by default streams are inherited; if this process wants to write
+ // to child's stdin the stream must be redirected (= captured)
+ ctx.stdin_behavior = capture;
+ child c = create_child(exe, ctx);
+ postream &os = c.get_stdin();
+ async_write(os, buffer("quit\n"), boost::bind(&end_write, placeholders::error));
+ ioservice.run();
+}
+
+void end_write(const boost::system::error_code &ec)
+{
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/write_async_to_parent.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/write_async_to_parent.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,27 @@
+// write asynchronously to parent process (suppose this program is always started as a child process)
+
+#include <boost/all/process.hpp>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+
+using namespace boost::process;
+using namespace boost::asio;
+
+io_service ioservice;
+
+void end_write(const boost::system::error_code &ec);
+
+int main()
+{
+ // ctx.io_service doesn't make much sense; or are there any other
+ // context settings to configure for a parent?
+ parent p(ioservice);
+ postream &os = p.get_stdin();
+ async_write(os, buffer("Hello, world!"), boost::bind(&end_write, placeholders::error));
+ ioservice.run();
+}
+
+void end_write(const boost::system::error_code &ec)
+{
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/write_info_to_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/write_info_to_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,26 @@
+// access child processes and write an attribute
+
+#include <boost/process/all.hpp>
+#include <boost/foreach.hpp>
+#include <vector>
+#include <iterator>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::vector<process> processes;
+
+ options opts;
+ opts.children_only = true;
+ // without any option the snapshot contains all processes;
+ // if and how many options Boost.Process is going to support
+ // depends on how much time there is to implement them
+ create_snapshot(std::back_inserter(processes), opts);
+
+ BOOST_FOREACH(process &p, processes)
+ p.set_priority(HIGH); //Not part of base plan
+
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/write_info_to_self.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/write_info_to_self.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,15 @@
+// access child processes and write an attribute
+
+#include <boost/process/all.hpp>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+
+ self &s = self::get_instance();
+ s.set_priority(HIGH); //implement latter?
+
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/write_to_child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/write_to_child.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,20 @@
+// creates a child process and writes synchronously
+
+#include <boost/all/process.hpp>
+#include <string>
+#include <iostream>
+
+using namespace boost::process;
+
+int main()
+{
+ std::string exe = find_executable_in_path("ftp");
+ context ctx;
+ // by default streams are inherited; if this process wants to write
+ // to child's stdin the stream must be redirected (= captured)
+ ctx.stdin_behavior = capture;
+ child c = create_child(exe, ctx);
+ postream &os = c.get_stdin();
+ os << "quit" << std::endl;
+}
+
Added: sandbox/SOC/2010/process/libs/process/example/write_to_parent.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/example/write_to_parent.cpp 2010-05-15 13:52:38 EDT (Sat, 15 May 2010)
@@ -0,0 +1,13 @@
+// write synchronously to parent process (suppose this program is always started as a child process)
+
+#include <boost/all/process.hpp>
+
+using namespace boost::process;
+
+int main()
+{
+ parent p;
+ postream &os = p.get_stdin();
+ os << "Hello, world!" << std::endl;
+}
+
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