Wed, 31 Dec 2014 06:09:35 +0100
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_