annotate 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
rev   line source
ian@0 1 //
ian@0 2 // Boost.Process
ian@0 3 // ~~~~~~~~~~~~~
ian@0 4 //
ian@0 5 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
ian@0 6 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
ian@0 7 // Copyright (c) 2009 Boris Schaeling
ian@0 8 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
ian@0 9 //
ian@0 10 // Distributed under the Boost Software License, Version 1.0. (See accompanying
ian@0 11 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
ian@0 12 //
ian@0 13
ian@0 14 /**
ian@0 15 * \file boost/process/process.hpp
ian@0 16 *
ian@0 17 * Includes the declaration of the process class.
ian@0 18 */
ian@0 19
ian@0 20 #ifndef BOOST_PROCESS_PROCESS_HPP
ian@0 21 #define BOOST_PROCESS_PROCESS_HPP
ian@0 22
ian@0 23 #include <boost/process/config.hpp>
ian@0 24
ian@0 25 #if defined(BOOST_POSIX_API)
ian@0 26 # include <unistd.h>
ian@0 27 # include <sys/types.h>
ian@0 28 # include <signal.h>
ian@0 29 # include <sys/wait.h>
ian@0 30 # include <errno.h>
ian@0 31 #elif defined(BOOST_WINDOWS_API)
ian@0 32 # include <boost/process/handle.hpp>
ian@0 33 # include <cstdlib>
ian@0 34 # include <windows.h>
ian@0 35 #else
ian@0 36 # error "Unsupported platform."
ian@0 37 #endif
ian@0 38
ian@0 39 #include <boost/process/pid_type.hpp>
ian@0 40
ian@0 41 namespace boost {
ian@0 42 namespace process {
ian@0 43
ian@0 44 /**
ian@0 45 * Process class to represent any running process.
ian@0 46 */
ian@0 47 class process
ian@0 48 {
ian@0 49 public:
ian@0 50 /**
ian@0 51 * Constructs a new process object.
ian@0 52 *
ian@0 53 * Creates a new process object that represents a running process
ian@0 54 * within the system.
ian@0 55 *
ian@0 56 * On Windows the process is opened and a handle saved. This is required
ian@0 57 * to avoid the operating system removing process resources when the
ian@0 58 * process exits. The handle is closed when the process instance (and all
ian@0 59 * of its copies) is destroyed.
ian@0 60 */
ian@0 61 process(pid_type id)
ian@0 62 : id_(id)
ian@0 63 #if defined(BOOST_WINDOWS_API)
ian@0 64 , handle_(open_process(id))
ian@0 65 #endif
ian@0 66 {
ian@0 67 }
ian@0 68
ian@0 69 #if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN)
ian@0 70 /**
ian@0 71 * Constructs a new process object.
ian@0 72 *
ian@0 73 * Creates a new process object that represents a running process
ian@0 74 * within the system.
ian@0 75 *
ian@0 76 * This operation is only available on Windows systems. The handle is
ian@0 77 * closed when the process instance (and all of its copies) is destroyed.
ian@0 78 */
ian@0 79 process(handle h)
ian@0 80 : id_(GetProcessId(h.native())),
ian@0 81 handle_(h)
ian@0 82 {
ian@0 83 }
ian@0 84 #endif
ian@0 85
ian@0 86 /**
ian@0 87 * Returns the process identifier.
ian@0 88 */
ian@0 89 pid_type get_id() const
ian@0 90 {
ian@0 91 return id_;
ian@0 92 }
ian@0 93
ian@0 94 /**
ian@0 95 * Terminates the process execution.
ian@0 96 *
ian@0 97 * Forces the termination of the process execution. Some platforms
ian@0 98 * allow processes to ignore some external termination notifications
ian@0 99 * or to capture them for a proper exit cleanup. You can set the
ian@0 100 * \a force flag to true to force their termination regardless
ian@0 101 * of any exit handler.
ian@0 102 *
ian@0 103 * After this call, accessing this object can be dangerous because the
ian@0 104 * process identifier may have been reused by a different process. It
ian@0 105 * might still be valid, though, if the process has refused to die.
ian@0 106 *
ian@0 107 * \throw boost::system::system_error If system calls used to terminate the
ian@0 108 * process fail.
ian@0 109 */
ian@0 110 void terminate(bool force = false) const
ian@0 111 {
ian@0 112 #if defined(BOOST_POSIX_API)
ian@0 113 if (kill(id_, force ? SIGKILL : SIGTERM) == -1)
ian@0 114 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("kill(2) failed");
ian@0 115 #elif defined(BOOST_WINDOWS_API)
ian@0 116 #if defined(BOOST_MSVC)
ian@0 117 force;
ian@0 118 #endif
ian@0 119 HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, id_);
ian@0 120 if (h == NULL)
ian@0 121 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
ian@0 122 if (!TerminateProcess(h, EXIT_FAILURE))
ian@0 123 {
ian@0 124 CloseHandle(h);
ian@0 125 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("TerminateProcess() failed");
ian@0 126 }
ian@0 127 if (!CloseHandle(h))
ian@0 128 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
ian@0 129 #endif
ian@0 130 }
ian@0 131
ian@0 132 /**
ian@0 133 * Blocks and waits for the process to terminate.
ian@0 134 *
ian@0 135 * Returns an exit code. The process object ceases to be valid after this
ian@0 136 * call.
ian@0 137 *
ian@0 138 * \remark Blocking remarks: This call blocks if the process has not
ian@0 139 * finalized execution and waits until it terminates.
ian@0 140 *
ian@0 141 * \throw boost::system::system_error If system calls used to wait for the
ian@0 142 * process fail.
ian@0 143 */
ian@0 144 int wait() const
ian@0 145 {
ian@0 146 #if defined(BOOST_POSIX_API)
ian@0 147 pid_t p;
ian@0 148 int status;
ian@0 149 do
ian@0 150 {
ian@0 151 p = waitpid(id_, &status, 0);
ian@0 152 } while (p == -1 && errno == EINTR);
ian@0 153 if (p == -1)
ian@0 154 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("waitpid(2) failed");
ian@0 155 return status;
ian@0 156 #elif defined(BOOST_WINDOWS_API)
ian@0 157 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE,
ian@0 158 id_);
ian@0 159 if (h == NULL)
ian@0 160 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
ian@0 161 if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED)
ian@0 162 {
ian@0 163 CloseHandle(h);
ian@0 164 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
ian@0 165 "WaitForSingleObject() failed");
ian@0 166 }
ian@0 167 DWORD exit_code;
ian@0 168 if (!GetExitCodeProcess(h, &exit_code))
ian@0 169 {
ian@0 170 CloseHandle(h);
ian@0 171 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
ian@0 172 "GetExitCodeProcess() failed");
ian@0 173 }
ian@0 174 if (!CloseHandle(h))
ian@0 175 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CloseHandle() failed");
ian@0 176 return exit_code;
ian@0 177 #endif
ian@0 178 }
ian@0 179
ian@0 180 private:
ian@0 181 /**
ian@0 182 * The process identifier.
ian@0 183 */
ian@0 184 pid_type id_;
ian@0 185
ian@0 186 #if defined(BOOST_WINDOWS_API)
ian@0 187 /**
ian@0 188 * Opens a process and returns a handle.
ian@0 189 *
ian@0 190 * OpenProcess() returns NULL and not INVALID_HANDLE_VALUE on failure.
ian@0 191 * That's why the return value is manually checked in this helper function
ian@0 192 * instead of simply passing it to the constructor of the handle class.
ian@0 193 */
ian@0 194 HANDLE open_process(pid_type id)
ian@0 195 {
ian@0 196 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id);
ian@0 197 if (h == NULL)
ian@0 198 BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
ian@0 199 return h;
ian@0 200 }
ian@0 201
ian@0 202 /**
ian@0 203 * The process handle.
ian@0 204 */
ian@0 205 handle handle_;
ian@0 206 #endif
ian@0 207 };
ian@0 208
ian@0 209 }
ian@0 210 }
ian@0 211
ian@0 212 #endif