|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r64280 - in sandbox/SOC/2010/process: boost boost/process boost/process/detail libs/process/test
From: boris_at_[hidden]
Date: 2010-07-22 20:02:24
Author: bschaeling
Date: 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
New Revision: 64280
URL: http://svn.boost.org/trac/boost/changeset/64280
Log:
Reviewed entire library
Added:
sandbox/SOC/2010/process/boost/process/detail/windows_helpers.hpp
- copied, changed from r64257, /sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp
sandbox/SOC/2010/process/libs/process/test/child.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/test/child.hpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/test/environment.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/test/executable.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/test/process.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/test/process.hpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/test/self.cpp (contents, props changed)
sandbox/SOC/2010/process/libs/process/test/status.cpp (contents, props changed)
Removed:
sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp
Text files modified:
sandbox/SOC/2010/process/boost/process.hpp | 32 -
sandbox/SOC/2010/process/boost/process/all.hpp | 43 +-
sandbox/SOC/2010/process/boost/process/child.hpp | 31 --
sandbox/SOC/2010/process/boost/process/config.hpp | 19
sandbox/SOC/2010/process/boost/process/context.hpp | 100 ++++++-
sandbox/SOC/2010/process/boost/process/detail/basic_status.hpp | 15 +
sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp | 7
sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp | 6
sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp | 15
sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp | 6
sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp | 8
sandbox/SOC/2010/process/boost/process/detail/windows_helpers.hpp | 26 +-
sandbox/SOC/2010/process/boost/process/environment.hpp | 5
sandbox/SOC/2010/process/boost/process/operations.hpp | 148 ++++++++----
sandbox/SOC/2010/process/boost/process/pid_type.hpp | 14 +
sandbox/SOC/2010/process/boost/process/pipe.hpp | 3
sandbox/SOC/2010/process/boost/process/pistream.hpp | 3
sandbox/SOC/2010/process/boost/process/postream.hpp | 17
sandbox/SOC/2010/process/boost/process/process.hpp | 112 ++++-----
sandbox/SOC/2010/process/boost/process/self.hpp | 65 ++--
sandbox/SOC/2010/process/boost/process/status.hpp | 9
sandbox/SOC/2010/process/boost/process/stream_behavior.hpp | 478 ++++++++++++++++++++-------------------
sandbox/SOC/2010/process/libs/process/test/Jamfile.jam | 8
sandbox/SOC/2010/process/libs/process/test/arguments.cpp | 4
24 files changed, 655 insertions(+), 519 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-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,33 +3,23 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
-/**
- * \file boost/process.hpp
- *
- * Convenience header that includes all other Boost.Process public header
- * files.
- */
+/**
+ * \file boost/process.hpp
+ *
+ * Convenience header that includes all public Boost.Process header files.
+ */
-#ifndef BOOST_PROCESS_HPP
-#define BOOST_PROCESS_HPP
+#ifndef BOOST_PROCESS_HPP
+#define BOOST_PROCESS_HPP
-#include <boost/process/config.hpp>
-#include <boost/process/child.hpp>
-#include <boost/process/context.hpp>
-#include <boost/process/environment.hpp>
-#include <boost/process/operations.hpp>
-#include <boost/process/pipe.hpp>
-#include <boost/process/pistream.hpp>
-#include <boost/process/postream.hpp>
-#include <boost/process/process.hpp>
-#include <boost/process/status.hpp>
-#include <boost/process/stream_behavior.hpp>
+#include <boost/process/all.hpp>
-#endif
+#endif
Modified: sandbox/SOC/2010/process/boost/process/all.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/all.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/all.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,33 +3,34 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
-/**
- * \file boost/process/all.hpp
- *
- * Convenience header that includes all other Boost.Process public header
- * files.
- */
+/**
+ * \file boost/process/all.hpp
+ *
+ * Convenience header that includes all public Boost.Process header files.
+ */
-#ifndef BOOST_PROCESS_ALL_HPP
-#define BOOST_PROCESS_ALL_HPP
+#ifndef BOOST_PROCESS_ALL_HPP
+#define BOOST_PROCESS_ALL_HPP
-#include <boost/process/config.hpp>
-#include <boost/process/child.hpp>
-#include <boost/process/context.hpp>
-#include <boost/process/environment.hpp>
-#include <boost/process/operations.hpp>
-#include <boost/process/pipe.hpp>
-#include <boost/process/pistream.hpp>
-#include <boost/process/postream.hpp>
-#include <boost/process/process.hpp>
-#include <boost/process/status.hpp>
-#include <boost/process/stream_behavior.hpp>
+#include <boost/process/child.hpp>
+#include <boost/process/context.hpp>
+#include <boost/process/environment.hpp>
+#include <boost/process/operations.hpp>
+#include <boost/process/pid_type.hpp>
+#include <boost/process/pipe.hpp>
+#include <boost/process/pistream.hpp>
+#include <boost/process/postream.hpp>
+#include <boost/process/process.hpp>
+#include <boost/process/self.hpp>
+#include <boost/process/status.hpp>
+#include <boost/process/stream_behavior.hpp>
-#endif
+#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-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -29,12 +30,12 @@
#endif
#include <boost/process/process.hpp>
+#include <boost/process/pid_type.hpp>
#include <boost/process/pistream.hpp>
#include <boost/process/postream.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/assert.hpp>
-#include <vector>
namespace boost {
namespace process {
@@ -54,16 +55,10 @@
* 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())
+ child(pid_type id, detail::file_handle fhstdin,
+ detail::file_handle fhstdout, detail::file_handle fhstderr)
: process(id)
-#if defined(BOOST_WINDOWS_API)
- , process_handle_(fhprocess.release(), ::CloseHandle)
-#endif
{
if (fhstdin.valid())
stdin_.reset(new postream(fhstdin));
@@ -139,24 +134,8 @@
* data stream.
*/
boost::shared_ptr<pistream> stderr_;
-
-#if defined(BOOST_WINDOWS_API)
- /**
- * Process handle owned by RAII object.
- */
- boost::shared_ptr<void> process_handle_;
-#endif
-
};
-/**
- * Collection of child objects.
- *
- * This convenience type represents a collection of child objects backed
- * by a vector.
- */
-typedef std::vector<child> children;
-
}
}
Modified: sandbox/SOC/2010/process/boost/process/config.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/config.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/config.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,8 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008 Ilya Sokolov
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -27,8 +27,10 @@
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
-#if defined(BOOST_WINDOWS_API)
-# include <windows.h>
+#if defined(BOOST_POSIX_API)
+# include <errno.h>
+#elif defined(BOOST_WINDOWS_API)
+# include <windows.h>
#endif
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN)
@@ -38,9 +40,10 @@
* value which specifies the system's maximal supported path length.
* By default it is set to 259. You should set the macro to PATH_MAX
* which should be defined in limits.h provided by your operating system
- * if you experience problems when instantiating a context. The
- * constructor of context tries to find out the maximal supported path
- * length but uses BOOST_PROCESS_POSIX_PATH_MAX if it fails.
+ * if you experience problems when calling boost::process::self::get_work_dir().
+ * This function tries to find out the maximal supported path length but uses
+ * BOOST_PROCESS_POSIX_PATH_MAX if it fails. Please note that the function is
+ * also called when you instantiate a context.
*/
# define BOOST_PROCESS_POSIX_PATH_MAX 259
# endif
@@ -52,7 +55,7 @@
#if defined(BOOST_POSIX_API)
# define BOOST_PROCESS_LAST_ERROR errno
#elif defined(BOOST_WINDOWS_API)
-# define BOOST_PROCESS_LAST_ERROR ::GetLastError()
+# define BOOST_PROCESS_LAST_ERROR GetLastError()
#endif
#define BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(what) \
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-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -19,47 +19,109 @@
#ifndef BOOST_PROCESS_CONTEXT_HPP
#define BOOST_PROCESS_CONTEXT_HPP
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+# include <unistd.h>
+#elif defined(BOOST_WINDOWS_API)
+# include <windows.h>
+#endif
+
#include <boost/process/stream_behavior.hpp>
#include <boost/process/environment.hpp>
#include <boost/process/self.hpp>
#include <boost/shared_ptr.hpp>
-#include <boost/make_shared.hpp>
+#include <string>
namespace boost {
namespace process {
-/*
- * Context class that defines how a process is created.
+/**
+ * Context class to define how a child process is created.
+ *
+ * The context class is used to configure standard streams and
+ * to set the work directory and environment variables. It is also
+ * used to change a process name (the variable commonly known as
+ * argv[0]).
*/
struct context
{
+ /**
+ * Behavior of the standard input stream.
+ */
boost::shared_ptr<behavior::stream> stdin_behavior;
+
+ /**
+ * Behavior of the standard output stream.
+ */
boost::shared_ptr<behavior::stream> stdout_behavior;
+
+ /**
+ * Behavior of the standard error stream.
+ */
boost::shared_ptr<behavior::stream> stderr_behavior;
+
+ /**
+ * Process name.
+ *
+ * The child process can access the process name via a variable
+ * commonly known as argv[0].
+ */
std::string process_name;
+
+ /**
+ * Work directory.
+ */
std::string work_dir;
+
+ /**
+ * Environment variables.
+ */
environment_t environment;
- /**
- * Constructs a process context.
- *
- * Sets behavior of standard streams (inherit), current work directory
- * and environment variables.
+ /**
+ * Constructs a process context.
+ *
+ * The default behavior of standard streams is to inherit them. The current
+ * work directory is also the work directory of the child process. The child
+ * process also inherits all environment variables.
*/
context()
-#if defined(BOOST_POSIX_API)
- : stdin_behavior(behavior::inherit::def(STDIN_FILENO)),
- stdout_behavior(behavior::inherit::def(STDOUT_FILENO)),
- stderr_behavior(behavior::inherit::def(STDERR_FILENO)),
-#elif defined(BOOST_WINDOWS_API)
- : stdin_behavior(behavior::inherit::def(::GetStdHandle(STD_INPUT_HANDLE))),
- stdout_behavior(behavior::inherit::def(::GetStdHandle(STD_OUTPUT_HANDLE))),
- stderr_behavior(behavior::inherit::def(::GetStdHandle(STD_ERROR_HANDLE))),
-#endif
- work_dir(self::get_work_dir()),
- environment(self::get_environment())
+#if defined(BOOST_POSIX_API)
+ : stdin_behavior(behavior::inherit::def(STDIN_FILENO)),
+ stdout_behavior(behavior::inherit::def(STDOUT_FILENO)),
+ stderr_behavior(behavior::inherit::def(STDERR_FILENO)),
+#elif defined(BOOST_WINDOWS_API)
+ : stdin_behavior(behavior::inherit::def(GetStdHandle(STD_INPUT_HANDLE))),
+ stdout_behavior(behavior::inherit::def(GetStdHandle(STD_OUTPUT_HANDLE))),
+ stderr_behavior(behavior::inherit::def(GetStdHandle(STD_ERROR_HANDLE))),
+#endif
+ work_dir(self::get_work_dir()),
+ environment(self::get_environment())
+ {
+ }
+
+#if defined(BOOST_PROCESS_DOXYGEN) || defined(BOOST_POSIX_API)
+ /**
+ * Setups a child process.
+ *
+ * This is an extension point to support more configuration options for
+ * child processes. You override setup() in a user-defined context class
+ * which should be derived from this class.
+ *
+ * On POSIX platforms setup() is called in the child process. On Windows
+ * platforms setup() is called in the parent process. Furthermore a
+ * reference to a STARTUPINFO structure is passed as a parameter on Windows
+ * platforms.
+ */
+ void setup()
+ {
+ }
+#elif defined(BOOST_WINDOWS_API)
+ void setup(STARTUPINFO &sainfo)
{
}
+#endif
};
}
Modified: sandbox/SOC/2010/process/boost/process/detail/basic_status.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/basic_status.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/basic_status.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -27,6 +28,12 @@
namespace process {
namespace detail {
+/**
+ * The basic_status class to wait for processes to exit.
+ *
+ * The basic_status class is a Boost.Asio I/O object and supports synchronous
+ * and asynchronous wait operations. It must be instantiated with a Service.
+ */
template <typename Service>
class basic_status
: public boost::asio::basic_io_object<Service>
@@ -37,11 +44,17 @@
{
}
+ /**
+ * Waits synchronously for a process to exit.
+ */
int wait(pid_type pid)
{
return this->service.wait(this->implementation, pid);
}
+ /**
+ * Waits asynchronously for a process to exit.
+ */
template <typename Handler>
void async_wait(pid_type pid, Handler handler)
{
Modified: sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/basic_status_service.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -46,6 +47,10 @@
namespace process {
namespace detail {
+/**
+ * The basic_status_service class provides the service to wait for processes
+ * synchronously and asynchronously.
+ */
template <typename StatusImplementation = status_impl>
class basic_status_service
: public boost::asio::detail::service_base<StatusImplementation>
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-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -13,8 +14,7 @@
/**
* \file boost/process/detail/file_handle.hpp
*
- * Includes the declaration of the file_handle class. This file is for
- * internal usage only and must not be included by the library user.
+ * Includes the declaration of the file_handle class.
*/
#ifndef BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP
Modified: sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -11,11 +12,9 @@
//
/**
- * \file boost/process/detail/posix_helper.hpp
- *
- * Includes the declaration of helper functions for the operations in a POSIX
- * system.
+ * \file boost/process/detail/posix_helpers.hpp
*
+ * Includes the declaration of helper functions for POSIX systems.
*/
#ifndef BOOST_PROCESS_POSIX_HELPERS_HPP
@@ -41,12 +40,14 @@
* NULL-terminated string of the form var=value; these must also be
* released by the caller.
*
+ * 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 representing the
* enviroment's content. Each array entry is a NULL-terminated
- * string of the form var=value. The caller is responsible of
+ * string of the form var=value. The caller is responsible for
* freeing them.
*/
inline std::pair<std::size_t, char**> environment_to_envp(const environment_t &env)
@@ -77,7 +78,7 @@
* 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.
+ * to the executable. The caller is responsible for freeing them.
*/
template <class Arguments>
inline std::pair<std::size_t, char**> collection_to_argv(const Arguments &args)
Modified: sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/status_impl.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -68,6 +69,9 @@
Handler handler_;
};
+/**
+ * The status_impl class saves internal data of every status I/O object.
+ */
class status_impl
{
public:
Modified: sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -13,8 +14,7 @@
/**
* \file boost/process/detail/systembuf.hpp
*
- * Includes the declaration of the systembuf class. This file is for
- * internal usage only and must not be included by the library user.
+ * Includes the declaration of the systembuf class.
*/
#ifndef BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP
@@ -58,7 +58,7 @@
*/
class systembuf : public std::streambuf, public boost::noncopyable
{
- friend class ::boost::process::postream;
+ friend class boost::process::postream;
public:
#if defined(BOOST_PROCESS_DOXYGEN)
Deleted: sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
+++ (empty file)
@@ -1,132 +0,0 @@
-//
-// Boost.Process
-// ~~~~~~~~~~~~~
-//
-// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
-// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-/**
- * \file boost/process/detail/helper_functions.hpp
- *
- * Includes the declaration of helper functions for the operations in a win32
- * system.
- *
- */
-
-#ifndef BOOST_PROCESS_WIN32_HELPERS_HPP
-#define BOOST_PROCESS_WIN32_HELPERS_HPP
-
-#include <boost/process/config.hpp>
-#include <boost/process/environment.hpp>
-#include <boost/shared_array.hpp>
-#include <string>
-#include <vector>
-#include <cstddef>
-#include <string.h>
-#include <windows.h>
-
-namespace boost {
-namespace process {
-namespace detail {
-
-/**
- * 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(environment_t &env)
-{
- boost::shared_array<char> envp;
-
- if (env.empty())
- {
- envp.reset(new char[2]);
- ZeroMemory(envp.get(), 2);
- }
- else
- {
- std::string s;
- for (environment_t::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;
-}
-
-/**
- * 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;
-}
-
-}
-}
-}
-
-#endif
Copied: sandbox/SOC/2010/process/boost/process/detail/windows_helpers.hpp (from r64257, /sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp)
==============================================================================
--- /sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/windows_helpers.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -11,15 +12,13 @@
//
/**
- * \file boost/process/detail/helper_functions.hpp
- *
- * Includes the declaration of helper functions for the operations in a win32
- * system.
+ * \file boost/process/detail/windows_helpers.hpp
*
+ * Includes the declaration of helper functions for Windows systems.
*/
-#ifndef BOOST_PROCESS_WIN32_HELPERS_HPP
-#define BOOST_PROCESS_WIN32_HELPERS_HPP
+#ifndef BOOST_PROCESS_WINDOWS_HELPERS_HPP
+#define BOOST_PROCESS_WINDOWS_HELPERS_HPP
#include <boost/process/config.hpp>
#include <boost/process/environment.hpp>
@@ -42,11 +41,13 @@
* allocated in dynamic memory; the caller must free it when not
* used any more. This is enforced by the use of a shared pointer.
*
+ * This operation is only available on Windows systems.
+ *
* \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(environment_t &env)
+inline boost::shared_array<char> environment_to_windows_strings(environment_t &env)
{
boost::shared_array<char> envp;
@@ -75,9 +76,10 @@
}
/**
- * 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.
+ * 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.
*
@@ -86,7 +88,7 @@
* 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)
+inline boost::shared_array<char> collection_to_windows_cmdline(const Arguments &args)
{
typedef std::vector<std::string> arguments_t;
arguments_t args2;
Modified: sandbox/SOC/2010/process/boost/process/environment.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/environment.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/environment.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -28,7 +29,7 @@
/**
* Representation of a process' environment variables.
*
- * The environment is a map that stablishes an unidirectional
+ * The environment is a map that establishes an unidirectional
* association between variable names and their values and is
* represented by a string to string map.
*
Modified: sandbox/SOC/2010/process/boost/process/operations.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/operations.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/operations.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -23,15 +24,16 @@
#if defined(BOOST_POSIX_API)
# include <boost/process/detail/posix_helpers.hpp>
+# include <utility>
+# include <cstddef>
# include <stdlib.h>
# include <unistd.h>
# if defined(__CYGWIN__)
-# include <boost/scoped_array.hpp>
# include <sys/cygwin.h>
# endif
#elif defined(BOOST_WINDOWS_API)
-# include <boost/process/detail/win32_helpers.hpp>
-# include <boost/algorithm/string/predicate.hpp>
+# include <boost/process/detail/windows_helpers.hpp>
+# include <boost/shared_array.hpp>
# include <windows.h>
#else
# error "Unsupported platform."
@@ -39,7 +41,6 @@
#include <boost/process/child.hpp>
#include <boost/process/context.hpp>
-#include <boost/process/stream_behavior.hpp>
#include <boost/process/detail/file_handle.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string/predicate.hpp>
@@ -49,8 +50,6 @@
#include <boost/assert.hpp>
#include <string>
#include <vector>
-#include <stdexcept>
-#include <cstddef>
namespace boost {
namespace process {
@@ -79,20 +78,22 @@
#if defined(BOOST_POSIX_API)
if (path.empty())
{
- const char *envpath = ::getenv("PATH");
+ 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)));
-
+ boost::throw_exception(boost::filesystem::filesystem_error(
+ BOOST_PROCESS_SOURCE_LOCATION "file not found", 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()))
+ if (!cygwin_posix_path_list_p(path.c_str()))
{
- int size = ::cygwin_win32_to_posix_path_list_buf_size(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());
+ cygwin_win32_to_posix_path_list(path.c_str(), cygpath.get());
path = cygpath.get();
}
#endif
@@ -101,9 +102,11 @@
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))
+ 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());
@@ -114,7 +117,8 @@
{
char buf[MAX_PATH];
char *dummy;
- DWORD size = ::SearchPathA(path.empty() ? NULL : path.c_str(), file.c_str(), *ext, MAX_PATH, buf, &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)
{
@@ -126,7 +130,10 @@
#endif
if (result.empty())
- boost::throw_exception(boost::filesystem::filesystem_error(BOOST_PROCESS_SOURCE_LOCATION "file not found", file, boost::system::errc::make_error_code(boost::system::errc::no_such_file_or_directory)));
+ boost::throw_exception(boost::filesystem::filesystem_error(
+ BOOST_PROCESS_SOURCE_LOCATION "file not found", file,
+ boost::system::errc::make_error_code(
+ boost::system::errc::no_such_file_or_directory)));
return result;
}
@@ -151,7 +158,9 @@
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")))
+ 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
@@ -162,8 +171,7 @@
* Starts a new child process.
*
* Launches a new process based on the binary image specified by the
- * executable, the set of arguments to be passed to it and several
- * parameters that describe the execution context.
+ * executable, the set of arguments passed to it and the execution context.
*
* \remark Blocking remarks: This function may block if the device
* holding the executable blocks when loading the image. This might
@@ -171,10 +179,11 @@
*
* \return A handle to the new child process.
*/
-template <class Arguments>
-inline child create_child(const std::string &executable, Arguments args, context ctx = context())
+template <typename Arguments, typename Context>
+inline child create_child(const std::string &executable, Arguments args, Context ctx)
{
- std::string p_name = ctx.process_name.empty() ? executable : ctx.process_name;
+ std::string p_name = ctx.process_name.empty() ?
+ executable_to_progname(executable) : ctx.process_name;
args.insert(args.begin(), p_name);
#if defined(BOOST_POSIX_API)
@@ -199,7 +208,7 @@
closeflags[i] = true;
int stdin_fd = ctx.stdin_behavior->get_child_end();
- if (stdin_fd != -1 && stdin_fd < maxdescs)
+ if (stdin_fd != -1)
{
if (dup2(stdin_fd, STDIN_FILENO) == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup2() failed");
@@ -207,7 +216,7 @@
}
int stdout_fd = ctx.stdout_behavior->get_child_end();
- if (stdout_fd != -1 && stdout_fd < maxdescs)
+ if (stdout_fd != -1)
{
if (dup2(stdout_fd, STDOUT_FILENO) == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup2() failed");
@@ -215,7 +224,7 @@
}
int stderr_fd = ctx.stderr_behavior->get_child_end();
- if (stderr_fd != -1 && stderr_fd < maxdescs)
+ if (stderr_fd != -1)
{
if (dup2(stderr_fd, STDERR_FILENO) == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup2() failed");
@@ -227,6 +236,8 @@
if (closeflags[i])
close(i);
}
+
+ ctx.setup();
}
catch (const boost::system::system_error &e)
{
@@ -235,8 +246,10 @@
std::exit(127);
}
- std::pair<std::size_t, char**> argv = detail::collection_to_argv(args);
- std::pair<std::size_t, char**> envp = detail::environment_to_envp(ctx.environment);
+ std::pair<std::size_t, char**> argv =
+ detail::collection_to_argv(args);
+ std::pair<std::size_t, char**> envp =
+ detail::environment_to_envp(ctx.environment);
execve(executable.c_str(), argv.second, envp.second);
@@ -248,7 +261,9 @@
delete[] envp.second[i];
delete[] envp.second;
- boost::system::system_error e(boost::system::error_code(errno, boost::system::get_system_category()), BOOST_PROCESS_SOURCE_LOCATION "execve(2) failed");
+ boost::system::system_error e(boost::system::error_code(errno,
+ boost::system::get_system_category()),
+ BOOST_PROCESS_SOURCE_LOCATION "execve(2) failed");
write(STDERR_FILENO, e.what(), std::strlen(e.what()));
write(STDERR_FILENO, "\n", 1);
std::exit(127);
@@ -258,11 +273,11 @@
BOOST_ASSERT(pid > 0);
if (ctx.stdin_behavior->get_child_end() != -1)
- ::close(ctx.stdin_behavior->get_child_end());
+ close(ctx.stdin_behavior->get_child_end());
if (ctx.stdout_behavior->get_child_end() != -1)
- ::close(ctx.stdout_behavior->get_child_end());
+ close(ctx.stdout_behavior->get_child_end());
if (ctx.stderr_behavior->get_child_end() != -1)
- ::close(ctx.stderr_behavior->get_child_end());
+ close(ctx.stderr_behavior->get_child_end());
return child(pid,
detail::file_handle(ctx.stdin_behavior->get_parent_end()),
@@ -278,36 +293,73 @@
startup_info.hStdOutput = ctx.stdout_behavior->get_child_end();
startup_info.hStdError = ctx.stderr_behavior->get_child_end();
+ ctx.setup(startup_info);
+
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
- boost::shared_array<char> cmdline = detail::collection_to_win32_cmdline(args);
+ boost::shared_array<char> cmdline =
+ detail::collection_to_windows_cmdline(args);
boost::scoped_array<char> exe(new char[executable.size() + 1]);
- ::strcpy_s(exe.get(), executable.size() + 1, executable.c_str());
+ strcpy_s(exe.get(), executable.size() + 1, executable.c_str());
boost::scoped_array<char> workdir(new char[ctx.work_dir.size() + 1]);
- ::strcpy_s(workdir.get(), ctx.work_dir.size() + 1, ctx.work_dir.c_str());
+ strcpy_s(workdir.get(), ctx.work_dir.size() + 1, ctx.work_dir.c_str());
+
+ boost::shared_array<char> envstrs =
+ detail::environment_to_windows_strings(ctx.environment);
- boost::shared_array<char> envstrs = detail::environment_to_win32_strings(ctx.environment);
+ if (CreateProcessA(exe.get(), cmdline.get(), NULL, NULL, TRUE, 0,
+ envstrs.get(), workdir.get(), &startup_info, &pi) == 0)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed");
- if (CreateProcessA(exe.get(), cmdline.get(), NULL, NULL, TRUE, 0, envstrs.get(), workdir.get(), &startup_info, &pi) == 0)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed");
+ if (!CloseHandle(pi.hProcess))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
if (!CloseHandle(pi.hThread))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
- return child(pi.dwProcessId,
- detail::file_handle(ctx.stdin_behavior->get_parent_end()),
- detail::file_handle(ctx.stdout_behavior->get_parent_end()),
- detail::file_handle(ctx.stderr_behavior->get_parent_end()),
- detail::file_handle(pi.hProcess));
-#endif
+ return child(pi.dwProcessId,
+ detail::file_handle(ctx.stdin_behavior->get_parent_end()),
+ detail::file_handle(ctx.stdout_behavior->get_parent_end()),
+ detail::file_handle(ctx.stderr_behavior->get_parent_end()));
+#endif
+}
+
+/**
+ * Starts a new child process.
+ *
+ * Launches a new process based on the binary image specified by the
+ * executable.
+ *
+ * \remark Blocking remarks: This function may block if the device
+ * holding the executable blocks when loading the image. This might
+ * happen if, e.g., the binary is being loaded from a network share.
+ *
+ * \return A handle to the new child process.
+ */
+inline child create_child(const std::string &executable)
+{
+ return create_child(executable, std::vector<std::string>(), context());
}
-inline child create_child(const std::string &executable, context ctx = context())
+/**
+ * Starts a new child process.
+ *
+ * Launches a new process based on the binary image specified by the
+ * executable and the set of arguments passed to it.
+ *
+ * \remark Blocking remarks: This function may block if the device
+ * holding the executable blocks when loading the image. This might
+ * happen if, e.g., the binary is being loaded from a network share.
+ *
+ * \return A handle to the new child process.
+ */
+template <typename Arguments>
+inline child create_child(const std::string &executable, Arguments args)
{
- return create_child(executable, std::vector<std::string>(), ctx);
+ return create_child(executable, args, context());
}
}
Modified: sandbox/SOC/2010/process/boost/process/pid_type.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/pid_type.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/pid_type.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -31,6 +32,17 @@
namespace process {
#if defined(BOOST_PROCESS_DOXYGEN)
+/**
+ * Opaque name for the process identifier type.
+ *
+ * Each operating system identifies processes using a specific type.
+ * The \a pid_type type is used to transparently refer to a process
+ * regardless of the operating system in which this class is used.
+ *
+ * This type is guaranteed to be an integral type on all supported
+ * platforms. On POSIX systems it is defined as pid_t, on Windows systems as
+ * DWORD.
+ */
typedef NativeProcessId pid_type;
#elif defined(BOOST_POSIX_API)
typedef pid_t pid_type;
Modified: sandbox/SOC/2010/process/boost/process/pipe.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/pipe.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/pipe.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Modified: sandbox/SOC/2010/process/boost/process/pistream.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/pistream.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/pistream.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Modified: sandbox/SOC/2010/process/boost/process/postream.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/postream.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/postream.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -46,13 +47,13 @@
* 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
{
Modified: sandbox/SOC/2010/process/boost/process/process.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/process.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/process.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -22,9 +23,11 @@
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
-# include <cerrno>
-# include <sys/wait.h>
+# include <unistd.h>
+# include <sys/types.h>
# include <signal.h>
+
+# include <sys/wait.h>
#elif defined(BOOST_WINDOWS_API)
# include <cstdlib>
# include <windows.h>
@@ -32,54 +35,32 @@
# error "Unsupported platform."
#endif
-#include <boost/process/status.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/shared_ptr.hpp>
+#include <boost/process/pid_type.hpp>
namespace boost {
namespace process {
/**
- * The process class provides access to an unrelated process (a process
- * which is neither a child process nor a parent process nor self).
+ * Process class to represent any running process.
*/
class process
{
public:
-#if defined(BOOST_PROCESS_DOXYGEN)
- /**
- * Opaque name for the native process' identifier type.
- *
- * Each operating system identifies processes using a specific type.
- * The \a id_type type is used to transparently refer to a process
- * regardless of the operating system in which this class is used.
- *
- * This type is guaranteed to be an integral type on all supported
- * platforms.
- */
- typedef NativeProcessId id_type;
-#elif defined(BOOST_POSIX_API)
- typedef pid_t id_type;
-#elif defined(BOOST_WINDOWS_API)
- typedef DWORD id_type;
-#endif
-
/**
* Constructs a new process object.
*
* Creates a new process object that represents a running process
* within the system.
*/
- process(id_type id)
+ process(pid_type id)
: id_(id)
{
}
/**
- * Returns the process' identifier.
+ * Returns the process identifier.
*/
- id_type get_id() const
+ pid_type get_id() const
{
return id_;
}
@@ -103,19 +84,19 @@
void terminate(bool force = false) const
{
#if defined(BOOST_POSIX_API)
- if (::kill(id_, force ? SIGKILL : SIGTERM) == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("kill(2) failed");
+ if (kill(id_, force ? SIGKILL : SIGTERM) == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("kill(2) failed");
#elif defined(BOOST_WINDOWS_API)
- HANDLE h = ::OpenProcess(PROCESS_TERMINATE, FALSE, id_);
+ HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, id_);
if (h == NULL)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
- if (!::TerminateProcess(h, EXIT_FAILURE))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
+ if (!TerminateProcess(h, EXIT_FAILURE))
{
- ::CloseHandle(h);
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("TerminateProcess() failed");
+ CloseHandle(h);
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("TerminateProcess() failed");
}
- if (!::CloseHandle(h))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
+ if (!CloseHandle(h))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
#endif
}
@@ -129,41 +110,44 @@
* process has not finalized execution and waits until
* it terminates.
*/
- int wait()
+ int wait() const
{
#if defined(BOOST_POSIX_API)
- int s;
- if (::waitpid(get_id(), &s, 0) == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("waitpid(2) failed");
- return s;
+ pid_t p;
+ int status;
+ do
+ {
+ p = waitpid(id_, &status, 0);
+ } while (p == -1 && errno == EINTR);
+ if (p == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("waitpid(2) failed");
+ return status;
#elif defined(BOOST_WINDOWS_API)
- HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, id_);
+ HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, id_);
if (h == NULL)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
-
- if (::WaitForSingleObject(h, INFINITE) == WAIT_FAILED)
- {
- ::CloseHandle(h);
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("WaitForSingleObject() failed");
- }
-
- DWORD exit_code;
- if (!::GetExitCodeProcess(h, &exit_code))
- {
- ::CloseHandle(h);
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("GetExitCodeProcess() failed");
- }
- if (!::CloseHandle(h))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
- return exit_code;
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
+ if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED)
+ {
+ CloseHandle(h);
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("WaitForSingleObject() failed");
+ }
+ DWORD exit_code;
+ if (!GetExitCodeProcess(h, &exit_code))
+ {
+ CloseHandle(h);
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("GetExitCodeProcess() failed");
+ }
+ if (!CloseHandle(h))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
+ return exit_code;
#endif
}
private:
/**
- * The process' identifier.
+ * The process identifier.
*/
- id_type id_;
+ pid_type id_;
};
}
Modified: sandbox/SOC/2010/process/boost/process/self.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/self.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/self.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -22,9 +23,9 @@
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
-# include <boost/scoped_array.hpp>
-# include <cerrno>
-# include <unistd.h>
+# include <boost/scoped_array.hpp>
+# include <errno.h>
+# include <unistd.h>
# if defined(__APPLE__)
# include <crt_externs.h>
# endif
@@ -36,11 +37,9 @@
#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 <boost/assert.hpp>
#include <string>
-#include <iostream>
#if defined(BOOST_POSIX_API)
extern "C"
@@ -55,7 +54,7 @@
/**
* The self class provides access to the process itself.
*/
-class self : public process, boost::noncopyable
+class self : public process, public boost::noncopyable
{
public:
/**
@@ -72,7 +71,7 @@
/**
* Returns the current environment.
*
- * Returns the current process' environment variables. Modifying the
+ * Returns the current process environment variables. Modifying the
* returned object has no effect on the current environment.
*/
static environment_t get_environment()
@@ -83,14 +82,15 @@
# if defined(__APPLE__)
char **env = *_NSGetEnviron();
# else
- char **env = ::environ;
+ char **env = environ;
# endif
while (*env)
{
std::string s = *env;
std::string::size_type pos = s.find('=');
- e.insert(boost::process::environment_t::value_type(s.substr(0, pos), s.substr(pos + 1)));
+ e.insert(environment_t::value_type(s.substr(0, pos),
+ s.substr(pos + 1)));
++env;
}
#elif defined(BOOST_WINDOWS_API)
@@ -98,7 +98,7 @@
# undef GetEnvironmentStrings
# endif
- char *ms_environ = ::GetEnvironmentStrings();
+ char *ms_environ = GetEnvironmentStrings();
if (!ms_environ)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("GetEnvironmentStrings() failed");
try
@@ -108,16 +108,17 @@
{
std::string s = env;
std::string::size_type pos = s.find('=');
- e.insert(boost::process::environment_t::value_type(s.substr(0, pos), s.substr(pos + 1)));
+ e.insert(environment_t::value_type(s.substr(0, pos),
+ s.substr(pos + 1)));
env += s.size() + 1;
}
}
catch (...)
{
- ::FreeEnvironmentStringsA(ms_environ);
+ FreeEnvironmentStringsA(ms_environ);
throw;
}
- ::FreeEnvironmentStringsA(ms_environ);
+ FreeEnvironmentStringsA(ms_environ);
#endif
return e;
@@ -127,25 +128,25 @@
{
#if defined(BOOST_POSIX_API)
errno = 0;
- long size = ::pathconf(".", _PC_PATH_MAX);
+ long size = pathconf(".", _PC_PATH_MAX);
if (size == -1 && errno)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pathconf(2) failed");
- else if (size == -1)
- size = BOOST_PROCESS_POSIX_PATH_MAX;
- BOOST_ASSERT(size > 0);
- boost::scoped_array<char> cwd(new char[size]);
- if (!::getcwd(cwd.get(), size))
+ else if (size == -1)
+ size = BOOST_PROCESS_POSIX_PATH_MAX;
+ BOOST_ASSERT(size > 0);
+ boost::scoped_array<char> cwd(new char[size]);
+ if (!getcwd(cwd.get(), size))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("getcwd(2) failed");
- BOOST_ASSERT(cwd[0] != '\0');
- return cwd.get();
-#elif defined(BOOST_WINDOWS_API)
- BOOST_ASSERT(MAX_PATH > 0);
- char cwd[MAX_PATH];
- if (!::GetCurrentDirectoryA(sizeof(cwd), cwd))
+ BOOST_ASSERT(cwd[0] != '\0');
+ return cwd.get();
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_ASSERT(MAX_PATH > 0);
+ char cwd[MAX_PATH];
+ if (!GetCurrentDirectoryA(sizeof(cwd), cwd))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("GetCurrentDirectory() failed");
- BOOST_ASSERT(cwd[0] != '\0');
- return cwd;
-#endif
+ BOOST_ASSERT(cwd[0] != '\0');
+ return cwd;
+#endif
}
private:
@@ -156,9 +157,9 @@
*/
self() :
#if defined(BOOST_POSIX_API)
- process(::getpid())
+ process(getpid())
#elif defined(BOOST_WINDOWS_API)
- process(::GetCurrentProcessId())
+ process(GetCurrentProcessId())
#endif
{
}
Modified: sandbox/SOC/2010/process/boost/process/status.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/status.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/status.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -26,6 +27,12 @@
namespace boost {
namespace process {
+/**
+ * The status class to wait for processes to exit.
+ *
+ * The status class is a Boost.Asio I/O object and supports synchronous
+ * and asynchronous wait operations.
+ */
typedef detail::basic_status<detail::basic_status_service<> > status;
}
Modified: sandbox/SOC/2010/process/boost/process/stream_behavior.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/stream_behavior.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/stream_behavior.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -3,7 +3,8 @@
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
-// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -22,324 +23,331 @@
#include <boost/process/config.hpp>
-#if defined(BOOST_POSIX_API)
+#if defined(BOOST_POSIX_API)
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
-#elif defined(BOOST_WINDOWS_API)
-# include <boost/lexical_cast.hpp>
-# include <string>
-# include <windows.h>
-#endif
+#elif defined(BOOST_WINDOWS_API)
+# include <boost/lexical_cast.hpp>
+# include <string>
+# include <windows.h>
+#endif
-#include <boost/shared_ptr.hpp>
-#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
namespace boost {
namespace process {
namespace behavior {
-/*
- * BEHAVIOR | BEFORE fork/CreateProcess | AFTER fork/CreateProcess
- * ---------+----------------------------------+---------------------------------
- * close | | POSIX: close explicitly
- * inherit | Windows: duplicate handle and |
- * | save it in STARTUPINFO |
- * capture | POSIX: create pipe | POSIX: use one end to initialize
- * | Windows: create pipe and save | child process object
- * | one end in STARTUPINFO | Windows: same
- * mute | POSIX: open file |
- * | Windows: open file and save |
- * | handle in STARTUPINFO |
- */
-
/**
- * Stream behaviors are used to configure streams of a child process.
+ * Base class for stream behaviors.
*
- * The class stream is the base class all other stream behavior classes
- * must be derived from.
+ * Stream behavior classes are used to configure streams of a child process.
+ * They must be derived from this class.
*/
-class stream
-{
-public:
-#if defined(BOOST_POSIX_API)
- typedef int native_type;
-#elif defined(BOOST_WINDOWS_API)
- typedef HANDLE native_type;
-#endif
+class stream
+{
+public:
+ /**
+ * Opaque identifier for a stream's end.
+ *
+ * Each operating system identifies streams' ends using a specific type.
+ * The \a stream_end_type type is used to transparently refer to a stream's
+ * end regardless of the operating system in which this class is used.
+ *
+ * On POSIX systems it is defined as int, on Windows systems as HANDLE.
+ */
+#if defined(BOOST_POSIX_API)
+ typedef NativeStreamType stream_end_type;
+#elif defined(BOOST_POSIX_API)
+ typedef int stream_end_type;
+#elif defined(BOOST_WINDOWS_API)
+ typedef HANDLE stream_end_type;
+#endif
- static boost::shared_ptr<stream> def()
- {
- return boost::make_shared<stream>(stream());
- }
+ /**
+ * Factory function to create a stream behavior object.
+ *
+ * Returns a shared pointer to the stream behavior object as this is
+ * what a context object expects. The shared pointer guarantees that
+ * the object is cleaned up.
+ */
+ static boost::shared_ptr<stream> def()
+ {
+ return boost::make_shared<stream>(stream());
+ }
- virtual native_type get_child_end()
- {
-#if defined(BOOST_POSIX_API)
- return -1;
-#elif defined(BOOST_WINDOWS_API)
- return INVALID_HANDLE_VALUE;
-#endif
- }
+ /**
+ * Returns the child's end of the stream.
+ */
+ virtual stream_end_type get_child_end()
+ {
+#if defined(BOOST_POSIX_API)
+ return -1;
+#elif defined(BOOST_WINDOWS_API)
+ return INVALID_HANDLE_VALUE;
+#endif
+ }
- virtual native_type get_parent_end()
- {
-#if defined(BOOST_POSIX_API)
- return -1;
-#elif defined(BOOST_WINDOWS_API)
- return INVALID_HANDLE_VALUE;
-#endif
- }
-};
+ /**
+ * Returns the parent's end of the stream.
+ */
+ virtual stream_end_type get_parent_end()
+ {
+#if defined(BOOST_POSIX_API)
+ return -1;
+#elif defined(BOOST_WINDOWS_API)
+ return INVALID_HANDLE_VALUE;
+#endif
+ }
+};
/**
* Stream behavior to close streams of a child process.
*
- * A child process will not be able to use its streams.
+ * A child process will not be able to use the stream.
*/
-typedef stream close;
+typedef stream close;
/**
* Stream behavior to make a child process inherit streams.
*
- * A child process will use the very same streams the current
- * process uses.
+ * A child process will use the very same stream of its parent process.
*/
-class inherit : public stream
-{
-public:
- inherit(native_type child_end)
+class inherit : public stream
+{
+public:
+ inherit(stream_end_type child_end)
: child_end_(child_end)
{
#if defined(BOOST_WINDOWS_API)
- if (!::DuplicateHandle(::GetCurrentProcess(), child_end_, ::GetCurrentProcess(), &child_end_, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ if (!DuplicateHandle(GetCurrentProcess(), child_end_,
+ GetCurrentProcess(), &child_end_, 0, TRUE, DUPLICATE_SAME_ACCESS))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("DuplicateHandle() failed");
-#endif
+#endif
}
- static boost::shared_ptr<inherit> def(native_type child_end)
+ static boost::shared_ptr<inherit> def(stream_end_type child_end)
{
return boost::make_shared<inherit>(inherit(child_end));
}
- native_type get_child_end()
+ stream_end_type get_child_end()
{
return child_end_;
}
-private:
- native_type child_end_;
-};
+private:
+ stream_end_type child_end_;
+};
/**
* Stream behavior to redirect streams with a pipe.
*
- * A child process will be able to communicate with the current
- * process.
+ * A child process will be able to communicate with its parent process.
*/
-class pipe : public stream
-{
-public:
- enum stream_type { input_stream, output_stream };
+class pipe : public stream
+{
+public:
+ enum stream_type { input_stream, output_stream };
pipe(stream_type stream)
- {
- native_type natives[2];
-#if defined(BOOST_POSIX_API)
- if (::pipe(natives) == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pipe(2) failed");
-#elif defined(BOOST_WINDOWS_API)
+ {
+ stream_end_type ends[2];
+#if defined(BOOST_POSIX_API)
+ if (pipe(ends) == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pipe(2) failed");
+#elif defined(BOOST_WINDOWS_API)
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
- //sa.bInheritHandle = TRUE;
- if (!::CreatePipe(&natives[0], &natives[1], &sa, 0))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreatePipe() failed");
-#endif
- child_end_ = natives[(stream == input_stream) ? 0 : 1];
- parent_end_ = natives[(stream == input_stream) ? 1 : 0];
-#if defined(BOOST_WINDOWS_API)
- if (!::SetHandleInformation(child_end_, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("SetHandleInformation() failed");
+ sa.bInheritHandle = FALSE;
+ if (!CreatePipe(&ends[0], &ends[1], &sa, 0))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreatePipe() failed");
#endif
+ child_end_ = ends[(stream == input_stream) ? 0 : 1];
+ parent_end_ = ends[(stream == input_stream) ? 1 : 0];
+#if defined(BOOST_WINDOWS_API)
+ if (!SetHandleInformation(child_end_, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("SetHandleInformation() failed");
+#endif
+ }
- }
-
- static boost::shared_ptr<pipe> def(stream_type stream)
- {
- return boost::make_shared<pipe>(pipe(stream));
- }
+ static boost::shared_ptr<pipe> def(stream_type stream)
+ {
+ return boost::make_shared<pipe>(pipe(stream));
+ }
- native_type get_child_end()
- {
- return child_end_;
- }
+ stream_end_type get_child_end()
+ {
+ return child_end_;
+ }
- native_type get_parent_end()
- {
- return parent_end_;
- }
+ stream_end_type get_parent_end()
+ {
+ return parent_end_;
+ }
-private:
- native_type child_end_;
- native_type parent_end_;
-};
+private:
+ stream_end_type child_end_;
+ stream_end_type parent_end_;
+};
/**
* Stream behavior to redirect streams with a named pipe.
*
- * A child process will be able to communicate with the current
- * process. On Windows this stream behavior must be used for
- * asynchronous I/O (as only named pipes support asynchronous I/O
- * on Windows).
+ * A child process will be able to communicate with its parent process.
+ * On Windows this stream behavior must be used for asynchronous I/O (as only
+ * named pipes support asynchronous I/O on Windows).
*/
-class named_pipe : public stream
-{
-public:
- enum stream_type { input_stream, output_stream };
+class named_pipe : public stream
+{
+public:
+ enum stream_type { input_stream, output_stream };
- named_pipe(stream_type stream, std::string name = "")
- {
- native_type natives[2];
-#if defined(BOOST_POSIX_API)
- if (name.empty())
+ named_pipe(stream_type stream, std::string name = "")
+ {
+ stream_end_type ends[2];
+#if defined(BOOST_POSIX_API)
+ if (name.empty())
// TODO: Generate unique filename.
- name = "/tmp/fifo.1";
+ name = "/tmp/fifo.1";
- // TODO: Use RAII to close HANDLEs if an exception is thrown.
- if (::mkfifo(name.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("mkfifo(3) failed");
- if (stream == input_stream)
- {
- child_end_ = ::open(name.c_str(), O_RDONLY);
- if (child_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- parent_end_ = ::open(name.c_str(), O_WRONLY);
- if (parent_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- }
- else
- {
- child_end_ = ::open(name.c_str(), O_WRONLY);
- if (child_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- parent_end_ = ::open(name.c_str(), O_RDONLY);
- if (parent_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- }
-#elif defined(BOOST_WINDOWS_API)
- if (name.empty())
- {
- // TODO: Make this thread-safe (create unique filename differently).
- static unsigned int nextid = 0;
+ // TODO: Use RAII to close HANDLEs if an exception is thrown.
+ if (mkfifo(name.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("mkfifo(3) failed");
+ if (stream == input_stream)
+ {
+ child_end_ = open(name.c_str(), O_RDONLY);
+ if (child_end_ == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
+ parent_end_ = open(name.c_str(), O_WRONLY);
+ if (parent_end_ == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
+ }
+ else
+ {
+ child_end_ = open(name.c_str(), O_WRONLY);
+ if (child_end_ == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
+ parent_end_ = open(name.c_str(), O_RDONLY);
+ if (parent_end_ == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
+ }
+#elif defined(BOOST_WINDOWS_API)
+ if (name.empty())
+ {
+ // TODO: Make this thread-safe (create unique filename differently).
+ static unsigned int nextid = 0;
name = "\\\\.\\pipe\\boost_process_" + boost::lexical_cast<std::string>(::GetCurrentProcessId()) + "_" + boost::lexical_cast<std::string>(nextid++);
- }
+ }
- // TODO: Use RAII to close HANDLEs if an exception is thrown.
+ // TODO: Use RAII to close HANDLEs if an exception is thrown.
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
- natives[0] = ::CreateNamedPipeA(name.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa);
- if (natives[0] == INVALID_HANDLE_VALUE)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateNamedPipe() failed");
- natives[1] = ::CreateFileA(name.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (natives[1] == INVALID_HANDLE_VALUE)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
-
- OVERLAPPED overlapped;
- ZeroMemory(&overlapped, sizeof(overlapped));
- overlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!overlapped.hEvent)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateEvent() failed");
- BOOL b = ::ConnectNamedPipe(natives[0], &overlapped);
- if (!b)
- {
- if (::GetLastError() == ERROR_IO_PENDING)
- {
- if (::WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_FAILED)
- {
- ::CloseHandle(overlapped.hEvent);
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("WaitForSingleObject() failed");
- }
- }
- else if (::GetLastError() != ERROR_PIPE_CONNECTED)
- {
- ::CloseHandle(overlapped.hEvent);
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("ConnectNamedPipe() failed");
- }
- }
- ::CloseHandle(overlapped.hEvent);
-#endif
- child_end_ = natives[(stream == input_stream) ? 0 : 1];
- parent_end_ = natives[(stream == input_stream) ? 1 : 0];
-#if defined(BOOST_WINDOWS_API)
- if (!::SetHandleInformation(child_end_, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("SetHandleInformation() failed");
-#endif
- }
+ ends[0] = CreateNamedPipeA(name.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa);
+ if (ends[0] == INVALID_HANDLE_VALUE)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateNamedPipe() failed");
+ ends[1] = ::CreateFileA(name.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ if (ends[1] == INVALID_HANDLE_VALUE)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
+
+ OVERLAPPED overlapped;
+ ZeroMemory(&overlapped, sizeof(overlapped));
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (!overlapped.hEvent)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateEvent() failed");
+ BOOL b = ConnectNamedPipe(ends[0], &overlapped);
+ if (!b)
+ {
+ if (GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_FAILED)
+ {
+ CloseHandle(overlapped.hEvent);
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("WaitForSingleObject() failed");
+ }
+ }
+ else if (GetLastError() != ERROR_PIPE_CONNECTED)
+ {
+ CloseHandle(overlapped.hEvent);
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("ConnectNamedPipe() failed");
+ }
+ }
+ CloseHandle(overlapped.hEvent);
+#endif
+ child_end_ = ends[(stream == input_stream) ? 0 : 1];
+ parent_end_ = ends[(stream == input_stream) ? 1 : 0];
+#if defined(BOOST_WINDOWS_API)
+ if (!SetHandleInformation(child_end_, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("SetHandleInformation() failed");
+#endif
+ }
- static boost::shared_ptr<named_pipe> def(stream_type stream)
- {
- return boost::make_shared<named_pipe>(named_pipe(stream));
- }
+ static boost::shared_ptr<named_pipe> def(stream_type stream)
+ {
+ return boost::make_shared<named_pipe>(named_pipe(stream));
+ }
- native_type get_child_end()
- {
- return child_end_;
- }
+ stream_end_type get_child_end()
+ {
+ return child_end_;
+ }
- native_type get_parent_end()
- {
- return parent_end_;
- }
+ stream_end_type get_parent_end()
+ {
+ return parent_end_;
+ }
-private:
- native_type child_end_;
- native_type parent_end_;
-};
+private:
+ stream_end_type child_end_;
+ stream_end_type parent_end_;
+};
/**
* Stream behavior to mute streams.
*
- * A child process will be able to use streams. But data written to an
+ * A child process will be able to use streams. But data written to an
* output stream is discarded and data read from an input stream is 0.
*/
-class dummy : public stream
-{
-public:
- enum stream_type { input_stream, output_stream };
+class dummy : public stream
+{
+public:
+ enum stream_type { input_stream, output_stream };
- dummy(stream_type stream)
- {
-#if defined(BOOST_POSIX_API)
- std::string filename = (stream == input_stream) ? "/dev/zero" : "/dev/null";
- child_end_ = ::open(filename.c_str(), O_RDONLY);
- if (child_end_ == -1)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
-#elif defined(BOOST_WINDOWS_API)
- DWORD access = (stream == input_stream) ? GENERIC_READ : GENERIC_WRITE;
- child_end_ = ::CreateFileA("NUL", access, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (child_end_ == INVALID_HANDLE_VALUE)
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
-#endif
- }
+ dummy(stream_type stream)
+ {
+#if defined(BOOST_POSIX_API)
+ std::string filename = (stream == input_stream) ? "/dev/zero" : "/dev/null";
+ child_end_ = open(filename.c_str(), O_RDONLY);
+ if (child_end_ == -1)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
+#elif defined(BOOST_WINDOWS_API)
+ DWORD access = (stream == input_stream) ? GENERIC_READ : GENERIC_WRITE;
+ child_end_ = CreateFileA("NUL", access, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (child_end_ == INVALID_HANDLE_VALUE)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
+#endif
+ }
- static boost::shared_ptr<dummy> def(stream_type stream)
- {
- return boost::make_shared<dummy>(dummy(stream));
- }
+ static boost::shared_ptr<dummy> def(stream_type stream)
+ {
+ return boost::make_shared<dummy>(dummy(stream));
+ }
- native_type get_child_end()
- {
- return child_end_;
- }
+ stream_end_type get_child_end()
+ {
+ return child_end_;
+ }
-private:
- native_type child_end_;
-};
+private:
+ stream_end_type child_end_;
+};
}
}
Modified: sandbox/SOC/2010/process/libs/process/test/Jamfile.jam
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/Jamfile.jam (original)
+++ sandbox/SOC/2010/process/libs/process/test/Jamfile.jam 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -23,4 +23,12 @@
explicit helpers ;
using testing ;
+
+run environment.cpp butf bfs ;
+run self.cpp butf bfs ;
+
run arguments.cpp butf bfs : : helpers : <dependency>helpers ;
+run child.cpp butf bfs : : helpers : <dependency>helpers ;
+run executable.cpp butf bfs : : helpers : <dependency>helpers ;
+run process.cpp butf bfs : : helpers : <dependency>helpers ;
+run status.cpp butf bfs : : helpers : <dependency>helpers ;
Modified: sandbox/SOC/2010/process/libs/process/test/arguments.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/arguments.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/arguments.cpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -107,7 +107,7 @@
#endif
#if defined(BOOST_WINDOWS_API)
-BOOST_AUTO_TEST_CASE(test_collection_to_win32_cmdline)
+BOOST_AUTO_TEST_CASE(test_collection_to_windows_cmdline)
{
std::vector<std::string> args;
args.push_back("program");
@@ -115,7 +115,7 @@
args.push_back("arg2");
args.push_back("arg3");
- boost::shared_array<char> cmdline = bpd::collection_to_win32_cmdline(args);
+ boost::shared_array<char> cmdline = bpd::collection_to_windows_cmdline(args);
BOOST_REQUIRE(std::strcmp(cmdline.get(), "program arg1 arg2 arg3") == 0);
}
#endif
Added: sandbox/SOC/2010/process/libs/process/test/child.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/child.cpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,65 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include "child.hpp"
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/back.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/int.hpp>
+#include <vector>
+#include <string>
+
+class launcher
+{
+public:
+ bp::child operator()(const std::vector<std::string> args,
+ bp::context ctx,
+ boost::shared_ptr<bpb::stream> bstdin = bpb::close::def(),
+ boost::shared_ptr<bpb::stream> bstdout = bpb::close::def(),
+ boost::shared_ptr<bpb::stream> bstderr = bpb::close::def())
+ const
+ {
+ ctx.stdin_behavior = bstdin;
+ ctx.stdout_behavior = bstdout;
+ ctx.stderr_behavior = bstderr;
+ return bp::create_child(get_helpers_path(), args, ctx);
+ }
+};
+
+namespace mpl = boost::mpl;
+
+typedef mpl::vector<
+ mpl::vector<launcher, bp::context, bp::child>
+> test_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(child_test_case, T, test_types)
+{
+ check_helpers();
+
+ typedef mpl::front<T>::type Launcher;
+ typedef mpl::at<T, mpl::int_<1> >::type Context;
+ typedef mpl::back<T>::type Child;
+
+ using namespace child_test;
+ test_close_stdin<Launcher, Context, Child>();
+ test_close_stdout<Launcher, Context, Child>();
+ test_close_stderr<Launcher, Context, Child>();
+ test_stdout<Launcher, Context, Child>();
+ test_stderr<Launcher, Context, Child>();
+ // test_redirect_err_to_out<Launcher, Context, Child>();
+ test_input<Launcher, Context, Child>();
+ test_work_directory<Launcher, Context, Child>();
+ test_clear_environment<Launcher, Context, Child>();
+ test_unset_environment<Launcher, Context, Child>();
+ test_set_environment<Launcher, Context, Child>();
+}
Added: sandbox/SOC/2010/process/libs/process/test/child.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/child.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,398 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+# include <stdlib.h>
+# include <sys/wait.h>
+# if defined(__CYGWIN__)
+# undef BOOST_POSIX_API
+# define BOOST_CYGWIN_PATH
+# endif
+#elif defined(BOOST_WINDOWS_API)
+# include <windows.h>
+#else
+# error "Unsupported platform."
+#endif
+
+#define BOOST_TEST_MAIN
+#include "util/boost.hpp"
+#include "util/use_helpers.hpp"
+#include <string>
+#include <vector>
+#include <utility>
+#include <cstdlib>
+
+namespace child_test {
+
+//
+// Overview
+// --------
+//
+// The functions below implement tests for common launcher functionality.
+// These are used to test different implementations without duplicating
+// much code.
+//
+// Launcher concept
+// ----------------
+//
+// The functions in this file all rely on a Launcher concept. This concept
+// provides a class whose () operator starts a new process given an
+// executable, its arguments, an execution context and the redirections for
+// the standard streams, and returns a new Child object. The operator also
+// receives a boolean, defaulting to false, that indicates if the child
+// process focuses on testing stdin input. This is needed when testing
+// pipelines to properly place a dummy process in the flow.
+//
+
+template <class Launcher, class Context, class Child>
+void test_close_stdin()
+{
+ std::vector<std::string> args;
+ args.push_back("is-closed-stdin");
+
+ int s1 = Launcher()(args, Context(), bpb::close::def(),
+ bpb::close::def(), bpb::close::def()).wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s1));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s1), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s1, EXIT_SUCCESS);
+#endif
+
+ int s2 = Launcher()(args, Context(), bpb::pipe::def(bpb::pipe::input_stream)).wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s2));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s2), EXIT_FAILURE);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s2, EXIT_FAILURE);
+#endif
+}
+
+template <class Launcher, class Context, class Child>
+void test_close_stdout()
+{
+ std::vector<std::string> args;
+ args.push_back("is-closed-stdout");
+
+ int s1 = Launcher()(args, Context()).wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s1));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s1), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s1, EXIT_SUCCESS);
+#endif
+
+ int s2 = Launcher()(args, Context(), bpb::close::def(),
+ bpb::pipe::def(bpb::pipe::output_stream)).wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s2));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s2), EXIT_FAILURE);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s2, EXIT_FAILURE);
+#endif
+}
+
+template <class Launcher, class Context, class Child>
+void test_close_stderr()
+{
+ std::vector<std::string> args;
+ args.push_back("is-closed-stderr");
+
+ int s1 = Launcher()(args, Context()).wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s1));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s1), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s1, EXIT_SUCCESS);
+#endif
+
+ int s2 = Launcher()(args, Context(), bpb::close::def(), bpb::close::def(),
+ bpb::pipe::def(bpb::pipe::output_stream)).wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s2));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s2), EXIT_FAILURE);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s2, EXIT_FAILURE);
+#endif
+}
+
+template <class Launcher, class Context, class Child>
+void test_input()
+{
+ std::vector<std::string> args;
+ args.push_back("stdin-to-stdout");
+
+ Child c = Launcher()(args, Context(),
+ bpb::pipe::def(bpb::pipe::input_stream),
+ bpb::pipe::def(bpb::pipe::output_stream));
+
+ bp::postream &os = c.get_stdin();
+ bp::pistream &is = c.get_stdout();
+
+ os << "message-to-process" << std::endl;
+ os.close();
+
+ std::string word;
+ is >> word;
+ BOOST_CHECK_EQUAL(word, "message-to-process");
+
+ int s = c.wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s, EXIT_SUCCESS);
+#endif
+}
+
+template <class Launcher, class Context, class Child>
+void test_output(bool out, const std::string &msg)
+{
+ std::vector<std::string> args;
+ args.push_back(out ? "echo-stdout" : "echo-stderr");
+ args.push_back(msg);
+
+ Child c = Launcher()(args, Context(), bpb::close::def(),
+ out ? bpb::pipe::def(bpb::pipe::output_stream) :
+ bpb::close::def(), out ? bpb::close::def() :
+ bpb::pipe::def(bpb::pipe::output_stream));
+
+ std::string word;
+ if (out)
+ {
+ bp::pistream &is = c.get_stdout();
+ is >> word;
+ }
+ else
+ {
+ bp::pistream &is = c.get_stderr();
+ is >> word;
+ }
+ BOOST_CHECK_EQUAL(word, msg);
+
+ int s = c.wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s, EXIT_SUCCESS);
+#endif
+}
+
+template <class Launcher, class Context, class Child>
+void test_stderr()
+{
+ test_output<Launcher, Context, Child>(false, "message1-stderr");
+ test_output<Launcher, Context, Child>(false, "message2-stderr");
+}
+
+template <class Launcher, class Context, class Child>
+void test_stdout()
+{
+ test_output<Launcher, Context, Child>(true, "message1-stdout");
+ test_output<Launcher, Context, Child>(true, "message2-stdout");
+}
+
+/*
+template <class Launcher, class Context, class Child>
+void test_redirect_err_to_out()
+{
+ std::vector<std::string> args;
+ args.push_back("echo-stdout-stderr");
+ args.push_back("message-to-two-streams");
+
+ Child c = Launcher()(args, Context(), bpb::close::def(),
+ bpb::pipe::def(bpb::pipe::output_stream),
+ bp::redirect_stream_to_stdout());
+
+ bp::pistream &is = c.get_stdout();
+ std::string word;
+ is >> word;
+ BOOST_CHECK_EQUAL(word, "stdout");
+ is >> word;
+ BOOST_CHECK_EQUAL(word, "message-to-two-streams");
+ is >> word;
+ BOOST_CHECK_EQUAL(word, "stderr");
+ is >> word;
+ BOOST_CHECK_EQUAL(word, "message-to-two-streams");
+
+ int s = c.wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s, EXIT_SUCCESS);
+#endif
+}
+*/
+
+template <class Launcher, class Context, class Child>
+void check_work_directory(const std::string &wdir)
+{
+ std::vector<std::string> args;
+ args.push_back("pwd");
+
+ Context ctx;
+ if (wdir.empty())
+ BOOST_CHECK(bfs::equivalent(ctx.work_dir,
+ bfs::current_path().string()));
+ else
+ ctx.work_dir = wdir;
+ Child c = Launcher()(args, ctx, bpb::close::def(),
+ bpb::pipe::def(bpb::pipe::output_stream));
+
+ bp::pistream &is = c.get_stdout();
+ std::string dir;
+ std::getline(is, dir);
+ std::string::size_type pos = dir.rfind('\r');
+ if (pos != std::string::npos)
+ dir.erase(pos);
+
+ int s = c.wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s, EXIT_SUCCESS);
+#endif
+
+ BOOST_CHECK_EQUAL(bfs::path(dir), bfs::path(ctx.work_dir));
+}
+
+template <class Launcher, class Context, class Child>
+void test_work_directory()
+{
+ check_work_directory<Launcher, Context, Child>("");
+
+ bfs::path wdir = bfs::current_path() / "test.dir";
+ BOOST_REQUIRE_NO_THROW(bfs::create_directory(wdir));
+ try
+ {
+ check_work_directory<Launcher, Context, Child>(wdir.string());
+ BOOST_CHECK_NO_THROW(bfs::remove_all(wdir));
+ }
+ catch (...)
+ {
+ BOOST_CHECK_NO_THROW(bfs::remove_all(wdir));
+ throw;
+ }
+}
+
+template <class Launcher, class Context, class Child>
+std::pair<bool, std::string> get_var_value(Context &ctx, const std::string &var)
+{
+ std::vector<std::string> args;
+ args.push_back("query-env");
+ args.push_back(var);
+
+ Child c = Launcher()(args, ctx, bpb::close::def(),
+ bpb::pipe::def(bpb::pipe::output_stream));
+
+ bp::pistream &is = c.get_stdout();
+ std::string status;
+ is >> status;
+ std::string gotval;
+ if (status == "defined")
+ is >> gotval;
+
+ int s = c.wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(s));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(s, EXIT_SUCCESS);
+#endif
+
+ return std::pair<bool, std::string>(status == "defined", gotval);
+}
+
+template <class Launcher, class Context, class Child>
+void test_clear_environment()
+{
+ Context ctx;
+ ctx.environment.erase("TO_BE_QUERIED");
+
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(setenv("TO_BE_QUERIED", "test", 1) != -1);
+ BOOST_REQUIRE(getenv("TO_BE_QUERIED") != 0);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_REQUIRE(SetEnvironmentVariableA("TO_BE_QUERIED", "test") != 0);
+ char buf[5];
+ BOOST_REQUIRE(GetEnvironmentVariableA("TO_BE_QUERIED", buf, 5) == 4);
+#endif
+
+ std::pair<bool, std::string> p =
+ get_var_value<Launcher, Context, Child>(ctx, "TO_BE_QUERIED");
+ BOOST_REQUIRE(!p.first);
+}
+
+template <class Launcher, class Context, class Child>
+void test_unset_environment()
+{
+ std::vector<std::string> args;
+ args.push_back("query-env");
+ args.push_back("TO_BE_UNSET");
+
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(setenv("TO_BE_UNSET", "test", 1) != -1);
+ BOOST_REQUIRE(getenv("TO_BE_UNSET") != 0);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_REQUIRE(SetEnvironmentVariableA("TO_BE_UNSET", "test") != 0);
+ char buf[5];
+ BOOST_REQUIRE(GetEnvironmentVariableA("TO_BE_UNSET", buf, 5) == 4);
+#endif
+
+ Context ctx;
+ ctx.environment.erase("TO_BE_UNSET");
+ std::pair<bool, std::string> p =
+ get_var_value<Launcher, Context, Child>(ctx, "TO_BE_UNSET");
+ BOOST_CHECK(!p.first);
+}
+
+template <class Launcher, class Context, class Child>
+void test_set_environment_var(const std::string &value)
+{
+ std::vector<std::string> args;
+ args.push_back("query-env");
+ args.push_back("TO_BE_SET");
+
+#if defined(BOOST_POSIX_API)
+ unsetenv("TO_BE_SET");
+ BOOST_REQUIRE(getenv("TO_BE_SET") == 0);
+#elif defined(BOOST_WINDOWS_API)
+ char buf[5];
+ BOOST_REQUIRE(GetEnvironmentVariableA("TO_BE_SET", buf, 5) == 0 ||
+ SetEnvironmentVariableA("TO_BE_SET", NULL) != 0);
+ BOOST_REQUIRE(GetEnvironmentVariableA("TO_BE_SET", buf, 5) == 0);
+#endif
+
+ Context ctx;
+ ctx.environment.insert(bp::environment_t::value_type("TO_BE_SET", value));
+ std::pair<bool, std::string> p =
+ get_var_value<Launcher, Context, Child>(ctx, "TO_BE_SET");
+ BOOST_CHECK(p.first);
+ BOOST_CHECK_EQUAL(p.second, "'" + value + "'");
+}
+
+template <class Launcher, class Context, class Child>
+void test_set_environment()
+{
+#if defined(BOOST_POSIX_API)
+ test_set_environment_var<Launcher, Context, Child>("");
+#endif
+ test_set_environment_var<Launcher, Context, Child>("some-value-1");
+ test_set_environment_var<Launcher, Context, Child>("some-value-2");
+}
+
+}
Added: sandbox/SOC/2010/process/libs/process/test/environment.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/environment.cpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,125 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+# include <stdlib.h>
+#elif defined(BOOST_WINDOWS_API)
+# include <boost/shared_array.hpp>
+# include <cstring>
+# include <windows.h>
+#else
+# error "Unsupported platform."
+#endif
+
+#define BOOST_TEST_MAIN
+#include "util/boost.hpp"
+#include "util/use_helpers.hpp"
+#include <string>
+
+BOOST_AUTO_TEST_CASE(test_current)
+{
+ bp::environment_t env1 = bp::self::get_environment();
+ BOOST_CHECK(env1.find("THIS_SHOULD_NOT_BE_DEFINED") == env1.end());
+
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(setenv("THIS_SHOULD_BE_DEFINED", "some-value", 1) == 0);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_REQUIRE(SetEnvironmentVariable("THIS_SHOULD_BE_DEFINED",
+ "some-value") != 0);
+#endif
+
+ bp::environment_t env2 = bp::self::get_environment();
+ bp::environment_t::const_iterator it =
+ env2.find("THIS_SHOULD_BE_DEFINED");
+ BOOST_CHECK(it != env2.end());
+ BOOST_CHECK_EQUAL(it->second, "some-value");
+}
+
+#if defined(BOOST_POSIX_API)
+BOOST_AUTO_TEST_CASE(test_envp)
+{
+ bp::environment_t env;
+ env.insert(bp::environment_t::value_type("VAR1", "value1"));
+ env.insert(bp::environment_t::value_type("VAR2", "value2"));
+ env.insert(bp::environment_t::value_type("VAR3", "value3"));
+
+ char **ep = bpd::environment_to_envp(env);
+
+ BOOST_REQUIRE(ep[0] != NULL);
+ BOOST_REQUIRE_EQUAL(std::string(ep[0]), "VAR1=value1");
+ delete[] ep[0];
+
+ BOOST_REQUIRE(ep[1] != NULL);
+ BOOST_REQUIRE_EQUAL(std::string(ep[1]), "VAR2=value2");
+ delete[] ep[1];
+
+ BOOST_REQUIRE(ep[2] != NULL);
+ BOOST_REQUIRE_EQUAL(std::string(ep[2]), "VAR3=value3");
+ delete[] ep[2];
+
+ BOOST_REQUIRE(ep[3] == NULL);
+ delete[] ep;
+}
+
+BOOST_AUTO_TEST_CASE(test_envp_unsorted)
+{
+ bp::environment_t env;
+ env.insert(bp::environment_t::value_type("VAR2", "value2"));
+ env.insert(bp::environment_t::value_type("VAR1", "value1"));
+
+ char **ep = bpd::environment_to_envp(env);
+
+ BOOST_REQUIRE(ep[0] != NULL);
+ BOOST_REQUIRE_EQUAL(std::string(ep[0]), "VAR1=value1");
+ delete[] ep[0];
+
+ BOOST_REQUIRE(ep[1] != NULL);
+ BOOST_REQUIRE_EQUAL(std::string(ep[1]), "VAR2=value2");
+ delete[] ep[1];
+
+ BOOST_REQUIRE(ep[2] == NULL);
+ delete[] ep;
+}
+#endif
+
+#if defined(BOOST_WINDOWS_API)
+BOOST_AUTO_TEST_CASE(test_strings)
+{
+ bp::environment_t env;
+ env.insert(bp::environment_t::value_type("VAR1", "value1"));
+ env.insert(bp::environment_t::value_type("VAR2", "value2"));
+ env.insert(bp::environment_t::value_type("VAR3", "value3"));
+
+ boost::shared_array<char> strs =
+ bpd::environment_to_windows_strings(env);
+ BOOST_REQUIRE(strs.get() != NULL);
+
+ char *expected = "VAR1=value1\0VAR2=value2\0VAR3=value3\0\0";
+ BOOST_REQUIRE(std::memcmp(strs.get(), expected, 37) == 0);
+}
+
+BOOST_AUTO_TEST_CASE(test_strings_unsorted)
+{
+ bp::environment_t env;
+ env.insert(bp::environment_t::value_type("VAR2", "value2"));
+ env.insert(bp::environment_t::value_type("VAR1", "value1"));
+
+ boost::shared_array<char> strs =
+ bpd::environment_to_windows_strings(env);
+ BOOST_REQUIRE(strs.get() != NULL);
+
+ char *expected = "VAR1=value1\0VAR2=value2\0\0";
+ BOOST_REQUIRE(std::memcmp(strs.get(), expected, 25) == 0);
+}
+#endif
Added: sandbox/SOC/2010/process/libs/process/test/executable.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/executable.cpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,113 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+# include <stdlib.h>
+# if defined(__CYGWIN__)
+# undef BOOST_POSIX_API
+# define BOOST_CYGWIN_PATH
+# endif
+#elif defined(BOOST_WINDOWS_API)
+# include <boost/shared_array.hpp>
+# include <cstring>
+# include <windows.h>
+#else
+# error "Unsupported platform."
+#endif
+
+#define BOOST_TEST_MAIN
+#include "util/boost.hpp"
+#include "util/use_helpers.hpp"
+#include <string>
+#include <stdexcept>
+
+BOOST_AUTO_TEST_CASE(test_find_default)
+{
+ check_helpers();
+
+ std::string helpersname = bfs::path(get_helpers_path()).leaf();
+
+ BOOST_CHECK_THROW(bp::find_executable_in_path(helpersname),
+ boost::filesystem::filesystem_error);
+}
+
+BOOST_AUTO_TEST_CASE(test_find_env)
+{
+ check_helpers();
+
+ bfs::path orig = get_helpers_path();
+ std::string helpersdir = orig.branch_path().string();
+ std::string helpersname = orig.leaf();
+
+#if defined(BOOST_POSIX_API)
+ std::string oldpath = getenv("PATH");
+ try
+ {
+ setenv("PATH", helpersdir.c_str(), 1);
+ bfs::path found = bp::find_executable_in_path(helpersname);
+ BOOST_CHECK(bfs::equivalent(orig, found));
+ setenv("PATH", oldpath.c_str(), 1);
+ }
+ catch (...)
+ {
+ setenv("PATH", oldpath.c_str(), 1);
+ }
+#elif defined(BOOST_WINDOWS_API)
+ char oldpath[MAX_PATH];
+ BOOST_REQUIRE(GetEnvironmentVariableA("PATH", oldpath, MAX_PATH) != 0);
+ try
+ {
+ BOOST_REQUIRE(SetEnvironmentVariableA("PATH",
+ helpersdir.c_str()) != 0);
+ bfs::path found = bp::find_executable_in_path(helpersname);
+ BOOST_CHECK(bfs::equivalent(orig, found));
+ BOOST_REQUIRE(SetEnvironmentVariable("PATH", oldpath) != 0);
+ }
+ catch (...)
+ {
+ BOOST_REQUIRE(SetEnvironmentVariable("PATH", oldpath) != 0);
+ }
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_find_param)
+{
+ check_helpers();
+
+ bfs::path orig = get_helpers_path();
+ std::string helpersdir = orig.branch_path().string();
+ std::string helpersname = orig.leaf();
+
+ bfs::path found = bp::find_executable_in_path(helpersname, helpersdir);
+ BOOST_CHECK(bfs::equivalent(orig, found));
+}
+
+BOOST_AUTO_TEST_CASE(test_progname)
+{
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("foo"), "foo");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("/foo"), "foo");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("/foo/bar"), "bar");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("///foo///bar"), "bar");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("/foo/bar/baz"), "baz");
+
+#if defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("f.exe"), "f");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("f.com"), "f");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("f.bat"), "f");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("f.bar"), "f.bar");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("f.bar.exe"), "f.bar");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("f.bar.com"), "f.bar");
+ BOOST_CHECK_EQUAL(bp::executable_to_progname("f.bar.bat"), "f.bar");
+#endif
+}
Added: sandbox/SOC/2010/process/libs/process/test/process.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/process.cpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,41 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include "process.hpp"
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/pair.hpp>
+
+namespace {
+
+class launcher
+{
+public:
+ bp::process operator()(bp::pid_type id) const
+ {
+ return bp::process(id);
+ }
+};
+
+}
+
+namespace mpl = boost::mpl;
+
+typedef mpl::list<
+ mpl::pair<bp::process, launcher>
+> test_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(process_test_case, T, test_types)
+{
+ using namespace process_test;
+ test_getters<T::first, T::second>();
+ test_terminate<T::first, T::second>();
+}
Added: sandbox/SOC/2010/process/libs/process/test/process.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/process.hpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,81 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+# include <sys/wait.h>
+#elif defined(BOOST_WINDOWS_API)
+# include <cstdlib>
+#else
+# error "Unsupported platform."
+#endif
+
+#define BOOST_TEST_MAIN
+#include "util/boost.hpp"
+#include "util/use_helpers.hpp"
+#include <string>
+#include <vector>
+
+namespace process_test {
+
+//
+// Overview
+// --------
+//
+// The functions below implement tests for the basic Process implementation.
+// In order to ensure appropriate behavior, all implementations must
+// have the same behavior in common public methods; keeping this set of
+// tests generic makes it easy to check this restriction because the tests
+// can easily be applied to any specific Process implementation.
+//
+// Factory concept
+// ---------------
+//
+// The functions in this file all rely on a Factory concept. This concept
+// provides a class whose () operator constructs a new Process instance
+// based on a process's identifier. Note that this is the most possible
+// generic construction, which should be conceptually supported by all
+// implementations.
+//
+
+template <class Process, class Factory>
+void test_getters()
+{
+ bp::pid_type id = static_cast<bp::pid_type>(0);
+ Process c = Factory()(id);
+
+ BOOST_CHECK_EQUAL(c.get_id(), id);
+}
+
+template <class Process, class Factory>
+void test_terminate()
+{
+ std::vector<std::string> args;
+ args.push_back("loop");
+
+ bp::context ctx;
+ bp::child c = bp::create_child(get_helpers_path(), args, ctx);
+
+ Process p = Factory()(c.get_id());
+ p.terminate();
+
+ int status = c.wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(!WIFEXITED(status));
+ BOOST_REQUIRE(WIFSIGNALED(status));
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(status, EXIT_FAILURE);
+#endif
+}
+
+}
Added: sandbox/SOC/2010/process/libs/process/test/self.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/self.cpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,65 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+# include <stdlib.h>
+# include <unistd.h>
+#elif defined(BOOST_WINDOWS_API)
+# include <windows.h>
+#else
+# error "Unsupported platform."
+#endif
+
+#define BOOST_TEST_MAIN
+#include "util/boost.hpp"
+#include "util/use_helpers.hpp"
+
+class launcher
+{
+public:
+ bp::self &operator()(bp::pid_type id)
+ {
+ return bp::self::get_instance();
+ }
+};
+
+BOOST_AUTO_TEST_CASE(test_id)
+{
+ bp::self &p = bp::self::get_instance();
+
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(p.get_id() == getpid());
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_REQUIRE(p.get_id() == GetCurrentProcessId());
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_get_environment)
+{
+ bp::self &p = bp::self::get_instance();
+
+ bp::environment_t env1 = p.get_environment();
+ BOOST_CHECK(env1.find("THIS_SHOULD_NOT_BE_DEFINED") == env1.end());
+
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(setenv("THIS_SHOULD_BE_DEFINED", "some-value", 1) == 0);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_REQUIRE(SetEnvironmentVariableA("THIS_SHOULD_BE_DEFINED", "some-value") != 0);
+#endif
+
+ bp::environment_t env2 = p.get_environment();
+ bp::environment_t::const_iterator it = env2.find("THIS_SHOULD_BE_DEFINED");
+ BOOST_CHECK(it != env2.end());
+ BOOST_CHECK_EQUAL(it->second, "some-value");
+}
Added: sandbox/SOC/2010/process/libs/process/test/status.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/libs/process/test/status.cpp 2010-07-22 20:02:20 EDT (Thu, 22 Jul 2010)
@@ -0,0 +1,55 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+#elif defined(BOOST_WINDOWS_API)
+#else
+# error "Unsupported platform."
+#endif
+
+#define BOOST_TEST_MAIN
+#include "util/boost.hpp"
+#include "util/use_helpers.hpp"
+#include <string>
+#include <vector>
+
+bp::child launch_helper(const std::string &command)
+{
+ std::vector<std::string> args;
+ args.push_back(command);
+ bp::context ctx;
+ return bp::create_child(get_helpers_path(), args, ctx);
+}
+
+BOOST_AUTO_TEST_CASE(test_exit_failure)
+{
+ int status = launch_helper("exit-failure").wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(status));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(status), EXIT_FAILURE);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(status, EXIT_FAILURE);
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_exit_success)
+{
+ int status = launch_helper("exit-success").wait();
+#if defined(BOOST_POSIX_API)
+ BOOST_REQUIRE(WIFEXITED(status));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(status), EXIT_SUCCESS);
+#elif defined(BOOST_WINDOWS_API)
+ BOOST_CHECK_EQUAL(status, EXIT_SUCCESS);
+#endif
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk