|
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