Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64309 - in sandbox/SOC/2010/process: boost/process boost/process/detail libs/process/test
From: boris_at_[hidden]
Date: 2010-07-23 19:53:13


Author: bschaeling
Date: 2010-07-23 19:53:11 EDT (Fri, 23 Jul 2010)
New Revision: 64309
URL: http://svn.boost.org/trac/boost/changeset/64309

Log:
Added member variable to process class to save process handle (Windows only)
Text files modified:
   sandbox/SOC/2010/process/boost/process/child.hpp | 26 +++++++++++++++++++++++
   sandbox/SOC/2010/process/boost/process/context.hpp | 2
   sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp | 17 ++++----------
   sandbox/SOC/2010/process/boost/process/operations.hpp | 5 ---
   sandbox/SOC/2010/process/boost/process/process.hpp | 44 ++++++++++++++++++++++++++++++++++++++-
   sandbox/SOC/2010/process/libs/process/test/child.hpp | 16 +++----------
   6 files changed, 79 insertions(+), 31 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-23 19:53:11 EDT (Fri, 23 Jul 2010)
@@ -68,6 +68,32 @@
             stderr_.reset(new pistream(fhstderr));
     }
 
+#if defined(BOOST_WINDOWS_API)
+ /**
+ * Creates a new child object that represents the just spawned child
+ * process \a id.
+ *
+ * The \a fhstdin, \a fhstdout and \a fhstderr file handles represent
+ * the parent's handles used to communicate with the corresponding
+ * data streams. They needn't be valid but their availability must
+ * match the redirections configured by the launcher that spawned this
+ * process.
+ *
+ * This operation is only available on Windows systems.
+ */
+ child(HANDLE handle, detail::file_handle fhstdin,
+ detail::file_handle fhstdout, detail::file_handle fhstderr)
+ : process(handle)
+ {
+ if (fhstdin.valid())
+ stdin_.reset(new postream(fhstdin));
+ if (fhstdout.valid())
+ stdout_.reset(new pistream(fhstdout));
+ if (fhstderr.valid())
+ stderr_.reset(new pistream(fhstderr));
+ }
+#endif
+
     /**
      * Gets a reference to the child's standard input stream.
      *

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-23 19:53:11 EDT (Fri, 23 Jul 2010)
@@ -118,7 +118,7 @@
     {
     }
 #elif defined(BOOST_WINDOWS_API)
- void setup(STARTUPINFO &sainfo)
+ void setup(STARTUPINFOA &sainfo)
     {
     }
 #endif

Modified: sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp
==============================================================================
--- sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp (original)
+++ sandbox/SOC/2010/process/boost/process/detail/systembuf.hpp 2010-07-23 19:53:11 EDT (Fri, 23 Jul 2010)
@@ -154,7 +154,7 @@
      * \returns traits_type::eof() if a write error occurrs. Otherwise
      * returns traits_type::not_eof(c).
      */
- int_type overflow(int c)
+ virtual int_type overflow(int c)
     {
         BOOST_ASSERT(pptr() >= epptr());
 
@@ -180,31 +180,24 @@
      *
      * \returns 0 on success, -1 if an error occurred.
      */
-#if defined(BOOST_POSIX_API)
     virtual int sync()
     {
+#if defined(BOOST_POSIX_API)
         ssize_t cnt = pptr() - pbase();
- bool ok;
-
- ok = (write(handle_, pbase(), cnt) == cnt);
+ bool ok = (write(handle_, pbase(), cnt) == cnt);
         if (ok)
             pbump(-cnt);
         return ok ? 0 : -1;
- }
 #elif defined(BOOST_WINDOWS_API)
- virtual int sync()
- {
         long cnt = pptr() - pbase();
- bool ok;
         DWORD rcnt;
         BOOL res = WriteFile(handle_, pbase(), cnt, &rcnt, NULL);
-
- ok = (res && static_cast<long>(rcnt) == cnt);
+ bool ok = (res && static_cast<long>(rcnt) == cnt);
         if (ok)
             pbump(-cnt);
         return ok ? 0 : -1;
- }
 #endif
+ }
 
 private:
     /**

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-23 19:53:11 EDT (Fri, 23 Jul 2010)
@@ -314,13 +314,10 @@
         envstrs.get(), workdir.get(), &startup_info, &pi) == 0)
         BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed");
 
- if (!CloseHandle(pi.hProcess))
- BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
-
     if (!CloseHandle(pi.hThread))
         BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
 
- return child(pi.dwProcessId,
+ return child(pi.hProcess,
         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()));

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-23 19:53:11 EDT (Fri, 23 Jul 2010)
@@ -26,13 +26,13 @@
 # include <unistd.h>
 # include <sys/types.h>
 # include <signal.h>
-
 # include <sys/wait.h>
 #elif defined(BOOST_WINDOWS_API)
+# include <boost/shared_ptr.hpp>
 # include <cstdlib>
 # include <windows.h>
 #else
-# error "Unsupported platform."
+# error "Unsupported platform."
 #endif
 
 #include <boost/process/pid_type.hpp>
@@ -51,12 +51,41 @@
      *
      * Creates a new process object that represents a running process
      * within the system.
+ *
+ * On Windows the process is opened and a handle saved. This is required
+ * to avoid the operating system removing process resources when the
+ * process exits. The handle is closed when the process instance (and all
+ * of its copies) is destroyed.
      */
     process(pid_type id)
         : id_(id)
