ipc/chromium/src/base/process_util.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style license that can be
     3 // found in the LICENSE file.
     5 // This file/namespace contains utility functions for enumerating, ending and
     6 // computing statistics of processes.
     8 #ifndef BASE_PROCESS_UTIL_H_
     9 #define BASE_PROCESS_UTIL_H_
    11 #include "base/basictypes.h"
    13 #if defined(OS_WIN)
    14 #include <windows.h>
    15 #include <tlhelp32.h>
    16 #elif defined(OS_LINUX) || defined(__GLIBC__)
    17 #include <dirent.h>
    18 #include <limits.h>
    19 #include <sys/types.h>
    20 #elif defined(OS_MACOSX)
    21 #include <mach/mach.h>
    22 #endif
    24 #include <map>
    25 #include <string>
    26 #include <vector>
    28 #include "base/command_line.h"
    29 #include "base/process.h"
    31 #if defined(OS_WIN)
    32 typedef PROCESSENTRY32 ProcessEntry;
    33 typedef IO_COUNTERS IoCounters;
    34 #elif defined(OS_POSIX)
    35 // TODO(port): we should not rely on a Win32 structure.
    36 struct ProcessEntry {
    37   int pid;
    38   int ppid;
    39   char szExeFile[NAME_MAX + 1];
    40 };
    42 struct IoCounters {
    43   unsigned long long ReadOperationCount;
    44   unsigned long long WriteOperationCount;
    45   unsigned long long OtherOperationCount;
    46   unsigned long long ReadTransferCount;
    47   unsigned long long WriteTransferCount;
    48   unsigned long long OtherTransferCount;
    49 };
    51 #include "base/file_descriptor_shuffle.h"
    52 #endif
    54 #if defined(OS_MACOSX)
    55 struct kinfo_proc;
    56 #endif
    58 namespace base {
    60 // These can be used in a 32-bit bitmask.
    61 enum ProcessArchitecture {
    62   PROCESS_ARCH_I386 = 0x1,
    63   PROCESS_ARCH_X86_64 = 0x2,
    64   PROCESS_ARCH_PPC = 0x4,
    65   PROCESS_ARCH_ARM = 0x8
    66 };
    68 inline ProcessArchitecture GetCurrentProcessArchitecture()
    69 {
    70   base::ProcessArchitecture currentArchitecture;
    71 #if defined(ARCH_CPU_X86)
    72   currentArchitecture = base::PROCESS_ARCH_I386;
    73 #elif defined(ARCH_CPU_X86_64)
    74   currentArchitecture = base::PROCESS_ARCH_X86_64;
    75 #elif defined(ARCH_CPU_PPC)
    76   currentArchitecture = base::PROCESS_ARCH_PPC;
    77 #elif defined(ARCH_CPU_ARMEL)
    78   currentArchitecture = base::PROCESS_ARCH_ARM;
    79 #endif
    80   return currentArchitecture;
    81 }
    83 // A minimalistic but hopefully cross-platform set of exit codes.
    84 // Do not change the enumeration values or you will break third-party
    85 // installers.
    86 enum {
    87   PROCESS_END_NORMAL_TERMINATON = 0,
    88   PROCESS_END_KILLED_BY_USER    = 1,
    89   PROCESS_END_PROCESS_WAS_HUNG  = 2
    90 };
    92 // Returns the id of the current process.
    93 ProcessId GetCurrentProcId();
    95 // Returns the ProcessHandle of the current process.
    96 ProcessHandle GetCurrentProcessHandle();
    98 // Converts a PID to a process handle. This handle must be closed by
    99 // CloseProcessHandle when you are done with it. Returns true on success.
   100 bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
   102 // Converts a PID to a process handle. On Windows the handle is opened
   103 // with more access rights and must only be used by trusted code.
   104 // You have to close returned handle using CloseProcessHandle. Returns true
   105 // on success.
   106 bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
   108 // Closes the process handle opened by OpenProcessHandle.
   109 void CloseProcessHandle(ProcessHandle process);
   111 // Returns the unique ID for the specified process. This is functionally the
   112 // same as Windows' GetProcessId(), but works on versions of Windows before
   113 // Win XP SP1 as well.
   114 ProcessId GetProcId(ProcessHandle process);
   116 #if defined(OS_POSIX)
   117 // Sets all file descriptors to close on exec except for stdin, stdout
   118 // and stderr.
   119 // TODO(agl): remove this function
   120 // WARNING: do not use. It's inherently race-prone in the face of
   121 // multi-threading.
   122 void SetAllFDsToCloseOnExec();
   123 // Close all file descriptors, expect those which are a destination in the
   124 // given multimap. Only call this function in a child process where you know
   125 // that there aren't any other threads.
   126 void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map);
   127 #endif
   129 enum ChildPrivileges {
   130   PRIVILEGES_DEFAULT,
   131   PRIVILEGES_UNPRIVILEGED,
   132   PRIVILEGES_INHERIT,
   133   PRIVILEGES_LAST
   134 };
   136 #if defined(OS_WIN)
   137 // Runs the given application name with the given command line. Normally, the
   138 // first command line argument should be the path to the process, and don't
   139 // forget to quote it.
   140 //
   141 // If wait is true, it will block and wait for the other process to finish,
   142 // otherwise, it will just continue asynchronously.
   143 //
   144 // Example (including literal quotes)
   145 //  cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
   146 //
   147 // If process_handle is non-NULL, the process handle of the launched app will be
   148 // stored there on a successful launch.
   149 // NOTE: In this case, the caller is responsible for closing the handle so
   150 //       that it doesn't leak!
   151 bool LaunchApp(const std::wstring& cmdline,
   152                bool wait, bool start_hidden, ProcessHandle* process_handle);
   153 #elif defined(OS_POSIX)
   154 // Runs the application specified in argv[0] with the command line argv.
   155 // Before launching all FDs open in the parent process will be marked as
   156 // close-on-exec.  |fds_to_remap| defines a mapping of src fd->dest fd to
   157 // propagate FDs into the child process.
   158 //
   159 // As above, if wait is true, execute synchronously. The pid will be stored
   160 // in process_handle if that pointer is non-null.
   161 //
   162 // Note that the first argument in argv must point to the filename,
   163 // and must be fully specified.
   164 typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
   165 bool LaunchApp(const std::vector<std::string>& argv,
   166                const file_handle_mapping_vector& fds_to_remap,
   167                bool wait, ProcessHandle* process_handle);
   169 typedef std::map<std::string, std::string> environment_map;
   170 bool LaunchApp(const std::vector<std::string>& argv,
   171                const file_handle_mapping_vector& fds_to_remap,
   172                const environment_map& env_vars_to_set,
   173                ChildPrivileges privs,
   174                bool wait, ProcessHandle* process_handle,
   175                ProcessArchitecture arch=GetCurrentProcessArchitecture());
   176 bool LaunchApp(const std::vector<std::string>& argv,
   177                const file_handle_mapping_vector& fds_to_remap,
   178                const environment_map& env_vars_to_set,
   179                bool wait, ProcessHandle* process_handle,
   180                ProcessArchitecture arch=GetCurrentProcessArchitecture());
   181 #endif
   183 // Adjust the privileges of this process to match |privs|.  Only
   184 // returns if privileges were successfully adjusted.
   185 void SetCurrentProcessPrivileges(ChildPrivileges privs);
   187 // Executes the application specified by cl. This function delegates to one
   188 // of the above two platform-specific functions.
   189 bool LaunchApp(const CommandLine& cl,
   190                bool wait, bool start_hidden, ProcessHandle* process_handle);
   192 // Used to filter processes by process ID.
   193 class ProcessFilter {
   194  public:
   195   // Returns true to indicate set-inclusion and false otherwise.  This method
   196   // should not have side-effects and should be idempotent.
   197   virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0;
   198   virtual ~ProcessFilter() { }
   199 };
   201 // Attempts to kill the process identified by the given process
   202 // entry structure, giving it the specified exit code. If |wait| is true, wait
   203 // for the process to be actually terminated before returning.
   204 // Returns true if this is successful, false otherwise.
   205 bool KillProcess(ProcessHandle process, int exit_code, bool wait);
   207 // Get the termination status (exit code) of the process and return true if the
   208 // status indicates the process crashed. |child_exited| is set to true iff the
   209 // child process has terminated. (|child_exited| may be NULL.)
   210 //
   211 // On Windows, it is an error to call this if the process hasn't terminated
   212 // yet. On POSIX, |child_exited| is set correctly since we detect terminate in
   213 // a different manner on POSIX.
   214 bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
   216 // This class provides a way to iterate through the list of processes
   217 // on the current machine that were started from the given executable
   218 // name.  To use, create an instance and then call NextProcessEntry()
   219 // until it returns false.
   220 class NamedProcessIterator {
   221  public:
   222   NamedProcessIterator(const std::wstring& executable_name,
   223                        const ProcessFilter* filter);
   224   ~NamedProcessIterator();
   226   // If there's another process that matches the given executable name,
   227   // returns a const pointer to the corresponding PROCESSENTRY32.
   228   // If there are no more matching processes, returns NULL.
   229   // The returned pointer will remain valid until NextProcessEntry()
   230   // is called again or this NamedProcessIterator goes out of scope.
   231   const ProcessEntry* NextProcessEntry();
   233  private:
   234 #if !defined(OS_BSD) || defined(__GLIBC__)
   235   // Determines whether there's another process (regardless of executable)
   236   // left in the list of all processes.  Returns true and sets entry_ to
   237   // that process's info if there is one, false otherwise.
   238   bool CheckForNextProcess();
   240   bool IncludeEntry();
   242   // Initializes a PROCESSENTRY32 data structure so that it's ready for
   243   // use with Process32First/Process32Next.
   244   void InitProcessEntry(ProcessEntry* entry);
   246   std::wstring executable_name_;
   247 #endif
   249 #if defined(OS_WIN)
   250   HANDLE snapshot_;
   251   bool started_iteration_;
   252 #elif defined(OS_LINUX) || defined(__GLIBC__)
   253   DIR *procfs_dir_;
   254 #elif defined(OS_BSD)
   255   std::vector<ProcessEntry> content;
   256   size_t nextEntry;
   257 #elif defined(OS_MACOSX)
   258   std::vector<kinfo_proc> kinfo_procs_;
   259   size_t index_of_kinfo_proc_;
   260 #endif
   261 #if !defined(OS_BSD) || defined(__GLIBC__)
   262   ProcessEntry entry_;
   263   const ProcessFilter* filter_;
   264 #endif
   266   DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
   267 };
   269 // Provides performance metrics for a specified process (CPU usage, memory and
   270 // IO counters). To use it, invoke CreateProcessMetrics() to get an instance
   271 // for a specific process, then access the information with the different get
   272 // methods.
   273 class ProcessMetrics {
   274  public:
   275   // Creates a ProcessMetrics for the specified process.
   276   // The caller owns the returned object.
   277   static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
   279   ~ProcessMetrics();
   281   // Returns the CPU usage in percent since the last time this method was
   282   // called. The first time this method is called it returns 0 and will return
   283   // the actual CPU info on subsequent calls.
   284   // Note that on multi-processor machines, the CPU usage value is for all
   285   // CPUs. So if you have 2 CPUs and your process is using all the cycles
   286   // of 1 CPU and not the other CPU, this method returns 50.
   287   int GetCPUUsage();
   289  private:
   290   explicit ProcessMetrics(ProcessHandle process);
   292   ProcessHandle process_;
   294   int processor_count_;
   296   // Used to store the previous times so we can compute the CPU usage.
   297   int64_t last_time_;
   298   int64_t last_system_time_;
   300   DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
   301 };
   303 }  // namespace base
   305 #if defined(OS_WIN)
   306 // Undo the windows.h damage
   307 #undef GetMessage
   308 #undef CreateEvent
   309 #undef GetClassName
   310 #undef GetBinaryType
   311 #endif
   313 #endif  // BASE_PROCESS_UTIL_H_

mercurial