|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r65293 - in sandbox/SOC/2010/process: boost/process libs/process/example libs/process/test libs/process/test/util
From: boris_at_[hidden]
Date: 2010-09-05 10:00:29
Author: bschaeling
Date: 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
New Revision: 65293
URL: http://svn.boost.org/trac/boost/changeset/65293
Log:
Updated context class to use delegates based on boost::function (consequently updated all stream behaviors)
Changed named_pipe which requires now a name to be set by a developer
Added new stream behavior async_pipe
Text files modified:
sandbox/SOC/2010/process/boost/process/config.hpp | 6
sandbox/SOC/2010/process/boost/process/context.hpp | 27 +-
sandbox/SOC/2010/process/boost/process/operations.hpp | 55 ++++---
sandbox/SOC/2010/process/boost/process/stream_behavior.hpp | 281 ++++++++++++++-------------------------
sandbox/SOC/2010/process/libs/process/example/async_io.cpp | 5
sandbox/SOC/2010/process/libs/process/example/create_child_context.cpp | 6
sandbox/SOC/2010/process/libs/process/example/file_descriptors_setup.cpp | 21 +-
sandbox/SOC/2010/process/libs/process/example/redirect_to.cpp | 59 +++----
sandbox/SOC/2010/process/libs/process/test/Jamfile.jam | 4
sandbox/SOC/2010/process/libs/process/test/arguments.cpp | 2
sandbox/SOC/2010/process/libs/process/test/child.cpp | 125 ++++++++--------
sandbox/SOC/2010/process/libs/process/test/handle.cpp | 7
sandbox/SOC/2010/process/libs/process/test/util/boost.hpp | 4
13 files changed, 265 insertions(+), 337 deletions(-)
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-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -63,6 +63,12 @@
boost::system::error_code(BOOST_PROCESS_LAST_ERROR, \
boost::system::get_system_category()), \
BOOST_PROCESS_SOURCE_LOCATION what))
+
+#define BOOST_PROCESS_THROW_ERROR(error, what) \
+ boost::throw_exception(boost::system::system_error( \
+ boost::system::error_code(error, \
+ boost::system::get_system_category()), \
+ BOOST_PROCESS_SOURCE_LOCATION what))
/** \endcond */
#endif
Modified: sandbox/SOC/2010/process/boost/process/context.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/context.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/context.hpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -28,11 +28,13 @@
# include <windows.h>
#endif
-#include <boost/process/stream_behavior.hpp>
+#include <boost/process/handle.hpp>
#include <boost/process/environment.hpp>
#include <boost/process/self.hpp>
-#include <boost/shared_ptr.hpp>
+#include <boost/process/stream_behavior.hpp>
+#include <boost/function.hpp>
#include <string>
+#include <utility>
namespace boost {
namespace process {
@@ -49,17 +51,17 @@
/**
* Behavior of the standard input stream.
*/
- boost::shared_ptr<behavior::stream> stdin_behavior;
+ boost::function<std::pair<handle, handle> (bool)> stdin_behavior;
/**
* Behavior of the standard output stream.
*/
- boost::shared_ptr<behavior::stream> stdout_behavior;
+ boost::function<std::pair<handle, handle> (bool)> stdout_behavior;
/**
* Behavior of the standard error stream.
*/
- boost::shared_ptr<behavior::stream> stderr_behavior;
+ boost::function<std::pair<handle, handle> (bool)> stderr_behavior;
/**
* Process name.
@@ -88,16 +90,13 @@
*/
context()
#if defined(BOOST_POSIX_API)
- : stdin_behavior(behavior::inherit::create(STDIN_FILENO)),
- stdout_behavior(behavior::inherit::create(STDOUT_FILENO)),
- stderr_behavior(behavior::inherit::create(STDERR_FILENO)),
+ : stdin_behavior(behavior::inherit(STDIN_FILENO)),
+ stdout_behavior(behavior::inherit(STDOUT_FILENO)),
+ stderr_behavior(behavior::inherit(STDERR_FILENO)),
#elif defined(BOOST_WINDOWS_API)
- : stdin_behavior(behavior::inherit::create(GetStdHandle(
- STD_INPUT_HANDLE))),
- stdout_behavior(behavior::inherit::create(GetStdHandle(
- STD_OUTPUT_HANDLE))),
- stderr_behavior(behavior::inherit::create(GetStdHandle(
- STD_ERROR_HANDLE))),
+ : stdin_behavior(behavior::inherit(GetStdHandle(STD_INPUT_HANDLE))),
+ stdout_behavior(behavior::inherit(GetStdHandle(STD_OUTPUT_HANDLE))),
+ stderr_behavior(behavior::inherit(GetStdHandle(STD_ERROR_HANDLE))),
#endif
work_dir(self::get_work_dir()),
env(self::get_environment())
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-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -52,6 +52,7 @@
#include <boost/assert.hpp>
#include <string>
#include <vector>
+#include <utility>
namespace boost {
namespace process {
@@ -163,7 +164,7 @@
#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")))
+ boost::algorithm::iends_with(exe, ".bat")))
end = exe.size() - 4;
#endif
@@ -186,11 +187,17 @@
inline child create_child(const std::string &executable, Arguments args,
Context ctx)
{
-#if !defined(NDEBUG)
- BOOST_ASSERT(ctx.stdin_behavior.get());
- BOOST_ASSERT(ctx.stdout_behavior.get());
- BOOST_ASSERT(ctx.stderr_behavior.get());
-#endif
+ std::pair<handle, handle> stdin_pair;
+ if (ctx.stdin_behavior)
+ stdin_pair = ctx.stdin_behavior(true);
+
+ std::pair<handle, handle> stdout_pair;
+ if (ctx.stdout_behavior)
+ stdout_pair = ctx.stdout_behavior(false);
+
+ std::pair<handle, handle> stderr_pair;
+ if (ctx.stderr_behavior)
+ stderr_pair = ctx.stderr_behavior(false);
std::string p_name = ctx.process_name.empty() ?
executable_to_progname(executable) : ctx.process_name;
@@ -227,9 +234,9 @@
_exit(127);
}
- handle hstdin = ctx.stdin_behavior->get_child_end();
- handle hstdout = ctx.stdout_behavior->get_child_end();
- handle hstderr = ctx.stderr_behavior->get_child_end();
+ handle hstdin = stdin_pair.first;
+ handle hstdout = stdout_pair.first;
+ handle hstderr = stderr_pair.first;
if (hstdin.valid())
{
@@ -321,23 +328,23 @@
delete[] envp.second[i];
delete[] envp.second;
- ctx.stdin_behavior->get_child_end().close();
- ctx.stdout_behavior->get_child_end().close();
- ctx.stderr_behavior->get_child_end().close();
+ stdin_pair.first.close();
+ stdout_pair.first.close();
+ stderr_pair.first.close();
return child(pid,
- ctx.stdin_behavior->get_parent_end(),
- ctx.stdout_behavior->get_parent_end(),
- ctx.stderr_behavior->get_parent_end());
+ stdin_pair.second,
+ stdout_pair.second,
+ stderr_pair.second);
}
#elif defined(BOOST_WINDOWS_API)
STARTUPINFOA startup_info;
ZeroMemory(&startup_info, sizeof(startup_info));
startup_info.cb = sizeof(startup_info);
startup_info.dwFlags |= STARTF_USESTDHANDLES;
- startup_info.hStdInput = ctx.stdin_behavior->get_child_end().native();
- startup_info.hStdOutput = ctx.stdout_behavior->get_child_end().native();
- startup_info.hStdError = ctx.stderr_behavior->get_child_end().native();
+ startup_info.hStdInput = stdin_pair.first.native();
+ startup_info.hStdOutput = stdout_pair.first.native();
+ startup_info.hStdError = stderr_pair.first.native();
ctx.setup(startup_info);
@@ -360,9 +367,9 @@
envstrs.get(), workdir.get(), &startup_info, &pi) == 0)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed");
- ctx.stdin_behavior->get_child_end().close();
- ctx.stdout_behavior->get_child_end().close();
- ctx.stderr_behavior->get_child_end().close();
+ stdin_pair.first.close();
+ stdout_pair.first.close();
+ stderr_pair.first.close();
handle hprocess(pi.hProcess);
@@ -370,9 +377,9 @@
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
return child(hprocess,
- ctx.stdin_behavior->get_parent_end(),
- ctx.stdout_behavior->get_parent_end(),
- ctx.stderr_behavior->get_parent_end());
+ stdin_pair.second,
+ stdout_pair.second,
+ stderr_pair.second);
#endif
}
Modified: sandbox/SOC/2010/process/boost/process/stream_behavior.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/stream_behavior.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/stream_behavior.hpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -28,109 +28,63 @@
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
+# include <rpc.h>
#endif
#include <boost/process/handle.hpp>
-#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/random_generator.hpp>
-#include <boost/uuid/uuid_io.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/make_shared.hpp>
#include <string>
#include <algorithm>
+#include <utility>
namespace boost {
namespace process {
namespace behavior {
/**
- * Base class for stream behaviors.
+ * Stream behavior to close streams of a child process.
*
- * Stream behavior classes are used to configure streams of a child process.
- * They must be derived from this class.
+ * A child process will not be able to use the stream.
*/
-class stream
+class close
{
public:
- /**
- * Empty virtual destructor.
- */
- virtual ~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> create()
- {
- return boost::make_shared<stream>();
- }
-
- /**
- * Returns the child's end of the stream.
- */
- virtual handle get_child_end()
- {
- return handle();
- }
-
- /**
- * Returns the parent's end of the stream.
- */
- virtual handle get_parent_end()
+ std::pair<handle, handle> operator()(bool) const
{
- return handle();
+ return std::make_pair(handle(), handle());
}
};
/**
- * Stream behavior to close streams of a child process.
- *
- * A child process will not be able to use the stream.
- */
-typedef stream close;
-
-/**
* Stream behavior to make a child process inherit streams.
*
* A child process will use the very same stream of its parent process.
*/
-class inherit : public stream
+class inherit
{
public:
- inherit(handle::native_type child_end)
+ inherit(handle::native_type h)
+ : h_(h)
+ {
+ }
+
+ std::pair<handle, handle> operator()(bool) const
{
#if defined(BOOST_POSIX_API)
- child_end_ = dup(child_end);
- if (!child_end_.valid())
+ int h = dup(h_);
+ if (h == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup(2) failed");
#elif defined(BOOST_WINDOWS_API)
HANDLE h;
- if (!DuplicateHandle(GetCurrentProcess(), child_end,
- GetCurrentProcess(), &h, 0, TRUE, DUPLICATE_SAME_ACCESS))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("DuplicateHandle() failed");
- child_end_ = h;
+ if (!DuplicateHandle(GetCurrentProcess(), h_, GetCurrentProcess(),
+ &h, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
+ "SetHandleInformation() failed");
#endif
- }
-
- static boost::shared_ptr<inherit> create(handle::native_type child_end)
- {
- return boost::make_shared<inherit>(child_end);
- }
-
- handle get_child_end()
- {
- return child_end_;
+ return std::make_pair(h, handle());
}
private:
- handle child_end_;
+ handle::native_type h_;
};
/**
@@ -138,12 +92,10 @@
*
* A child process will be able to communicate with its parent process.
*/
-class pipe : public stream
+class pipe
{
public:
- enum stream_type { input_stream, output_stream };
-
- pipe(stream_type stream)
+ std::pair<handle, handle> operator()(bool in) const
{
handle::native_type ends[2];
#if defined(BOOST_POSIX_API)
@@ -158,34 +110,16 @@
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];
+ handle child_end = ends[in ? 0 : 1];
+ handle parent_end = ends[in ? 1 : 0];
#if defined(BOOST_WINDOWS_API)
- if (!SetHandleInformation(child_end_.native(), HANDLE_FLAG_INHERIT,
+ if (!SetHandleInformation(child_end.native(), HANDLE_FLAG_INHERIT,
HANDLE_FLAG_INHERIT))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
"SetHandleInformation() failed");
#endif
+ return std::make_pair(child_end, parent_end);
}
-
- static boost::shared_ptr<behavior::pipe> create(stream_type stream)
- {
- return boost::make_shared<pipe>(stream);
- }
-
- handle get_child_end()
- {
- return child_end_;
- }
-
- handle get_parent_end()
- {
- return parent_end_;
- }
-
-private:
- handle child_end_;
- handle parent_end_;
};
/**
@@ -195,98 +129,101 @@
* 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
+class named_pipe
{
public:
- enum stream_type { input_stream, output_stream };
+ named_pipe(const std::string &name)
+ : name_(name)
+ {
+ }
- named_pipe(stream_type stream, std::string *name = 0)
+ std::pair<handle, handle> operator()(bool in) const
{
#if defined(BOOST_POSIX_API)
- std::string s;
- if (name && !name->empty())
- s = *name;
- else
- {
- boost::uuids::random_generator gen;
- boost::uuids::uuid u = gen();
- s = "/tmp/boost_process_" + boost::lexical_cast<std::string>(u);
- if (name)
- *name = s;
- }
-
- if (mkfifo(s.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
+ if (mkfifo(name_.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("mkfifo(3) failed");
- child_end_ = open(s.c_str(), O_RDONLY | O_NONBLOCK);
- if (!child_end_.valid())
+ handle child_end = open(name_.c_str(), O_RDONLY | O_NONBLOCK);
+ if (!child_end.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
- int opts = fcntl(child_end_.native(), F_GETFL);
+ int opts = fcntl(child_end.native(), F_GETFL);
if (opts == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("fcntl(2) failed");
opts ^= O_NONBLOCK;
- if (fcntl(child_end_.native(), F_SETFL, opts) == -1)
+ if (fcntl(child_end.native(), F_SETFL, opts) == -1)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("fcntl(2) failed");
- parent_end_ = open(s.c_str(), O_WRONLY);
- if (!parent_end_.valid())
+ handle parent_end = open(name_.c_str(), O_WRONLY);
+ if (!parent_end.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
#elif defined(BOOST_WINDOWS_API)
- std::string s;
- if (name && !name->empty())
- s = *name;
- else
- {
- boost::uuids::random_generator gen;
- boost::uuids::uuid u = gen();
- s = "\\\\.\\pipe\\boost_process_" +
- boost::lexical_cast<std::string>(u);
- if (name)
- *name = s;
- }
-
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
- child_end_ = CreateNamedPipeA(s.c_str(), PIPE_ACCESS_INBOUND |
+ handle child_end = CreateNamedPipeA(name_.c_str(), PIPE_ACCESS_INBOUND |
FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa);
- if (!child_end_.valid())
+ if (!child_end.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateNamedPipe() failed");
- parent_end_ = CreateFileA(s.c_str(), GENERIC_WRITE, 0, NULL,
+ handle parent_end = CreateFileA(name_.c_str(), GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (!parent_end_.valid())
+ if (!parent_end.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
#endif
- if (stream == output_stream)
- std::swap(child_end_, parent_end_);
+ if (!in)
+ std::swap(child_end, parent_end);
#if defined(BOOST_WINDOWS_API)
- if (!SetHandleInformation(child_end_.native(), HANDLE_FLAG_INHERIT,
+ if (!SetHandleInformation(child_end.native(), HANDLE_FLAG_INHERIT,
HANDLE_FLAG_INHERIT))
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
"SetHandleInformation() failed");
#endif
+ return std::make_pair(child_end, parent_end);
}
- static boost::shared_ptr<named_pipe> create(stream_type stream,
- std::string *name = 0)
- {
- return boost::make_shared<named_pipe>(stream, name);
- }
-
- handle get_child_end()
- {
- return child_end_;
- }
+private:
+ std::string name_;
+};
- handle get_parent_end()
+/**
+ * Stream behavior to redirect streams with a pipe which supports asynchronous
+ * I/O.
+ *
+ * As platforms require different types of pipes for asynchronous I/O this
+ * stream behavior is provided for convenience. It uses the minimum required
+ * pipe type on a platform in order to be able to use asynchronous I/O.
+ */
+#if defined(BOOST_POSIX_API)
+typedef pipe async_pipe;
+#elif defined(BOOST_WINDOWS_API)
+class async_pipe
+{
+public:
+ std::pair<handle, handle> operator()(bool in) const
{
- return parent_end_;
+ UUID uuid;
+ RPC_STATUS s = UuidCreateSequential(&uuid);
+ if (s != RPC_S_OK && s != RPC_S_UUID_LOCAL_ONLY)
+ BOOST_PROCESS_THROW_ERROR(s, "UuidCreateSequential() failed");
+ unsigned char *c;
+ s = UuidToStringA(&uuid, &c);
+ if (s != RPC_S_OK)
+ BOOST_PROCESS_THROW_ERROR(s, "UuidToString() failed");
+ std::string name;
+ try
+ {
+ name = reinterpret_cast<char*>(c);
+ }
+ catch (...)
+ {
+ RpcStringFreeA(&c);
+ throw;
+ }
+ RpcStringFreeA(&c);
+ named_pipe p("\\\\.\\pipe\\boost_process_" + name);
+ return p(in);
}
-
-private:
- handle child_end_;
- handle parent_end_;
};
+#endif
/**
* Stream behavior to mute streams.
@@ -294,45 +231,29 @@
* 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 null : public stream
+class null
{
public:
- enum stream_type { input_stream, output_stream };
-
- null(stream_type stream)
+ std::pair<handle, handle> operator()(bool in) const
{
#if defined(BOOST_POSIX_API)
- std::string filename = (stream == input_stream) ? "/dev/zero" :
- "/dev/null";
- int flag = (stream == input_stream) ? O_RDONLY : O_WRONLY;
- child_end_ = open(filename.c_str(), flag);
- if (!child_end_.valid())
+ std::string filename = in ? "/dev/zero" : "/dev/null";
+ int flag = in ? O_RDONLY : O_WRONLY;
+ handle child_end = open(filename.c_str(), flag);
+ if (!child_end.valid())
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,
+ DWORD access = in ? GENERIC_READ : GENERIC_WRITE;
+ handle child_end = CreateFileA("NUL", access, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
- if (!child_end_.valid())
+ if (!child_end.valid())
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
- if (!SetHandleInformation(child_end_.native(), HANDLE_FLAG_INHERIT,
+ if (!SetHandleInformation(child_end.native(), HANDLE_FLAG_INHERIT,
HANDLE_FLAG_INHERIT))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
- "SetHandleInformation() failed");
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("SetHandleInformation() failed");
#endif
+ return std::make_pair(child_end, handle());
}
-
- static boost::shared_ptr<null> create(stream_type stream)
- {
- return boost::make_shared<null>(stream);
- }
-
- handle get_child_end()
- {
- return child_end_;
- }
-
-private:
- handle child_end_;
};
}
Modified: sandbox/SOC/2010/process/libs/process/example/async_io.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/example/async_io.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/example/async_io.cpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -11,8 +11,8 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
-#include <boost/process/all.hpp>
#include <boost/asio.hpp>
+#include <boost/process/all.hpp>
#include <boost/array.hpp>
#include <string>
#include <vector>
@@ -30,8 +30,7 @@
std::string exe = boost::process::find_executable_in_path("hostname");
std::vector<std::string> args;
boost::process::context ctx;
- ctx.stdout_behavior = boost::process::behavior::named_pipe::create(
- boost::process::behavior::named_pipe::output_stream);
+ ctx.stdout_behavior = boost::process::behavior::async_pipe();
boost::process::child c = boost::process::create_child(exe, args, ctx);
boost::process::pistream &is = c.get_stdout();
boost::process::handle h = is.handle();
Modified: sandbox/SOC/2010/process/libs/process/example/create_child_context.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/example/create_child_context.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/example/create_child_context.cpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -36,8 +36,7 @@
std::string exe = boost::process::find_executable_in_path("hostname");
std::vector<std::string> args;
boost::process::context ctx;
- ctx.stdout_behavior = boost::process::behavior::null::create(
- boost::process::behavior::null::output_stream);
+ ctx.stdout_behavior = boost::process::behavior::null();
boost::process::create_child(exe, args, ctx);
//]
}
@@ -48,8 +47,7 @@
std::string exe = boost::process::find_executable_in_path("hostname");
std::vector<std::string> args;
boost::process::context ctx;
- ctx.stdout_behavior = boost::process::behavior::pipe::create(
- boost::process::behavior::pipe::output_stream);
+ ctx.stdout_behavior = boost::process::behavior::pipe();
boost::process::child c = boost::process::create_child(exe, args, ctx);
boost::process::pistream &is = c.get_stdout();
std::cout << is.rdbuf() << std::flush;
Modified: sandbox/SOC/2010/process/libs/process/example/file_descriptors_setup.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/example/file_descriptors_setup.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/example/file_descriptors_setup.cpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -18,28 +18,29 @@
#include <boost/assign/list_of.hpp>
#include <string>
#include <vector>
+#include <utility>
#include <iostream>
#include <unistd.h>
//[file_descriptors_context
-boost::process::behavior::pipe address(
- boost::process::behavior::pipe::output_stream);
-boost::process::behavior::pipe pid(
- boost::process::behavior::pipe::output_stream);
+std::pair<boost::process::handle, boost::process::handle> address =
+ boost::process::behavior::pipe()(false);
+std::pair<boost::process::handle, boost::process::handle> pid =
+ boost::process::behavior::pipe()(false);
class context : public boost::process::context
{
public:
void setup(std::vector<bool> &closeflags)
{
- if (dup2(address.get_child_end().native(), 3) == -1)
+ if (dup2(address.first.native(), 3) == -1)
{
write(STDERR_FILENO, "dup2() failed\n", 14);
_exit(127);
}
closeflags[3] = false;
- if (dup2(pid.get_child_end().native(), 4) == -1)
+ if (dup2(pid.first.native(), 4) == -1)
{
write(STDERR_FILENO, "dup2() failed\n", 14);
_exit(127);
@@ -57,11 +58,11 @@
("--session")("--print-address=3")("--print-pid=4");
context ctx;
boost::process::create_child(exe, args, ctx);
- address.get_child_end().close();
- pid.get_child_end().close();
- boost::process::pistream isaddress(address.get_parent_end());
+ address.first.close();
+ pid.first.close();
+ boost::process::pistream isaddress(address.second);
std::cout << isaddress.rdbuf() << std::endl;
- boost::process::pistream ispid(pid.get_parent_end());
+ boost::process::pistream ispid(pid.second);
std::cout << ispid.rdbuf() << std::endl;
//]
}
Modified: sandbox/SOC/2010/process/libs/process/example/redirect_to.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/example/redirect_to.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/example/redirect_to.cpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -21,47 +21,37 @@
# error "Unsupported platform."
#endif
-#include <boost/shared_ptr.hpp>
-#include <boost/make_shared.hpp>
+#include <boost/bind.hpp>
#include <iostream>
+#include <utility>
#include <stdexcept>
//[redirect_to_stream
-class redirect_to : public boost::process::behavior::stream
+std::pair<boost::process::handle, boost::process::handle> redirect_to(
+ boost::process::handle h)
{
-public:
- redirect_to(boost::process::handle child_end)
- {
#if defined(BOOST_POSIX_API)
- child_end_ = dup(child_end.native());
- if (!child_end_.valid())
- throw std::runtime_error("dup(2) failed");
+ h = dup(h.native());
+ if (!h.valid())
+ throw std::runtime_error("dup(2) failed");
#elif defined(BOOST_WINDOWS_API)
- HANDLE h;
- if (!DuplicateHandle(GetCurrentProcess(), child_end.native(),
- GetCurrentProcess(), &h, 0, TRUE, DUPLICATE_SAME_ACCESS))
- throw std::runtime_error("DuplicateHandle() failed");
- child_end_ = h;
+ HANDLE h2;
+ if (!DuplicateHandle(GetCurrentProcess(), h.native(),
+ GetCurrentProcess(), &h2, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ throw std::runtime_error("DuplicateHandle() failed");
+ h = h2;
#endif
- }
-
- static boost::shared_ptr<redirect_to> create(
- boost::process::handle stream_end)
- {
- return boost::make_shared<redirect_to>(redirect_to(stream_end));
- }
-
- boost::process::handle get_child_end()
- {
- return child_end_;
- }
-
-private:
- boost::process::handle child_end_;
-};
+ return std::make_pair(h, boost::process::handle());
+}
//]
//[redirect_to_main
+std::pair<boost::process::handle, boost::process::handle> forward(
+ std::pair<boost::process::handle, boost::process::handle> p)
+{
+ return p;
+}
+
int main()
{
std::string executable = boost::process::find_executable_in_path(
@@ -69,11 +59,12 @@
std::vector<std::string> args;
+ std::pair<boost::process::handle, boost::process::handle> p =
+ boost::process::behavior::pipe()(false);
+
boost::process::context ctx;
- ctx.stdout_behavior = boost::process::behavior::pipe::create(
- boost::process::behavior::pipe::output_stream);
- ctx.stderr_behavior = redirect_to::create(
- ctx.stdout_behavior->get_child_end());
+ ctx.stdout_behavior = boost::bind(forward, p);
+ ctx.stderr_behavior = boost::bind(redirect_to, p.first);
boost::process::child c = boost::process::create_child(
executable, args, ctx);
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-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -24,6 +24,8 @@
exe helpers : util/helpers.cpp bfs ;
explicit helpers ;
+lib rpcrt4 : : <name>rpcrt4 ;
+
using testing ;
for local i in [ glob inclusion/*.cpp ]
@@ -37,7 +39,7 @@
run systembuf.cpp bfs ;
run arguments.cpp bfs : : helpers : <dependency>helpers ;
-run child.cpp bfs : : helpers : <dependency>helpers ;
+run child.cpp bfs : : helpers : <dependency>helpers <target-os>windows:<library>rpcrt4 ;
run executable.cpp bfs : : helpers : <dependency>helpers ;
run process.cpp bfs : : helpers : <dependency>helpers ;
run status.cpp 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-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -37,7 +37,7 @@
args.push_back(word);
bp::context ctx;
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
bp::pistream &is = c.get_stdout();
Modified: sandbox/SOC/2010/process/libs/process/test/child.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/child.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/child.cpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -40,7 +40,7 @@
args.push_back("is-closed-stdin");
bp::context ctx;
- ctx.stdin_behavior = bpb::close::create();
+ ctx.stdin_behavior = bpb::close();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -61,7 +61,7 @@
args.push_back("is-closed-stdout");
bp::context ctx1;
- ctx1.stdout_behavior = bpb::close::create();
+ ctx1.stdout_behavior = bpb::close();
bp::child c1 = bp::create_child(get_helpers_path(), args, ctx1);
@@ -74,7 +74,7 @@
#endif
bp::context ctx2;
- ctx2.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx2.stdout_behavior = bpb::pipe();
bp::child c2 = bp::create_child(get_helpers_path(), args, ctx2);
@@ -95,7 +95,7 @@
args.push_back("is-closed-stderr");
bp::context ctx1;
- ctx1.stderr_behavior = bpb::close::create();
+ ctx1.stderr_behavior = bpb::close();
bp::child c1 = bp::create_child(get_helpers_path(), args, ctx1);
@@ -108,7 +108,7 @@
#endif
bp::context ctx2;
- ctx2.stderr_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx2.stderr_behavior = bpb::pipe();
bp::child c2 = bp::create_child(get_helpers_path(), args, ctx2);
@@ -129,8 +129,8 @@
args.push_back("stdin-to-stdout");
bp::context ctx;
- ctx.stdin_behavior = bpb::pipe::create(bpb::pipe::input_stream);
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdin_behavior = bpb::pipe();
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -160,7 +160,7 @@
args.push_back("message-stdout");
bp::context ctx;
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -185,7 +185,7 @@
args.push_back("message-stderr");
bp::context ctx;
- ctx.stderr_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stderr_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -210,8 +210,8 @@
args.push_back("message-to-two-streams");
bp::context ctx;
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
- ctx.stderr_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
+ ctx.stderr_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -236,37 +236,26 @@
#endif
}
-class redirect_to : public bpb::stream
+std::pair<bp::handle, bp::handle> redirect_to(bp::handle h)
{
-public:
- redirect_to(bp::handle child_end)
- {
#if defined(BOOST_POSIX_API)
- child_end_ = dup(child_end.native());
- if (!child_end_.valid())
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup(2) failed");
-#elif defined(BOOST_WINDOWS_API)
- HANDLE h;
- if (!DuplicateHandle(GetCurrentProcess(), child_end.native(),
- GetCurrentProcess(), &h, 0, TRUE, DUPLICATE_SAME_ACCESS))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("DuplicateHandle() failed");
- child_end_ = h;
+ h = dup(h.native());
+ if (!h.valid())
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("dup(2) failed");
+#elif defined(BOOST_WINDOWS_API)
+ HANDLE h2;
+ if (!DuplicateHandle(GetCurrentProcess(), h.native(),
+ GetCurrentProcess(), &h2, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("DuplicateHandle() failed");
+ h = h2;
#endif
- }
-
- static boost::shared_ptr<redirect_to> create(bp::handle stream_end)
- {
- return boost::make_shared<redirect_to>(redirect_to(stream_end));
- }
-
- bp::handle get_child_end()
- {
- return child_end_;
- }
+ return std::make_pair(h, bp::handle());
+}
-private:
- bp::handle child_end_;
-};
+std::pair<bp::handle, bp::handle> forward(std::pair<bp::handle, bp::handle> p)
+{
+ return p;
+}
BOOST_AUTO_TEST_CASE(test_redirect_err_to_out)
{
@@ -274,10 +263,11 @@
args.push_back("echo-stdout-stderr");
args.push_back("message-to-two-streams");
+ std::pair<bp::handle, bp::handle> p = bpb::pipe()(false);
+
bp::context ctx;
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
- ctx.stderr_behavior = redirect_to::create(
- ctx.stdout_behavior->get_child_end());
+ ctx.stdout_behavior = boost::bind(forward, p);
+ ctx.stderr_behavior = boost::bind(redirect_to, p.first);
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -309,7 +299,7 @@
bp::context ctx;
BOOST_CHECK(bfs::equivalent(ctx.work_dir, bfs::current_path().string()));
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -343,7 +333,7 @@
{
bp::context ctx;
ctx.work_dir = wdir.string();
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -378,7 +368,7 @@
args.push_back("query-env");
args.push_back(var);
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -498,10 +488,8 @@
args.push_back("async-");
bp::context ctx;
- ctx.stdin_behavior = bp::behavior::named_pipe::create(
- bp::behavior::named_pipe::input_stream);
- ctx.stdout_behavior = bp::behavior::named_pipe::create(
- bp::behavior::named_pipe::output_stream);
+ ctx.stdin_behavior = bpb::async_pipe();
+ ctx.stdout_behavior = bpb::async_pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
bp::postream &os = c.get_stdin();
@@ -536,7 +524,7 @@
#endif
bp::context ctx;
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::shell(cmd, ctx);
@@ -562,7 +550,7 @@
args.push_back("is-nul-stdin");
bp::context ctx;
- ctx.stdin_behavior = bpb::null::create(bpb::null::input_stream);
+ ctx.stdin_behavior = bpb::null();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -583,7 +571,7 @@
args.push_back("is-nul-stdout");
bp::context ctx;
- ctx.stdout_behavior = bpb::null::create(bpb::null::output_stream);
+ ctx.stdout_behavior = bpb::null();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -604,7 +592,7 @@
args.push_back("is-nul-stderr");
bp::context ctx;
- ctx.stderr_behavior = bpb::null::create(bpb::null::output_stream);
+ ctx.stderr_behavior = bpb::null();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -622,13 +610,13 @@
{
public:
context()
- : p(bpb::pipe::output_stream)
+ : p(bpb::pipe()(false))
{
}
void setup(std::vector<bool> &closeflags)
{
- if (dup2(p.get_child_end().native(), 10) == -1)
+ if (dup2(p.first.native(), 10) == -1)
{
write(STDERR_FILENO, "dup2() failed\n", 14);
_exit(127);
@@ -636,7 +624,7 @@
closeflags[10] = false;
}
- bpb::pipe p;
+ std::pair<bp::handle, bp::handle> p;
};
BOOST_AUTO_TEST_CASE(test_posix)
@@ -652,7 +640,7 @@
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
std::string word;
- bp::pistream is(ctx.p.get_parent_end());
+ bp::pistream is(ctx.p.second);
is >> word;
BOOST_CHECK_EQUAL(word, "test");
@@ -710,8 +698,9 @@
raii_dup2 raii_stderr(STDERR_FILENO, 102);
close(STDERR_FILENO);
- ctx.stderr_behavior = bpb::pipe::create(bpb::pipe::output_stream);
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdin_behavior = bpb::null();
+ ctx.stderr_behavior = bpb::pipe();
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -760,7 +749,7 @@
args.push_back("windows-print-startupinfo");
context ctx;
- ctx.stdout_behavior = bpb::pipe::create(bpb::pipe::output_stream);
+ ctx.stdout_behavior = bpb::pipe();
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
@@ -786,6 +775,18 @@
BOOST_CHECK_EQUAL(s, EXIT_SUCCESS);
}
+std::string create_unique_pipe_name()
+{
+ bu::random_generator gen;
+ bu::uuid u = gen();
+#if defined(BOOST_POSIX_API)
+ std::string name = "/tmp/boost_process_test_";
+#elif defined(BOOST_WINDOWS_API)
+ std::string name = "\\\\.\\pipe\\boost_process_test_";
+#endif
+ return name + boost::lexical_cast<std::string>(u);
+}
+
BOOST_AUTO_TEST_CASE(test_sync_io_with_named_pipe)
{
check_helpers();
@@ -794,10 +795,8 @@
args.push_back("stdin-to-stdout");
bp::context ctx;
- ctx.stdin_behavior = bpb::named_pipe::create(
- bpb::named_pipe::input_stream);
- ctx.stdout_behavior = bpb::named_pipe::create(
- bpb::named_pipe::output_stream);
+ ctx.stdin_behavior = bpb::named_pipe(create_unique_pipe_name());
+ ctx.stdout_behavior = bpb::named_pipe(create_unique_pipe_name());
bp::child c = bp::create_child(get_helpers_path(), args, ctx);
Modified: sandbox/SOC/2010/process/libs/process/test/handle.cpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/handle.cpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/handle.cpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -24,13 +24,14 @@
#define BOOST_TEST_MAIN
#include "util/boost.hpp"
+#include <utility>
BOOST_AUTO_TEST_CASE(test_handle_readwrite)
{
- bpb::pipe p(bpb::pipe::input_stream);
+ std::pair<bp::handle, bp::handle> p = bpb::pipe()(true);
- bp::handle read_end = p.get_child_end();
- bp::handle write_end = p.get_parent_end();
+ bp::handle read_end = p.first;
+ bp::handle write_end = p.second;
bp::handle read_end2 = read_end;
bp::handle write_end2 = write_end;
Modified: sandbox/SOC/2010/process/libs/process/test/util/boost.hpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/util/boost.hpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/util/boost.hpp 2010-09-05 10:00:27 EDT (Sun, 05 Sep 2010)
@@ -22,6 +22,9 @@
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/random_generator.hpp>
+#include <boost/uuid/uuid_io.hpp>
namespace bp = boost::process;
namespace bpb = boost::process::behavior;
@@ -30,5 +33,6 @@
namespace butf = boost::unit_test::framework;
namespace bfs = boost::filesystem;
namespace ba = boost::asio;
+namespace bu = boost::uuids;
#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