Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62024 - in sandbox/SOC/2010/process/boost/process: . detail
From: fotanus_at_[hidden]
Date: 2010-05-16 02:46:33


Author: fotanus
Date: 2010-05-16 02:46:31 EDT (Sun, 16 May 2010)
New Revision: 62024
URL: http://svn.boost.org/trac/boost/changeset/62024

Log:
Started to refactor the win32 version of create_child function. Some small changes in the structure.
Added:
   sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp (contents, props changed)
   sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp (contents, props changed)
Text files modified:
   sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp | 2
   sandbox/SOC/2010/process/boost/process/detail/helper_functions.hpp | 123 --------------------------------------
   sandbox/SOC/2010/process/boost/process/detail/stream_detail.hpp | 35 +++++++++++
   sandbox/SOC/2010/process/boost/process/operations.hpp | 127 +++++++++++++++++++++------------------
   4 files changed, 104 insertions(+), 183 deletions(-)

Modified: sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/file_handle.hpp 2010-05-16 02:46:31 EDT (Sun, 16 May 2010)
@@ -345,7 +345,7 @@
          * DuplicateHandle() fails.
          */
 
- static file_handle win32_std(DWORD d, bool inheritable){
+ static file_handle win32_dup_std(DWORD d, bool inheritable){
                 BOOST_ASSERT(d == STD_INPUT_HANDLE || d == STD_OUTPUT_HANDLE || d == STD_ERROR_HANDLE);
 
                 HANDLE h = ::GetStdHandle(d);

Modified: sandbox/SOC/2010/process/boost/process/detail/helper_functions.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/helper_functions.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/helper_functions.hpp 2010-05-16 02:46:31 EDT (Sun, 16 May 2010)
@@ -37,129 +37,6 @@
 namespace detail{
 
 
-
-/*
- * This is the declaration of configure_stream function.
- * This function, given an stream_detail inherit from the current process
- * father, configure the stream.
- *
- * Note that this function is meant to be called on a brand-new child.
- *
- */
-inline configure_stream(stream_detail &s){
-
- switch(s.behavior){
- case dummy:{
-
- #if defined(BOOST_POSIX_API)
- char * null_file = "/dev/zero";
- #elif defined(BOOST_WINDOWS_API)
- char * null_file = "NUL";
- #endif
-
- int fd;
- if(s.stream_type == stdin_type)
- fd = ::open(null_file, O_RDONLY);
- else
- fd = ::open(null_file, O_WRONLY);
-
- if (fd == -1)
- boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_input: open(2) of " + s.object.file_ + " failed"));
-
- s.object.handle_ = file_handle(fd);
- s.object.handle_.posix_remap(s.stream_handler);
- s.object.handle_.release();
-
- break;
- }
-
- case closed:
- //?
- break;
-
- case inherit:
- //do nothing since is default?
- break;
-
- case capture:
- s.object.pipe_ = pipe();
- if(s.stream_type == stdin_type){
- s.object.pipe_->wend().close();
- s.object.pipe_->rend().posix_remap(s.stream_handler);
- }
- else{
- s.object.pipe_->rend().close();
- s.object.pipe_->wend().posix_remap(s.stream_handler);
- }
- break;
-
- default:
- BOOST_ASSERT(false);
- }
-
-}
-
-
-/**
- * Converts an environment to a char** table as used by execve().
- *
- * Converts the environment's contents to the format used by the
- * execve() system call. The returned char** array is allocated
- * in dynamic memory; the caller must free it when not used any
- * more. Each entry is also allocated in dynamic memory and is a
- * NULL-terminated string of the form var=value; these must also be
- * released by the caller.
- *
- * \return A dynamically allocated char** array that represents
- * the environment's content. Each array entry is a
- * NULL-terminated string of the form var=value.
- */
-inline char ** environment_to_envp( std::map<std::string,std::string> env){
- char **envp = new char*[env.size() + 1];
-
- unsigned int i = 0;
- for (std::map<std::string,std::string>::const_iterator it = env.begin(); it != env.end(); ++it){
- std::string s = (*it).first + "=" + (*it).second;
- envp[i] = new char[s.size() + 1];
- ::strncpy(envp[i], s.c_str(), s.size() + 1);
- ++i;
- }
- envp[i] = 0;
- return envp;
-}
-
-/**
- * Converts the command line to an array of C strings.
- *
- * Converts the command line's list of arguments to the format expected
- * by the \a argv parameter in the POSIX execve() system call.
- *
- * This operation is only available on POSIX systems.
- *
- * \return The first argument of the pair is an integer that indicates
- * how many strings are stored in the second argument. The
- * second argument is a NULL-terminated, dynamically allocated
- * array of dynamically allocated strings holding the arguments
- * to the executable. The caller is responsible of freeing them.
- */
-template <class Arguments>
-inline std::pair<std::size_t, char**> collection_to_posix_argv(const Arguments &args)
-{
- std::size_t nargs = args.size();
- BOOST_ASSERT(nargs >= 0);
-
- char **argv = new char*[nargs + 1];
- typename Arguments::size_type i = 0;
- for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it)
- {
- argv[i] = new char[it->size() + 1];
- ::strncpy(argv[i], it->c_str(), it->size() + 1);
- ++i;
- }
- argv[nargs] = 0;
-
- return std::pair<std::size_t, char**>(nargs, argv);
-}
 }
 }
 }

