summaryrefslogtreecommitdiffstats
path: root/ipc/chromium/src/base/process_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/chromium/src/base/process_util.h')
-rw-r--r--ipc/chromium/src/base/process_util.h321
1 files changed, 321 insertions, 0 deletions
diff --git a/ipc/chromium/src/base/process_util.h b/ipc/chromium/src/base/process_util.h
new file mode 100644
index 000000000..4df1f29fb
--- /dev/null
+++ b/ipc/chromium/src/base/process_util.h
@@ -0,0 +1,321 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+// 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 <windows.h>
+#include <tlhelp32.h>
+#include <io.h>
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#elif defined(OS_LINUX) || defined(__GLIBC__)
+#include <dirent.h>
+#include <limits.h>
+#include <sys/types.h>
+#elif defined(OS_MACOSX)
+#include <mach/mach.h>
+#endif
+
+#include <map>
+#include <string>
+#include <vector>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef OS_WIN
+#include <unistd.h>
+#endif
+
+#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,
+ PROCESS_ARCH_MIPS = 0x10,
+ PROCESS_ARCH_ARM64 = 0x20
+};
+
+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;
+#elif defined(ARCH_CPU_MIPS)
+ currentArchitecture = base::PROCESS_ARCH_MIPS;
+#elif defined(ARCH_CPU_ARM64)
+ currentArchitecture = base::PROCESS_ARCH_ARM64;
+#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<std::pair<int, int> > file_handle_mapping_vector;
+bool LaunchApp(const std::vector<std::string>& argv,
+ const file_handle_mapping_vector& fds_to_remap,
+ bool wait, ProcessHandle* process_handle);
+
+typedef std::map<std::string, std::string> environment_map;
+bool LaunchApp(const std::vector<std::string>& 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<std::string>& 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);
+
+// 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
+
+namespace mozilla {
+
+class EnvironmentLog
+{
+public:
+ explicit EnvironmentLog(const char* varname) {
+ const char *e = getenv(varname);
+ if (e && *e) {
+ fname_ = e;
+ }
+ }
+
+ ~EnvironmentLog() {}
+
+ void print(const char* format, ...) {
+ if (!fname_.size())
+ return;
+
+ FILE* f;
+ if (fname_.compare("-") == 0) {
+ f = fdopen(dup(STDOUT_FILENO), "a");
+ } else {
+ f = fopen(fname_.c_str(), "a");
+ }
+
+ if (!f)
+ return;
+
+ va_list a;
+ va_start(a, format);
+ vfprintf(f, format, a);
+ va_end(a);
+ fclose(f);
+ }
+
+private:
+ std::string fname_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(EnvironmentLog);
+};
+
+} // namespace mozilla
+
+#if defined(OS_WIN)
+// Undo the windows.h damage
+#undef GetMessage
+#undef CreateEvent
+#undef GetClassName
+#undef GetBinaryType
+#undef RemoveDirectory
+#endif
+
+#endif // BASE_PROCESS_UTIL_H_