Boost logo

Boost-Commit :

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)


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