$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r63802 - in sandbox/SOC/2010/process/boost/process: . detail
From: fotanus_at_[hidden]
Date: 2010-07-10 00:07:39
Author: fotanus
Date: 2010-07-10 00:07:36 EDT (Sat, 10 Jul 2010)
New Revision: 63802
URL: http://svn.boost.org/trac/boost/changeset/63802
Log:
Added linux support to new stream_behavior model.
It's 100% yet, but compiles and run a basic create_child with inheritance.
Text files modified: 
   sandbox/SOC/2010/process/boost/process/child.hpp                |   124 --------------------------------------- 
   sandbox/SOC/2010/process/boost/process/context.hpp              |    10 +-                                      
   sandbox/SOC/2010/process/boost/process/detail/posix_helpers.hpp |     6                                         
   sandbox/SOC/2010/process/boost/process/environment.hpp          |     2                                         
   sandbox/SOC/2010/process/boost/process/operations.hpp           |    93 ++++++++---------------------           
   sandbox/SOC/2010/process/boost/process/process.hpp              |     1                                         
   sandbox/SOC/2010/process/boost/process/self.hpp                 |     8 +-                                      
   sandbox/SOC/2010/process/boost/process/status.hpp               |    52 ++++++++++++++++                        
   sandbox/SOC/2010/process/boost/process/stream_behavior.hpp      |     3                                         
   9 files changed, 99 insertions(+), 200 deletions(-)
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -22,9 +22,8 @@
 #include <boost/process/config.hpp>
 
 #if defined(BOOST_POSIX_API)
-#   include <boost/process/detail/pipe.hpp>
-#   include <boost/process/detail/posix_ops.hpp>
-#   include <boost/process/detail/stream_info.hpp>
+#   include <boost/process/pipe.hpp>
+#   include <boost/process/detail/posix_helpers.hpp>
 #   include <map>
 #   include <unistd.h>
 #elif defined(BOOST_WINDOWS_API)
@@ -64,7 +63,7 @@
      * 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(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr, detail::file_handle fhprocess = detail::file_handle())
         : process(id)
 #if defined(BOOST_WINDOWS_API) 
         , process_handle_(fhprocess.release(), ::CloseHandle) 
@@ -152,123 +151,6 @@
     boost::shared_ptr<void> process_handle_; 
 #endif 
 
