diff third_party/boost/process/process.hpp @ 0:add35537fdbb tip

Initial import
author irh <ian.r.hobson@gmail.com>
date Thu, 25 Aug 2011 11:05:55 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/third_party/boost/process/process.hpp	Thu Aug 25 11:05:55 2011 +0100
@@ -0,0 +1,212 @@
+//
+// Boost.Process
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+/**
+ * \file boost/process/process.hpp
+ *
+ * Includes the declaration of the process class.
+ */
+
+#ifndef BOOST_PROCESS_PROCESS_HPP
+#define BOOST_PROCESS_PROCESS_HPP
+
+#include <boost/process/config.hpp>
+
+#if defined(BOOST_POSIX_API)
+#   include <unistd.h>
+#   include <sys/types.h>
+#   include <signal.h>
+#   include <sys/wait.h>
+#   include <errno.h>
+#elif defined(BOOST_WINDOWS_API)
+#   include <boost/process/handle.hpp>
+#   include <cstdlib>
+#   include <windows.h>
+#else
+#   error "Unsupported platform."
+#endif
+
+#include <boost/process/pid_type.hpp>
+
+namespace boost {
+namespace process {
+
+/**
+ * Process class to represent any running process.
+ */
+class process
+{
+public:
+    /**
+     * Constructs a new process object.
+     *
+     * 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_(open_process(id))
+#endif
+    {
+    }
+
+#if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN)
+    /**
+     * 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 h)
+        : id_(GetProcessId(h.native())),
+        handle_(h)
+    {
+    }
+#endif
+
+    /**
+     * Returns the process identifier.
+     */
+    pid_type get_id() const
+    {
+        return id_;
+    }
+
+    /**
+     * Terminates the process execution.
+     *
+     * Forces the termination of the process execution. Some platforms
+     * allow processes to ignore some external termination notifications
+     * or to capture them for a proper exit cleanup. You can set the
+     * \a force flag to true to force their termination regardless
+     * of any exit handler.
+     *
+     * After this call, accessing this object can be dangerous because the
+     * process identifier may have been reused by a different process. It
+     * might still be valid, though, if the process has refused to die.
+     *
+     * \throw boost::system::system_error If system calls used to terminate the
+     *        process fail.
+     */
+    void terminate(bool force = false) const
+    {
+#if defined(BOOST_POSIX_API)
+        if (kill(id_, force ? SIGKILL : SIGTERM) == -1)
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("kill(2) failed");
+#elif defined(BOOST_WINDOWS_API)
+#if defined(BOOST_MSVC)
+        force;
+#endif
+        HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, id_);
+        if (h == NULL)
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
+        if (!TerminateProcess(h, EXIT_FAILURE))
+        {
+            CloseHandle(h);
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("TerminateProcess() failed");
+        }
+        if (!CloseHandle(h))
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
+#endif
+    }
+
+    /**
+     * Blocks and waits for the process to terminate.
+     *
+     * Returns an exit code. The process object ceases to be valid after this
+     * call.
+     *
+     * \remark Blocking remarks: This call blocks if the process has not
+     *         finalized execution and waits until it terminates.
+     *
+     * \throw boost::system::system_error If system calls used to wait for the
+     *        process fail.
+     */
+    int wait() const
+    {
+#if defined(BOOST_POSIX_API)
+        pid_t p;
+        int status;
+        do
+        {
+            p = waitpid(id_, &status, 0);
+        } while (p == -1 && errno == EINTR);
+        if (p == -1)
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("waitpid(2) failed");
+        return status;
+#elif defined(BOOST_WINDOWS_API)
+        HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE,
+            id_);
+        if (h == NULL) 
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
+        if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED)
+        {
+            CloseHandle(h);
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
+                "WaitForSingleObject() failed");
+        }
+        DWORD exit_code;
+        if (!GetExitCodeProcess(h, &exit_code))
+        {
+            CloseHandle(h);
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
+                "GetExitCodeProcess() failed");
+        }
+        if (!CloseHandle(h))
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
+        return exit_code;
+#endif
+    }
+
+private:
+    /**
+     * The process identifier.
+     */
+    pid_type id_;
+
+#if defined(BOOST_WINDOWS_API)
+    /**
+     * Opens a process and returns a handle.
+     *
+     * OpenProcess() returns NULL and not INVALID_HANDLE_VALUE on failure.
+     * That's why the return value is manually checked in this helper function
+     * instead of simply passing it to the constructor of the handle class.
+     */
+    HANDLE open_process(pid_type id)
+    {
+        HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id);
+        if (h == NULL)
+            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
+        return h;
+    }
+
+    /**
+     * The process handle.
+     */
+    handle handle_;
+#endif
+};
+
+}
+}
+
+#endif