Added: sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp 2010-05-16 02:46:31 EDT (Sun, 16 May 2010)
@@ -0,0 +1,172 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Boris Schaeling, Felipe Tanus
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * \file boost/process/detail/helper_functions.hpp
+ *
+ * Includes the declaration of helper functions for the operations in a win32 system.
+ * It's for internal purposes.
+ *
+ */
+
+#include <boost/process/detail/file_handle.hpp>
+#include <boost/process/detail/pipe.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/assert.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/throw_exception.hpp>
+#include <vector>
+#include <string>
+#include <cstddef>
+#include <string.h>
+#include <windows.h>
+
+
+
+#ifndef BOOST_PROCESS_WIN32_HELPERS_HPP
+#define BOOST_PROCESS_WIN32_HELPERS_HPP
+namespace boost{
+namespace process{
+namespace detail{
+
+
+/*
+ * This is the declaration of configure_stream function.
+ * This function, given an stream_detail inherit from the current process
+ * father, configure the stream.
+ *
+ * Note that this function is meant to be called on a brand-new child.
+ *
+ */
+inline void configure_stream(stream_detail &s){
+
+ switch(s.behavior){
+ case dummy:{
+
+ char null_file[10];
+ if(s.stream_type == stdin_type)
+ null_file = "/dev/null";
+ else
+ null_file = "/dev/zero";
+
+ int fd;
+ if(s.stream_type == stdin_type)
+ fd = ::open(null_file, O_RDONLY);
+ else
+ fd = ::open(null_file, O_WRONLY);
+
+ if (fd == -1)
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_input: open(2) of " + s.object.file_ + " failed"));
+
+ s.object.handle_ = file_handle(fd);
+ s.object.handle_.posix_remap(s.stream_handler);
+ s.object.handle_.release();
+
+ break;
+ }
+
+ case closed:
+ //?
+ break;
+
+ case inherit:
+ //do nothing since is default?
+ break;
+
+ case capture:
+ s.object.pipe_ = pipe();
+ if(s.stream_type == stdin_type){
+ s.object.pipe_->wend().close();
+ s.object.pipe_->rend().posix_remap(s.stream_handler);
+ }
+ else{
+ s.object.pipe_->rend().close();
+ s.object.pipe_->wend().posix_remap(s.stream_handler);
+ }
+ break;
+
+ default:
+ BOOST_ASSERT(false);
+ }
+
+}
+
+
+/**
+ * Converts an environment to a char** table as used by execve().
+ *
+ * Converts the environment's contents to the format used by the
+ * execve() system call. The returned char** array is allocated
+ * in dynamic memory; the caller must free it when not used any
+ * more. Each entry is also allocated in dynamic memory and is a
+ * NULL-terminated string of the form var=value; these must also be
+ * released by the caller.
+ *
+ * \return A dynamically allocated char** array that represents
+ * the environment's content. Each array entry is a
+ * NULL-terminated string of the form var=value.
+ */
+inline char ** environment_to_envp( std::map<std::string,std::string> env){
+ char **envp = new char*[env.size() + 1];
+
+ unsigned int i = 0;
+ for (std::map<std::string,std::string>::const_iterator it = env.begin(); it != env.end(); ++it){
+ std::string s = (*it).first + "=" + (*it).second;
+ envp[i] = new char[s.size() + 1];
+ ::strncpy(envp[i], s.c_str(), s.size() + 1);
+ ++i;
+ }
+ envp[i] = 0;
+ return envp;
+}
+
+/**
+ * Converts the command line to an array of C strings.
+ *
+ * Converts the command line's list of arguments to the format expected
+ * by the \a argv parameter in the POSIX execve() system call.
+ *
+ * This operation is only available on POSIX systems.
+ *
+ * \return The first argument of the pair is an integer that indicates
+ * how many strings are stored in the second argument. The
+ * second argument is a NULL-terminated, dynamically allocated
+ * array of dynamically allocated strings holding the arguments
+ * to the executable. The caller is responsible of freeing them.
+ */
+template <class Arguments>
+inline std::pair<std::size_t, char**> collection_to_posix_argv(const Arguments &args)
+{
+ std::size_t nargs = args.size();
+ BOOST_ASSERT(nargs >= 0);
+
+ char **argv = new char*[nargs + 1];
+ typename Arguments::size_type i = 0;
+ for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it)
+ {
+ argv[i] = new char[it->size() + 1];
+ ::strncpy(argv[i], it->c_str(), it->size() + 1);
+ ++i;
+ }
+ argv[nargs] = 0;
+
+ return std::pair<std::size_t, char**>(nargs, argv);
+}
+
+}
+}
+}
+
+
+#endif