-#if defined(BOOST_POSIX_API) 
-public:
-    /**
-     * Creates a new child object on a POSIX platform.
-     *
-     * The \a infoin and \a infoout maps contain the pipes used to handle
-     * the redirections of the child process; at the moment, no other
-     * stream_info types are supported. If the launcher was asked to
-     * redirect any of the three standard flows, their pipes must be
-     * present in these maps.
-     */
-    child(id_type id, detail::info_map &infoin, detail::info_map &infoout)
-        : child(id,
-        detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false),
-        detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true),
-        detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true))
-    {
-        for (detail::info_map::iterator it = infoin.begin();
-                it != infoin.end(); ++it)
-        {
-            detail::stream_info &si = it->second;
-            if (si.type_ == detail::stream_info::use_pipe)
-            {
-                BOOST_ASSERT(si.pipe_->wend().valid());
-                boost::shared_ptr<postream> st(new postream(si.pipe_->wend()));
-                input_map_.insert(input_map_t::value_type(it->first, st));
-            }
-        }
-
-        for (detail::info_map::iterator it = infoout.begin();
-                it != infoout.end(); ++it)
-        {
-            detail::stream_info &si = it->second;
-            if (si.type_ == detail::stream_info::use_pipe)
-            {
-                BOOST_ASSERT(si.pipe_->rend().valid());
-                boost::shared_ptr<pistream> st(new pistream(si.pipe_->rend()));
-                output_map_.insert(output_map_t::value_type(it->first, st));
-            }
-        }
-    }
-
-    /**
-     * Gets a reference to the child's input stream \a desc.
-     *
-     * Returns a reference to a postream object that represents one of
-     * the multiple input communication channels with the child process.
-     * The channel is identified by \a desc as seen from the child's
-     * point of view. The parent can use the returned stream to send
-     * data to the child.
-     *
-     * Giving this function the STDIN_FILENO constant (defined in
-     * unistd.h) is a synonym for the get_stdin() call inherited from
-     * child.
-     */
-    postream &get_input(int desc) const
-    {
-        if (desc == STDIN_FILENO)
-            return posix_child::get_stdin();
-        else
-        {
-            input_map_t::const_iterator it = input_map_.find(desc);
-            BOOST_ASSERT(it != input_map_.end());
-            return *it->second;
-        }
-    }
-
-    /**
-     * Gets a reference to the child's output stream \a desc.
-     *
-     * Returns a reference to a pistream object that represents one of
-     * the multiple output communication channels with the child process.
-     * The channel is identified by \a desc as seen from the child's
-     * point of view. The parent can use the returned stream to retrieve
-     * data from the child.
-     *
-     * Giving this function the STDOUT_FILENO or STDERR_FILENO constants
-     * (both defined in unistd.h) are synonyms for the get_stdout() and
-     * get_stderr() calls inherited from child, respectively.
-     */
-    pistream &get_output(int desc) const
-    {
-        if (desc == STDOUT_FILENO)
-            return posix_child::get_stdout();
-        else if (desc == STDERR_FILENO)
-            return posix_child::get_stderr();
-        else
-        {
-            output_map_t::const_iterator it = output_map_.find(desc);
-            BOOST_ASSERT(it != output_map_.end());
-            return *it->second;
-        }
-    }
-
-private:
-    /**
-     * Maps child's file descriptors to postream objects.
-     */
-    typedef std::map<int, boost::shared_ptr<postream> > input_map_t;
-
-    /**
-     * Contains all relationships between child's input file
-     * descriptors and their corresponding postream objects.
-     */
-    input_map_t input_map_;
-
-    /**
-     * Maps child's file descriptors to pistream objects.
-     */
-    typedef std::map<int, boost::shared_ptr<pistream> > output_map_t;
-
-    /**
-     * Contains all relationships between child's output file
-     * descriptors and their corresponding pistream objects.
-     */
-    output_map_t output_map_;
-#endif 
 };
 
 /**
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -38,7 +38,7 @@
     boost::shared_ptr<behavior::stream> stderr_behavior;
     std::string process_name;
     std::string work_dir;
-    environment environment;
+    environment_t environment;
 
     /** 
      * Constructs a process context. 
@@ -46,11 +46,11 @@
      * Sets behavior of standard streams (inherit), current work directory 
      * and environment variables. 
      */ 
-    context() 
+    context()
 #if defined(BOOST_POSIX_API) 
-        : stdin_behavior(behavior::inherit::def(behavior::inherit(STDIN_FILENO))), 
-        stdout_behavior(behavior::inherit::def(behavior::inherit(STDOUT_FILENO))), 
-        stderr_behavior(behavior::inherit::def(behavior::inherit(STDERR_FILENO))), 
+        : 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))), 
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -45,12 +45,12 @@
  *         the environment's content. Each array entry is a
  *         NULL-terminated string of the form var=value.
  */
-inline char **environment_to_envp(const environment &env)
+inline char **environment_to_envp(const environment_t &env)
 {
     char **envp = new char*[env.size() + 1]; 
 
-    environment::size_type i = 0; 
-    for (environment::const_iterator it = env.begin(); it != env.end(); ++it) 
+    environment_t::size_type i = 0; 
+    for (environment_t::const_iterator it = env.begin(); it != env.end(); ++it) 
     { 
         std::string s = it->first + "=" + it->second; 
         envp[i] = new char[s.size() + 1]; 
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -43,7 +43,7 @@
  * This is provided for-free by the map container used to implement this
  * type, and this behavior is required by Windows systems.
  */
-typedef std::map<std::string, std::string> environment;
+typedef std::map<std::string, std::string> environment_t;
 
 }
 }
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -33,6 +33,7 @@
 #   include <boost/process/detail/win32_helpers.hpp>
 #   include <boost/algorithm/string/predicate.hpp>
 #   include <windows.h>
+#   include <boost/process/status.hpp>
 #else
 #   error "Unsupported platform."
 #endif
