diff -r 000000000000 -r 6474c204b198 ipc/chromium/src/base/process_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ipc/chromium/src/base/process_util.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,313 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file/namespace contains utility functions for enumerating, ending and +// computing statistics of processes. + +#ifndef BASE_PROCESS_UTIL_H_ +#define BASE_PROCESS_UTIL_H_ + +#include "base/basictypes.h" + +#if defined(OS_WIN) +#include +#include +#elif defined(OS_LINUX) || defined(__GLIBC__) +#include +#include +#include +#elif defined(OS_MACOSX) +#include +#endif + +#include +#include +#include + +#include "base/command_line.h" +#include "base/process.h" + +#if defined(OS_WIN) +typedef PROCESSENTRY32 ProcessEntry; +typedef IO_COUNTERS IoCounters; +#elif defined(OS_POSIX) +// TODO(port): we should not rely on a Win32 structure. +struct ProcessEntry { + int pid; + int ppid; + char szExeFile[NAME_MAX + 1]; +}; + +struct IoCounters { + unsigned long long ReadOperationCount; + unsigned long long WriteOperationCount; + unsigned long long OtherOperationCount; + unsigned long long ReadTransferCount; + unsigned long long WriteTransferCount; + unsigned long long OtherTransferCount; +}; + +#include "base/file_descriptor_shuffle.h" +#endif + +#if defined(OS_MACOSX) +struct kinfo_proc; +#endif + +namespace base { + +// These can be used in a 32-bit bitmask. +enum ProcessArchitecture { + PROCESS_ARCH_I386 = 0x1, + PROCESS_ARCH_X86_64 = 0x2, + PROCESS_ARCH_PPC = 0x4, + PROCESS_ARCH_ARM = 0x8 +}; + +inline ProcessArchitecture GetCurrentProcessArchitecture() +{ + base::ProcessArchitecture currentArchitecture; +#if defined(ARCH_CPU_X86) + currentArchitecture = base::PROCESS_ARCH_I386; +#elif defined(ARCH_CPU_X86_64) + currentArchitecture = base::PROCESS_ARCH_X86_64; +#elif defined(ARCH_CPU_PPC) + currentArchitecture = base::PROCESS_ARCH_PPC; +#elif defined(ARCH_CPU_ARMEL) + currentArchitecture = base::PROCESS_ARCH_ARM; +#endif + return currentArchitecture; +} + +// A minimalistic but hopefully cross-platform set of exit codes. +// Do not change the enumeration values or you will break third-party +// installers. +enum { + PROCESS_END_NORMAL_TERMINATON = 0, + PROCESS_END_KILLED_BY_USER = 1, + PROCESS_END_PROCESS_WAS_HUNG = 2 +}; + +// Returns the id of the current process. +ProcessId GetCurrentProcId(); + +// Returns the ProcessHandle of the current process. +ProcessHandle GetCurrentProcessHandle(); + +// Converts a PID to a process handle. This handle must be closed by +// CloseProcessHandle when you are done with it. Returns true on success. +bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle); + +// Converts a PID to a process handle. On Windows the handle is opened +// with more access rights and must only be used by trusted code. +// You have to close returned handle using CloseProcessHandle. Returns true +// on success. +bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle); + +// Closes the process handle opened by OpenProcessHandle. +void CloseProcessHandle(ProcessHandle process); + +// Returns the unique ID for the specified process. This is functionally the +// same as Windows' GetProcessId(), but works on versions of Windows before +// Win XP SP1 as well. +ProcessId GetProcId(ProcessHandle process); + +#if defined(OS_POSIX) +// Sets all file descriptors to close on exec except for stdin, stdout +// and stderr. +// TODO(agl): remove this function +// WARNING: do not use. It's inherently race-prone in the face of +// multi-threading. +void SetAllFDsToCloseOnExec(); +// Close all file descriptors, expect those which are a destination in the +// given multimap. Only call this function in a child process where you know +// that there aren't any other threads. +void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map); +#endif + +enum ChildPrivileges { + PRIVILEGES_DEFAULT, + PRIVILEGES_UNPRIVILEGED, + PRIVILEGES_INHERIT, + PRIVILEGES_LAST +}; + +#if defined(OS_WIN) +// Runs the given application name with the given command line. Normally, the +// first command line argument should be the path to the process, and don't +// forget to quote it. +// +// If wait is true, it will block and wait for the other process to finish, +// otherwise, it will just continue asynchronously. +// +// Example (including literal quotes) +// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" +// +// If process_handle is non-NULL, the process handle of the launched app will be +// stored there on a successful launch. +// NOTE: In this case, the caller is responsible for closing the handle so +// that it doesn't leak! +bool LaunchApp(const std::wstring& cmdline, + bool wait, bool start_hidden, ProcessHandle* process_handle); +#elif defined(OS_POSIX) +// Runs the application specified in argv[0] with the command line argv. +// Before launching all FDs open in the parent process will be marked as +// close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to +// propagate FDs into the child process. +// +// As above, if wait is true, execute synchronously. The pid will be stored +// in process_handle if that pointer is non-null. +// +// Note that the first argument in argv must point to the filename, +// and must be fully specified. +typedef std::vector > file_handle_mapping_vector; +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + bool wait, ProcessHandle* process_handle); + +typedef std::map environment_map; +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + const environment_map& env_vars_to_set, + ChildPrivileges privs, + bool wait, ProcessHandle* process_handle, + ProcessArchitecture arch=GetCurrentProcessArchitecture()); +bool LaunchApp(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + const environment_map& env_vars_to_set, + bool wait, ProcessHandle* process_handle, + ProcessArchitecture arch=GetCurrentProcessArchitecture()); +#endif + +// Adjust the privileges of this process to match |privs|. Only +// returns if privileges were successfully adjusted. +void SetCurrentProcessPrivileges(ChildPrivileges privs); + +// Executes the application specified by cl. This function delegates to one +// of the above two platform-specific functions. +bool LaunchApp(const CommandLine& cl, + bool wait, bool start_hidden, ProcessHandle* process_handle); + +// Used to filter processes by process ID. +class ProcessFilter { + public: + // Returns true to indicate set-inclusion and false otherwise. This method + // should not have side-effects and should be idempotent. + virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0; + virtual ~ProcessFilter() { } +}; + +// Attempts to kill the process identified by the given process +// entry structure, giving it the specified exit code. If |wait| is true, wait +// for the process to be actually terminated before returning. +// Returns true if this is successful, false otherwise. +bool KillProcess(ProcessHandle process, int exit_code, bool wait); + +// Get the termination status (exit code) of the process and return true if the +// status indicates the process crashed. |child_exited| is set to true iff the +// child process has terminated. (|child_exited| may be NULL.) +// +// On Windows, it is an error to call this if the process hasn't terminated +// yet. On POSIX, |child_exited| is set correctly since we detect terminate in +// a different manner on POSIX. +bool DidProcessCrash(bool* child_exited, ProcessHandle handle); + +// This class provides a way to iterate through the list of processes +// on the current machine that were started from the given executable +// name. To use, create an instance and then call NextProcessEntry() +// until it returns false. +class NamedProcessIterator { + public: + NamedProcessIterator(const std::wstring& executable_name, + const ProcessFilter* filter); + ~NamedProcessIterator(); + + // If there's another process that matches the given executable name, + // returns a const pointer to the corresponding PROCESSENTRY32. + // If there are no more matching processes, returns NULL. + // The returned pointer will remain valid until NextProcessEntry() + // is called again or this NamedProcessIterator goes out of scope. + const ProcessEntry* NextProcessEntry(); + + private: +#if !defined(OS_BSD) || defined(__GLIBC__) + // Determines whether there's another process (regardless of executable) + // left in the list of all processes. Returns true and sets entry_ to + // that process's info if there is one, false otherwise. + bool CheckForNextProcess(); + + bool IncludeEntry(); + + // Initializes a PROCESSENTRY32 data structure so that it's ready for + // use with Process32First/Process32Next. + void InitProcessEntry(ProcessEntry* entry); + + std::wstring executable_name_; +#endif + +#if defined(OS_WIN) + HANDLE snapshot_; + bool started_iteration_; +#elif defined(OS_LINUX) || defined(__GLIBC__) + DIR *procfs_dir_; +#elif defined(OS_BSD) + std::vector content; + size_t nextEntry; +#elif defined(OS_MACOSX) + std::vector kinfo_procs_; + size_t index_of_kinfo_proc_; +#endif +#if !defined(OS_BSD) || defined(__GLIBC__) + ProcessEntry entry_; + const ProcessFilter* filter_; +#endif + + DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator); +}; + +// Provides performance metrics for a specified process (CPU usage, memory and +// IO counters). To use it, invoke CreateProcessMetrics() to get an instance +// for a specific process, then access the information with the different get +// methods. +class ProcessMetrics { + public: + // Creates a ProcessMetrics for the specified process. + // The caller owns the returned object. + static ProcessMetrics* CreateProcessMetrics(ProcessHandle process); + + ~ProcessMetrics(); + + // Returns the CPU usage in percent since the last time this method was + // called. The first time this method is called it returns 0 and will return + // the actual CPU info on subsequent calls. + // Note that on multi-processor machines, the CPU usage value is for all + // CPUs. So if you have 2 CPUs and your process is using all the cycles + // of 1 CPU and not the other CPU, this method returns 50. + int GetCPUUsage(); + + private: + explicit ProcessMetrics(ProcessHandle process); + + ProcessHandle process_; + + int processor_count_; + + // Used to store the previous times so we can compute the CPU usage. + int64_t last_time_; + int64_t last_system_time_; + + DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics); +}; + +} // namespace base + +#if defined(OS_WIN) +// Undo the windows.h damage +#undef GetMessage +#undef CreateEvent +#undef GetClassName +#undef GetBinaryType +#endif + +#endif // BASE_PROCESS_UTIL_H_