Modified: sandbox/SOC/2010/process/boost/process/detail/stream_detail.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/stream_detail.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/stream_detail.hpp 2010-05-16 02:46:31 EDT (Sun, 16 May 2010)
@@ -73,8 +73,43 @@
         struct stream_object object;
         std_stream_type stream_type;
         stream_behavior behavior;
+
+ stream_detail(std_stream_type st){
+ switch(st){
+ case stdin_type:{
+ stream_type = st;
+
+ #if defined(BOOST_POSIX_API)
+ stream_handler = STDIN_FILENO;
+ #elif defined(BOOST_WINDOWS_API)
+ stream_handler = STD_INPUT_HANDLE;
+ #endif
+ }
+ case stdout_type:{
+ stream_type = st;
+
+ #if defined(BOOST_POSIX_API)
+ stream_handler = STDOUT_FILENO;
+ #elif defined(BOOST_WINDOWS_API)
+ stream_handler = STD_OUTPUT_HANDLE;
+ #endif
+ }
+ case stderr_type:{
+ stream_type = st;
+
+ #if defined(BOOST_POSIX_API)
+ stream_handler = STDERR_FILENO;
+ #elif defined(BOOST_WINDOWS_API)
+ stream_handler = STD_ERROR_HANDLE;
+ #endif
+ }
+
+ }
+ }
 };
 
+
+
 }
 }
 }

Added: sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2010/process/boost/process/detail/win32_helpers.hpp 2010-05-16 02:46:31 EDT (Sun, 16 May 2010)
@@ -0,0 +1,232 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008, 2009 Boris Schaeling
+// Copyright (c) 2010 Boris Schaeling, Felipe Tanus
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * \file boost/process/detail/helper_functions.hpp
+ *
+ * Includes the declaration of helper functions for the operations in a win32 system.
+ * It's for internal purposes.
+ *
+ */
+
+#include <boost/process/detail/file_handle.hpp>
+#include <boost/process/detail/stream_detail.hpp>
+#include <boost/process/detail/pipe.hpp>
+#include <boost/process/child.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/assert.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/throw_exception.hpp>
+#include <vector>
+#include <map>
+#include <string>
+#include <cstddef>
+#include <string.h>
+#include <windows.h>
+
+
+
+#ifndef BOOST_PROCESS_WIN32_HELPERS_HPP
+#define BOOST_PROCESS_WIN32_HELPERS_HPP
+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(std::map<std::string,std::string> &env){
+ boost::shared_array<char> envp;
+
+ if (env.empty())
+ {
+ envp.reset(new char[2]);
+ ::ZeroMemory(envp.get(), 2);
+ }
+ else
+ {
+ std::string s;
+ for (std::map<std::string,std::string>::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;
+}
+
+
+
+void configure_win32_stream(stream_detail &sd, STARTUPINFOA &si){
+
+ file_handle return_handle;
+
+ switch (sd.behavior){
+ case closed:{
+
+ break;
+ }
+ case inherit:{
+ return_handle = file_handle::win32_dup_std(sd.stream_handler, true);
+ break;
+ }
+
+ case dummy:{
+ HANDLE h;
+ if(sd.stream_type == stdin_type){
+ h = ::CreateFileA("NUL",
+ GENERIC_READ, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+
+ }
+ else{
+ h = ::CreateFileA("NUL",
+ GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ }
+
+ if (h == INVALID_HANDLE_VALUE)
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed"));
+
+ return_handle = file_handle(h);
+
+ break;
+ }
+
+ case capture:{
+ if(sd.stream_type == stdin_type){
+ sd.object.pipe_->rend().win32_set_inheritable(true);
+ return_handle = sd.object.pipe_->rend();
+ }
+ else{
+ sd.object.pipe_->wend().win32_set_inheritable(true);
+ return_handle = sd.object.pipe_->wend();
+ }
+
+ break;
+ }
+
+ default:{
+ BOOST_ASSERT(false);
+ break;
+ }
+ }
+
+
+ file_handle h;
+
+
+ switch(sd.stream_type){
+ case stdin_type:{
+ if(return_handle.valid())
+ si.hStdInput = return_handle.get();
+ else
+ si.hStdInput = INVALID_HANDLE_VALUE;
+ break;
+ }
+ case stdout_type:{
+ if(return_handle.valid())
+ si.hStdOutput = return_handle.get();
+ else
+ si.hStdOutput = INVALID_HANDLE_VALUE;
+ break;
+ }
+ case stderr_type:{
+ if(return_handle.valid())
+ si.hStdError = return_handle.get();
+ else
+ si.hStdError = INVALID_HANDLE_VALUE;
+ break;
+ }
+
+ }
+
+}
+
+
+}
+}
+}
+
+
+#endif

Modified: sandbox/SOC/2010/process/boost/process/operations.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/operations.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/operations.hpp 2010-05-16 02:46:31 EDT (Sun, 16 May 2010)
@@ -21,17 +21,17 @@
 #include <boost/process/config.hpp>
 
 #if defined(BOOST_POSIX_API)
-//# include <boost/process/detail/posix_ops.hpp>
-# include <stdlib.h>
-# include <unistd.h>
-# if defined(__CYGWIN__)
-# include <boost/scoped_array.hpp>
-# include <sys/cygwin.h>
-# endif
+ #include <boost/process/detail/posix_helpers.hpp>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #if defined(__CYGWIN__)
+ #include <boost/scoped_array.hpp>
+ #include <sys/cygwin.h>
+ #endif
 #elif defined(BOOST_WINDOWS_API)
-# include <boost/process/detail/win32_ops.hpp>
-# include <boost/algorithm/string/predicate.hpp>
-# include <windows.h>
+ #include <boost/process/detail/win32_helpers.hpp>
+ #include <boost/algorithm/string/predicate.hpp>
+ #include <windows.h>
 #else
 # error "Unsupported platform."
 #endif
@@ -50,7 +50,7 @@
 #include <boost/process/status.hpp>
 #include <boost/process/detail/file_handle.hpp>
 #include <boost/process/detail/stream_detail.hpp>
-#include <boost/process/detail/helper_functions.hpp>
+
 
 #include <boost/filesystem/path.hpp>
 #include <boost/algorithm/string/predicate.hpp>
@@ -204,40 +204,22 @@
 
 template<class Arguments>
 inline child create_child(const std::string &executable, Arguments args, context &ctx = DEFAULT_CONTEXT){
- detail::file_handle fhstdin, fhstdout, fhstderr;
- detail::stream_detail stdin_stream, stdout_stream, stderr_stream;
 
- stdin_stream.behavior = ctx.stdin_behavior;
- stdin_stream.stream_handler = STDIN_FILENO;
+ detail::file_handle fhstdin, fhstdout, fhstderr;
 
- stdout_stream.behavior = ctx.stdout_behavior;
- stdout_stream.stream_handler = STDOUT_FILENO;
+ detail::stream_detail stdin_stream(detail::stdin_type),
+ stdout_stream(detail::stdout_type),
+ stderr_stream(detail::stderr_type);
 
+ stdin_stream.behavior = ctx.stdin_behavior;
+ stdout_stream.behavior = ctx.stdout_behavior;
         stderr_stream.behavior = ctx.stderr_behavior;
- stderr_stream.stream_handler = STDERR_FILENO;
-
-
-#if defined(BOOST_POSIX_API)
 
- //adjust_output_behavior(ctx); //adjusts the std streams after child lanched
-
- std::string p_name = ctx.process_name.empty() ? executable : ctx.process_name;
+ std::string p_name = ctx.process_name.empty() ? executable : ctx.process_name;
         args.insert(args.begin(),p_name);
 
- std::pair<std::size_t, char**> argcv = detail::collection_to_posix_argv(args);
- char **envp = detail::environment_to_envp(ctx.environment);
-
 
- /*
- detail::posix_setup s;
- s();
- s.work_directory = ctx.work_directory;
- s.uid = ctx.uid;
- s.euid = ctx.euid;
- s.gid = ctx.gid;
- s.egid = ctx.egid;
- s.chroot = ctx.chroot;
- */
+#if defined(BOOST_POSIX_API)
 
         child::id_type pid = ::fork();
         if (pid == -1)
@@ -245,9 +227,12 @@
 
         else if (pid == 0){
 
- detail::configure_stream(stdin_stream);
- detail::configure_stream(stdout_stream);
- detail::configure_stream(stderr_stream);
+ detail::configure_posix_stream(stdin_stream);
+ detail::configure_posix_stream(stdout_stream);
+ detail::configure_posix_stream(stderr_stream);
+
+ std::pair<std::size_t, char**> argcv = detail::collection_to_posix_argv(args);
+ char **envp = detail::environment_to_envp(ctx.environment);
 
                 ::execve(executable.c_str(), argcv.second, envp);
 
@@ -257,6 +242,8 @@
 
         BOOST_ASSERT(pid > 0);
 
+
+ //TODO: turn this in a helper
         if(ctx.stdin_behavior == capture){
                 stdin_stream.object.pipe_->rend().close();
                 fhstdin = stdin_stream.object.pipe_->rend().release();
@@ -280,30 +267,52 @@
 
 
 #elif defined(BOOST_WINDOWS_API)
- detail::stream_info behin = detail::stream_info(ctx.stdin_behavior, false);
- if (behin.type_ == detail::stream_info::use_pipe)
- fhstdin = behin.pipe_->wend();
- detail::stream_info behout = detail::stream_info(ctx.stdout_behavior, true);
- if (behout.type_ == detail::stream_info::use_pipe)
- fhstdout = behout.pipe_->rend();
- detail::stream_info beherr = detail::stream_info(ctx.stderr_behavior, true);
- if (beherr.type_ == detail::stream_info::use_pipe)
- fhstderr = beherr.pipe_->rend();
-
- STARTUPINFOA si;
- ::ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
-
- detail::win32_setup s;
- s.work_directory = ctx.work_directory;
- s.startupinfo = &si;
 
- PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s);
 
- if (!::CloseHandle(pi.hThread))
+ //Set up the pipes when needed for the current process.
+ if (stdin_stream.behavior == capture)
+ fhstdin = stdin_stream.object.pipe_->wend();
+ if (stdin_stream.behavior == capture)
+ fhstdin = stdin_stream.object.pipe_->wend();
+ if (stdin_stream.behavior == capture)
+ fhstdin = stdin_stream.object.pipe_->wend();
+
+ //define startup info from the new child
+ STARTUPINFOA start_up_info;
+ ::ZeroMemory(&start_up_info, sizeof(start_up_info));
+ start_up_info.cb = sizeof(start_up_info);
+
+ start_up_info.dwFlags |= STARTF_USESTDHANDLES;
+
+ configure_win32_stream(stdin_stream, start_up_info);
+ configure_win32_stream(stdout_stream, start_up_info);
+ configure_win32_stream(stderr_stream, start_up_info);
+
+ //define basic info to start the process
+ PROCESS_INFORMATION pi;
+ ::ZeroMemory(&pi, sizeof(pi));
+
+ boost::shared_array<char> cmdline = detail::collection_to_win32_cmdline(args);
+
+ boost::scoped_array<char> exe(new char[executable.size() + 1]);
+ ::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());
+
+
+ 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(),
+ &start_up_info, &pi))
+ boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateProcess failed"));
+
+ if (! ::CloseHandle(pi.hThread))
             boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch: CloseHandle failed"));
 
         return child(pi.dwProcessId, fhstdin, fhstdout, fhstderr, detail::file_handle(pi.hProcess));
+
 #endif
 }
 


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