1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/process_util.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,313 @@ 1.4 +// Copyright (c) 2009 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +// This file/namespace contains utility functions for enumerating, ending and 1.9 +// computing statistics of processes. 1.10 + 1.11 +#ifndef BASE_PROCESS_UTIL_H_ 1.12 +#define BASE_PROCESS_UTIL_H_ 1.13 + 1.14 +#include "base/basictypes.h" 1.15 + 1.16 +#if defined(OS_WIN) 1.17 +#include <windows.h> 1.18 +#include <tlhelp32.h> 1.19 +#elif defined(OS_LINUX) || defined(__GLIBC__) 1.20 +#include <dirent.h> 1.21 +#include <limits.h> 1.22 +#include <sys/types.h> 1.23 +#elif defined(OS_MACOSX) 1.24 +#include <mach/mach.h> 1.25 +#endif 1.26 + 1.27 +#include <map> 1.28 +#include <string> 1.29 +#include <vector> 1.30 + 1.31 +#include "base/command_line.h" 1.32 +#include "base/process.h" 1.33 + 1.34 +#if defined(OS_WIN) 1.35 +typedef PROCESSENTRY32 ProcessEntry; 1.36 +typedef IO_COUNTERS IoCounters; 1.37 +#elif defined(OS_POSIX) 1.38 +// TODO(port): we should not rely on a Win32 structure. 1.39 +struct ProcessEntry { 1.40 + int pid; 1.41 + int ppid; 1.42 + char szExeFile[NAME_MAX + 1]; 1.43 +}; 1.44 + 1.45 +struct IoCounters { 1.46 + unsigned long long ReadOperationCount; 1.47 + unsigned long long WriteOperationCount; 1.48 + unsigned long long OtherOperationCount; 1.49 + unsigned long long ReadTransferCount; 1.50 + unsigned long long WriteTransferCount; 1.51 + unsigned long long OtherTransferCount; 1.52 +}; 1.53 + 1.54 +#include "base/file_descriptor_shuffle.h" 1.55 +#endif 1.56 + 1.57 +#if defined(OS_MACOSX) 1.58 +struct kinfo_proc; 1.59 +#endif 1.60 + 1.61 +namespace base { 1.62 + 1.63 +// These can be used in a 32-bit bitmask. 1.64 +enum ProcessArchitecture { 1.65 + PROCESS_ARCH_I386 = 0x1, 1.66 + PROCESS_ARCH_X86_64 = 0x2, 1.67 + PROCESS_ARCH_PPC = 0x4, 1.68 + PROCESS_ARCH_ARM = 0x8 1.69 +}; 1.70 + 1.71 +inline ProcessArchitecture GetCurrentProcessArchitecture() 1.72 +{ 1.73 + base::ProcessArchitecture currentArchitecture; 1.74 +#if defined(ARCH_CPU_X86) 1.75 + currentArchitecture = base::PROCESS_ARCH_I386; 1.76 +#elif defined(ARCH_CPU_X86_64) 1.77 + currentArchitecture = base::PROCESS_ARCH_X86_64; 1.78 +#elif defined(ARCH_CPU_PPC) 1.79 + currentArchitecture = base::PROCESS_ARCH_PPC; 1.80 +#elif defined(ARCH_CPU_ARMEL) 1.81 + currentArchitecture = base::PROCESS_ARCH_ARM; 1.82 +#endif 1.83 + return currentArchitecture; 1.84 +} 1.85 + 1.86 +// A minimalistic but hopefully cross-platform set of exit codes. 1.87 +// Do not change the enumeration values or you will break third-party 1.88 +// installers. 1.89 +enum { 1.90 + PROCESS_END_NORMAL_TERMINATON = 0, 1.91 + PROCESS_END_KILLED_BY_USER = 1, 1.92 + PROCESS_END_PROCESS_WAS_HUNG = 2 1.93 +}; 1.94 + 1.95 +// Returns the id of the current process. 1.96 +ProcessId GetCurrentProcId(); 1.97 + 1.98 +// Returns the ProcessHandle of the current process. 1.99 +ProcessHandle GetCurrentProcessHandle(); 1.100 + 1.101 +// Converts a PID to a process handle. This handle must be closed by 1.102 +// CloseProcessHandle when you are done with it. Returns true on success. 1.103 +bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle); 1.104 + 1.105 +// Converts a PID to a process handle. On Windows the handle is opened 1.106 +// with more access rights and must only be used by trusted code. 1.107 +// You have to close returned handle using CloseProcessHandle. Returns true 1.108 +// on success. 1.109 +bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle); 1.110 + 1.111 +// Closes the process handle opened by OpenProcessHandle. 1.112 +void CloseProcessHandle(ProcessHandle process); 1.113 + 1.114 +// Returns the unique ID for the specified process. This is functionally the 1.115 +// same as Windows' GetProcessId(), but works on versions of Windows before 1.116 +// Win XP SP1 as well. 1.117 +ProcessId GetProcId(ProcessHandle process); 1.118 + 1.119 +#if defined(OS_POSIX) 1.120 +// Sets all file descriptors to close on exec except for stdin, stdout 1.121 +// and stderr. 1.122 +// TODO(agl): remove this function 1.123 +// WARNING: do not use. It's inherently race-prone in the face of 1.124 +// multi-threading. 1.125 +void SetAllFDsToCloseOnExec(); 1.126 +// Close all file descriptors, expect those which are a destination in the 1.127 +// given multimap. Only call this function in a child process where you know 1.128 +// that there aren't any other threads. 1.129 +void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map); 1.130 +#endif 1.131 + 1.132 +enum ChildPrivileges { 1.133 + PRIVILEGES_DEFAULT, 1.134 + PRIVILEGES_UNPRIVILEGED, 1.135 + PRIVILEGES_INHERIT, 1.136 + PRIVILEGES_LAST 1.137 +}; 1.138 + 1.139 +#if defined(OS_WIN) 1.140 +// Runs the given application name with the given command line. Normally, the 1.141 +// first command line argument should be the path to the process, and don't 1.142 +// forget to quote it. 1.143 +// 1.144 +// If wait is true, it will block and wait for the other process to finish, 1.145 +// otherwise, it will just continue asynchronously. 1.146 +// 1.147 +// Example (including literal quotes) 1.148 +// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" 1.149 +// 1.150 +// If process_handle is non-NULL, the process handle of the launched app will be 1.151 +// stored there on a successful launch. 1.152 +// NOTE: In this case, the caller is responsible for closing the handle so 1.153 +// that it doesn't leak! 1.154 +bool LaunchApp(const std::wstring& cmdline, 1.155 + bool wait, bool start_hidden, ProcessHandle* process_handle); 1.156 +#elif defined(OS_POSIX) 1.157 +// Runs the application specified in argv[0] with the command line argv. 1.158 +// Before launching all FDs open in the parent process will be marked as 1.159 +// close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to 1.160 +// propagate FDs into the child process. 1.161 +// 1.162 +// As above, if wait is true, execute synchronously. The pid will be stored 1.163 +// in process_handle if that pointer is non-null. 1.164 +// 1.165 +// Note that the first argument in argv must point to the filename, 1.166 +// and must be fully specified. 1.167 +typedef std::vector<std::pair<int, int> > file_handle_mapping_vector; 1.168 +bool LaunchApp(const std::vector<std::string>& argv, 1.169 + const file_handle_mapping_vector& fds_to_remap, 1.170 + bool wait, ProcessHandle* process_handle); 1.171 + 1.172 +typedef std::map<std::string, std::string> environment_map; 1.173 +bool LaunchApp(const std::vector<std::string>& argv, 1.174 + const file_handle_mapping_vector& fds_to_remap, 1.175 + const environment_map& env_vars_to_set, 1.176 + ChildPrivileges privs, 1.177 + bool wait, ProcessHandle* process_handle, 1.178 + ProcessArchitecture arch=GetCurrentProcessArchitecture()); 1.179 +bool LaunchApp(const std::vector<std::string>& argv, 1.180 + const file_handle_mapping_vector& fds_to_remap, 1.181 + const environment_map& env_vars_to_set, 1.182 + bool wait, ProcessHandle* process_handle, 1.183 + ProcessArchitecture arch=GetCurrentProcessArchitecture()); 1.184 +#endif 1.185 + 1.186 +// Adjust the privileges of this process to match |privs|. Only 1.187 +// returns if privileges were successfully adjusted. 1.188 +void SetCurrentProcessPrivileges(ChildPrivileges privs); 1.189 + 1.190 +// Executes the application specified by cl. This function delegates to one 1.191 +// of the above two platform-specific functions. 1.192 +bool LaunchApp(const CommandLine& cl, 1.193 + bool wait, bool start_hidden, ProcessHandle* process_handle); 1.194 + 1.195 +// Used to filter processes by process ID. 1.196 +class ProcessFilter { 1.197 + public: 1.198 + // Returns true to indicate set-inclusion and false otherwise. This method 1.199 + // should not have side-effects and should be idempotent. 1.200 + virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0; 1.201 + virtual ~ProcessFilter() { } 1.202 +}; 1.203 + 1.204 +// Attempts to kill the process identified by the given process 1.205 +// entry structure, giving it the specified exit code. If |wait| is true, wait 1.206 +// for the process to be actually terminated before returning. 1.207 +// Returns true if this is successful, false otherwise. 1.208 +bool KillProcess(ProcessHandle process, int exit_code, bool wait); 1.209 + 1.210 +// Get the termination status (exit code) of the process and return true if the 1.211 +// status indicates the process crashed. |child_exited| is set to true iff the 1.212 +// child process has terminated. (|child_exited| may be NULL.) 1.213 +// 1.214 +// On Windows, it is an error to call this if the process hasn't terminated 1.215 +// yet. On POSIX, |child_exited| is set correctly since we detect terminate in 1.216 +// a different manner on POSIX. 1.217 +bool DidProcessCrash(bool* child_exited, ProcessHandle handle); 1.218 + 1.219 +// This class provides a way to iterate through the list of processes 1.220 +// on the current machine that were started from the given executable 1.221 +// name. To use, create an instance and then call NextProcessEntry() 1.222 +// until it returns false. 1.223 +class NamedProcessIterator { 1.224 + public: 1.225 + NamedProcessIterator(const std::wstring& executable_name, 1.226 + const ProcessFilter* filter); 1.227 + ~NamedProcessIterator(); 1.228 + 1.229 + // If there's another process that matches the given executable name, 1.230 + // returns a const pointer to the corresponding PROCESSENTRY32. 1.231 + // If there are no more matching processes, returns NULL. 1.232 + // The returned pointer will remain valid until NextProcessEntry() 1.233 + // is called again or this NamedProcessIterator goes out of scope. 1.234 + const ProcessEntry* NextProcessEntry(); 1.235 + 1.236 + private: 1.237 +#if !defined(OS_BSD) || defined(__GLIBC__) 1.238 + // Determines whether there's another process (regardless of executable) 1.239 + // left in the list of all processes. Returns true and sets entry_ to 1.240 + // that process's info if there is one, false otherwise. 1.241 + bool CheckForNextProcess(); 1.242 + 1.243 + bool IncludeEntry(); 1.244 + 1.245 + // Initializes a PROCESSENTRY32 data structure so that it's ready for 1.246 + // use with Process32First/Process32Next. 1.247 + void InitProcessEntry(ProcessEntry* entry); 1.248 + 1.249 + std::wstring executable_name_; 1.250 +#endif 1.251 + 1.252 +#if defined(OS_WIN) 1.253 + HANDLE snapshot_; 1.254 + bool started_iteration_; 1.255 +#elif defined(OS_LINUX) || defined(__GLIBC__) 1.256 + DIR *procfs_dir_; 1.257 +#elif defined(OS_BSD) 1.258 + std::vector<ProcessEntry> content; 1.259 + size_t nextEntry; 1.260 +#elif defined(OS_MACOSX) 1.261 + std::vector<kinfo_proc> kinfo_procs_; 1.262 + size_t index_of_kinfo_proc_; 1.263 +#endif 1.264 +#if !defined(OS_BSD) || defined(__GLIBC__) 1.265 + ProcessEntry entry_; 1.266 + const ProcessFilter* filter_; 1.267 +#endif 1.268 + 1.269 + DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator); 1.270 +}; 1.271 + 1.272 +// Provides performance metrics for a specified process (CPU usage, memory and 1.273 +// IO counters). To use it, invoke CreateProcessMetrics() to get an instance 1.274 +// for a specific process, then access the information with the different get 1.275 +// methods. 1.276 +class ProcessMetrics { 1.277 + public: 1.278 + // Creates a ProcessMetrics for the specified process. 1.279 + // The caller owns the returned object. 1.280 + static ProcessMetrics* CreateProcessMetrics(ProcessHandle process); 1.281 + 1.282 + ~ProcessMetrics(); 1.283 + 1.284 + // Returns the CPU usage in percent since the last time this method was 1.285 + // called. The first time this method is called it returns 0 and will return 1.286 + // the actual CPU info on subsequent calls. 1.287 + // Note that on multi-processor machines, the CPU usage value is for all 1.288 + // CPUs. So if you have 2 CPUs and your process is using all the cycles 1.289 + // of 1 CPU and not the other CPU, this method returns 50. 1.290 + int GetCPUUsage(); 1.291 + 1.292 + private: 1.293 + explicit ProcessMetrics(ProcessHandle process); 1.294 + 1.295 + ProcessHandle process_; 1.296 + 1.297 + int processor_count_; 1.298 + 1.299 + // Used to store the previous times so we can compute the CPU usage. 1.300 + int64_t last_time_; 1.301 + int64_t last_system_time_; 1.302 + 1.303 + DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics); 1.304 +}; 1.305 + 1.306 +} // namespace base 1.307 + 1.308 +#if defined(OS_WIN) 1.309 +// Undo the windows.h damage 1.310 +#undef GetMessage 1.311 +#undef CreateEvent 1.312 +#undef GetClassName 1.313 +#undef GetBinaryType 1.314 +#endif 1.315 + 1.316 +#endif // BASE_PROCESS_UTIL_H_