+#if defined(BOOST_WINDOWS_API)
+ , handle_(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id), CloseHandle)
+#endif
     {
+#if defined(BOOST_WINDOWS_API)
+ if (handle_ == NULL)
+ BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
+#endif
     }
 
+#if defined(BOOST_WINDOWS_API)
+ /**
+ * Constructs a new process object.
+ *
+ * Creates a new process object that represents a running process
+ * within the system.
+ *
+ * This operation is only available on Windows systems. The handle is
+ * closed when the process instance (and all of its copies) is destroyed.
+ */
+ process(HANDLE handle)
+ : id_(GetProcessId(handle)),
+ handle_(handle, CloseHandle)
+ {
+ }
+#endif
+
     /**
      * Returns the process identifier.
      */
@@ -148,6 +177,17 @@
      * The process identifier.
      */
     pid_type id_;
+
+#if defined(BOOST_WINDOWS_API)
+ /**
+ * The process handle.
+ *
+ * The process handle is saved in a shared pointer to guarantee that it
+ * is closed when not needed anymore. The handle guarantees that Windows
+ * does not remove process resources when a process exits.
+ */
+ boost::shared_ptr<void> handle_;
+#endif
 };
 
 }

Modified: sandbox/SOC/2010/process/libs/process/test/child.hpp
==============================================================================
--- sandbox/SOC/2010/process/libs/process/test/child.hpp (original)
+++ sandbox/SOC/2010/process/libs/process/test/child.hpp 2010-07-23 19:53:11 EDT (Fri, 23 Jul 2010)
@@ -61,21 +61,13 @@
     std::vector<std::string> args;
     args.push_back("is-closed-stdin");
 
- int s1 = Launcher()(args, Context(), bpb::close::def(),
+ int s = Launcher()(args, Context(), bpb::close::def(),
                         bpb::close::def(), bpb::close::def()).wait();
 #if defined(BOOST_POSIX_API)
- BOOST_REQUIRE(WIFEXITED(s1));
- BOOST_CHECK_EQUAL(WEXITSTATUS(s1), EXIT_SUCCESS);
-#elif defined(BOOST_WINDOWS_API)
- BOOST_CHECK_EQUAL(s1, EXIT_SUCCESS);
-#endif
-
- int s2 = Launcher()(args, Context(), bpb::pipe::def(bpb::pipe::input_stream)).wait();
-#if defined(BOOST_POSIX_API)
- BOOST_REQUIRE(WIFEXITED(s2));
- BOOST_CHECK_EQUAL(WEXITSTATUS(s2), EXIT_FAILURE);
+ BOOST_REQUIRE(WIFEXITED(s));
+ BOOST_CHECK_EQUAL(WEXITSTATUS(s), EXIT_SUCCESS);
 #elif defined(BOOST_WINDOWS_API)
- BOOST_CHECK_EQUAL(s2, EXIT_FAILURE);
+ BOOST_CHECK_EQUAL(s, EXIT_SUCCESS);
 #endif
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk