$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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 
 }