@@ -40,7 +41,6 @@
 #include <boost/process/child.hpp>
 #include <boost/process/context.hpp>
 #include <boost/process/stream_behavior.hpp>
-#include <boost/process/status.hpp>
 #include <boost/process/detail/file_handle.hpp>
 #include <boost/filesystem/path.hpp>
 #include <boost/algorithm/string/predicate.hpp>
@@ -179,92 +179,53 @@
     args.insert(args.begin(), p_name);
 
 #if defined(BOOST_POSIX_API)
-    child::id_type pid = ::fork();
+    child::id_type pid;
+    pid = ::fork();
 
     if (pid == -1)
         BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("fork(2) failed"); 
 
     if (pid == 0) 
-    { 
-#if defined(F_MAXFD) 
-        int maxdescs = ::fcntl(-1, F_MAXFD, 0); 
-        if (maxdescs == -1) 
-            maxdescs = ::sysconf(_SC_OPEN_MAX); 
-#else 
-        int maxdescs = ::sysconf(_SC_OPEN_MAX); 
-#endif 
-        if (maxdescs == -1) 
-            maxdescs = 1024; 
-        try 
-        { 
-            boost::scoped_array<bool> closeflags(new bool[maxdescs]); 
-            for (int i = 0; i < maxdescs; ++i) 
-                closeflags[i] = true; 
-
-            // setup_input(infoin, closeflags.get(), maxdescs); 
-            // setup_output(infoout, closeflags.get(), maxdescs); 
-
-            int stdin_fd = ctx.stdin_behavior->get_child_end();
-            if (stdin_fd != -1 && stdin_fd < maxdescs)
-                closeflags[stdin_fd] = false;
-
-            int stdout_fd = ctx.stdout_behavior->get_child_end();
-            if (stdout_fd != -1 && stdout_fd < maxdescs)
-                closeflags[stdout_fd] = false;
-
-            int stderr_fd = ctx.stderr_behavior->get_child_end();
-            if (stderr_fd != -1 && stderr_fd < maxdescs)
-                closeflags[stderr_fd] = false;
-
-            for (int i = 0; i < maxdescs; ++i) 
-            { 
-                if (closeflags[i]) 
-                    ::close(i); 
-            } 
-
-            // setup(); 
-        } 
-        catch (const boost::system::system_error &e) 
-        { 
-            ::write(STDERR_FILENO, e.what(), std::strlen(e.what())); 
-            ::write(STDERR_FILENO, "\n", 1); 
-            std::exit(EXIT_FAILURE); 
-        } 
+    {
+        dup2(ctx.stdin_behavior->get_child_end(),STDIN_FILENO);
+        dup2(ctx.stdout_behavior->get_child_end(),STDOUT_FILENO);
+        dup2(ctx.stderr_behavior->get_child_end(),STDERR_FILENO);
 
         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);
 
-        boost::system::system_error e(boost::system::error_code(errno, boost::system::get_system_category()), BOOST_PROCESS_SOURCE_LOCATION "execve(2) failed"); 
-
         for (std::size_t i = 0; i < argcv.first; ++i) 
             delete[] argcv.second[i]; 
         delete[] argcv.second; 
 
-        for (std::size_t i = 0; i < env.size(); ++i) 
+        for (std::size_t i = 0; i < sizeof(envp); ++i) 
             delete[] envp[i]; 
         delete[] envp; 
 
-        ::write(STDERR_FILENO, e.what(), std::strlen(e.what())); 
-        ::write(STDERR_FILENO, "\n", 1); 
-        // TODO: Use return values which is less likely used by the
-        // program which should have been started.
+        BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("execve() failed"); 
         std::exit(EXIT_FAILURE); 
-    } 
 
-    BOOST_ASSERT(pid > 0);
+    }
+    else
+    {
+        BOOST_ASSERT(pid > 0);
+
+        //Is this really necessary?
+        if(ctx.stdin_behavior->get_child_end() != -1)
+            ::close(ctx.stdin_behavior->get_child_end());
+        if(ctx.stdout_behavior->get_child_end() != -1)
+            ::close(ctx.stdout_behavior->get_child_end());
+        if(ctx.stderr_behavior->get_child_end() != -1)
+            ::close(ctx.stderr_behavior->get_child_end());
+
+        return child(pid,
+        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()));
+    }
 
