ipc/chromium/src/base/process_util.h

changeset 0
6474c204b198
     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_

mercurial