-    if (ctx.stdin_behavior->get_child_end() != -1)
-        ::close(ctx.stdin_behavior->get_child_end());
-    if (ctx.stdout_behavior->get_child_end() != -1)
-        ::close(ctx.stdout_behavior->get_child_end());
-    if (ctx.stderr_behavior->get_child_end() != -1)
-        ::close(ctx.stderr_behavior->get_child_end());
 
-    return child(pid, 
-        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())); 
 #elif defined(BOOST_WINDOWS_API)
     STARTUPINFOA startup_info;
     ::ZeroMemory(&startup_info, sizeof(startup_info));
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -23,6 +23,7 @@
 
 #if defined(BOOST_POSIX_API)
 #   include <cerrno>
+#   include <sys/wait.h>
 #   include <signal.h>
 #elif defined(BOOST_WINDOWS_API)
 #   include <cstdlib>
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -75,9 +75,9 @@
      * Returns the current process' environment variables. Modifying the
      * returned object has no effect on the current environment.
      */
-    static environment get_environment()
+    static environment_t get_environment()
     {
-        environment e;
+        environment_t e;
 
 #if defined(BOOST_POSIX_API)
 #   if defined(__APPLE__)
@@ -90,7 +90,7 @@
         {
             std::string s = *env;
             std::string::size_type pos = s.find('=');
-            e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1)));
+            e.insert(boost::process::environment_t::value_type(s.substr(0, pos), s.substr(pos + 1)));
             ++env;
         }
 #elif defined(BOOST_WINDOWS_API)
@@ -108,7 +108,7 @@
             {
                 std::string s = env;
                 std::string::size_type pos = s.find('=');
-                e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1)));
+                e.insert(boost::process::environment_t::value_type(s.substr(0, pos), s.substr(pos + 1)));
                 env += s.size() + 1;
             }
         }
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-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -19,6 +19,7 @@
 #ifndef BOOST_PROCESS_STATUS_HPP
 #define BOOST_PROCESS_STATUS_HPP
 
+#if defined(BOOST_WINDOWS_API)
 #include <boost/process/config.hpp>
 #include <boost/process/detail/basic_status.hpp>
 #include <boost/process/detail/basic_status_service.hpp>
@@ -30,5 +31,56 @@
 
 }
 }
+#endif
+#if defined(BOOST_POSIX_API)
+
+//Old status implementation
+class status
+{
+    friend class process;
+
+public:
+    /**
+     * Returns whether the process exited gracefully or not.
+     */
+    bool exited() const
+    {
+        return WIFEXITED(flags_);
+    }
+
+    /**
+     * If exited, returns the exit code.
+     *
+     * If the process exited, returns the exit code it returned.
+     *
+     * \pre exited() is true.
+     */
 
+    int exit_code() const
+    {
+        BOOST_ASSERT(exited());
+
+        return WEXITSTATUS(flags_);
+    }
+
+protected:
+    /**
+     * Creates a status object based on exit information.
+     *
+     * Creates a new status object representing the exit status of a
+     * child process.
+     *
+     * \param flags In a POSIX system this parameter contains the
+     *        flags returned by the ::waitpid() call. In a
+     *        Windows system it contains the exit code only.
+     */
+    status(int flags)
+        : flags_(flags) {}
+
+    /**
+     * OS-specific codification of exit status.
+     */
+    int flags_;
+};
+#endif
 #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-07-10 00:07:36 EDT (Sat, 10 Jul 2010)
@@ -115,6 +115,9 @@
         if (!::DuplicateHandle(::GetCurrentProcess(), child_end_, ::GetCurrentProcess(), &child_end_, 0, TRUE, DUPLICATE_SAME_ACCESS)) 
             BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("DuplicateHandle() failed"); 
 #endif 
+#if defined(BOOST_POSIX_API)
+        //Do nothing since is the default.
+#endif
     } 
 
     static boost::shared_ptr<inherit> def(native_type child_end)