Remove base/process Change-Id: I3fa5f6d059278cf8b0a17d475ac2e6ff881d09c0 Reviewed-on: https://gn-review.googlesource.com/1660 Reviewed-by: Brett Wilson <brettw@chromium.org> Commit-Queue: Scott Graham <scottmg@chromium.org>
diff --git a/base/files/file.cc b/base/files/file.cc index 8f779d5..8bc4fdb 100644 --- a/base/files/file.cc +++ b/base/files/file.cc
@@ -4,7 +4,6 @@ #include "base/files/file.h" #include "base/files/file_path.h" -#include "base/timer/elapsed_timer.h" #include "build_config.h" #if defined(OS_POSIX) || defined(OS_FUCHSIA)
diff --git a/base/files/file_util_win.cc b/base/files/file_util_win.cc index 48190ad..545dbc0 100644 --- a/base/files/file_util_win.cc +++ b/base/files/file_util_win.cc
@@ -23,7 +23,6 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/macros.h" -#include "base/process/process_handle.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -506,7 +505,7 @@ // the one exists, keep trying another path name until we reach some limit. string16 new_dir_name; new_dir_name.assign(prefix); - new_dir_name.append(IntToString16(GetCurrentProcId())); + new_dir_name.append(IntToString16(::GetCurrentProcessId())); new_dir_name.push_back('_'); new_dir_name.append(UTF8ToUTF16(GenerateGUID()));
diff --git a/base/process/internal_linux.cc b/base/process/internal_linux.cc deleted file mode 100644 index 6c2cafa..0000000 --- a/base/process/internal_linux.cc +++ /dev/null
@@ -1,220 +0,0 @@ -// Copyright (c) 2012 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. - -#include "base/process/internal_linux.h" - -#include <limits.h> -#include <unistd.h> - -#include <map> -#include <string> -#include <vector> - -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/time/time.h" - -namespace base { -namespace internal { - -const char kProcDir[] = "/proc"; - -const char kStatFile[] = "stat"; - -FilePath GetProcPidDir(pid_t pid) { - return FilePath(kProcDir).Append(IntToString(pid)); -} - -pid_t ProcDirSlotToPid(const char* d_name) { - int i; - for (i = 0; i < NAME_MAX && d_name[i]; ++i) { - if (!IsAsciiDigit(d_name[i])) { - return 0; - } - } - if (i == NAME_MAX) - return 0; - - // Read the process's command line. - pid_t pid; - std::string pid_string(d_name); - if (!StringToInt(pid_string, &pid)) { - NOTREACHED(); - return 0; - } - return pid; -} - -bool ReadProcFile(const FilePath& file, std::string* buffer) { - buffer->clear(); - if (!ReadFileToString(file, buffer)) { - DLOG(WARNING) << "Failed to read " << file.MaybeAsASCII(); - return false; - } - return !buffer->empty(); -} - -bool ReadProcStats(pid_t pid, std::string* buffer) { - FilePath stat_file = internal::GetProcPidDir(pid).Append(kStatFile); - return ReadProcFile(stat_file, buffer); -} - -bool ParseProcStats(const std::string& stats_data, - std::vector<std::string>* proc_stats) { - // |stats_data| may be empty if the process disappeared somehow. - // e.g. http://crbug.com/145811 - if (stats_data.empty()) - return false; - - // The stat file is formatted as: - // pid (process name) data1 data2 .... dataN - // Look for the closing paren by scanning backwards, to avoid being fooled by - // processes with ')' in the name. - size_t open_parens_idx = stats_data.find(" ("); - size_t close_parens_idx = stats_data.rfind(") "); - if (open_parens_idx == std::string::npos || - close_parens_idx == std::string::npos || - open_parens_idx > close_parens_idx) { - DLOG(WARNING) << "Failed to find matched parens in '" << stats_data << "'"; - NOTREACHED(); - return false; - } - open_parens_idx++; - - proc_stats->clear(); - // PID. - proc_stats->push_back(stats_data.substr(0, open_parens_idx)); - // Process name without parentheses. - proc_stats->push_back(stats_data.substr( - open_parens_idx + 1, close_parens_idx - (open_parens_idx + 1))); - - // Split the rest. - std::vector<std::string> other_stats = - SplitString(stats_data.substr(close_parens_idx + 2), " ", - base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - for (size_t i = 0; i < other_stats.size(); ++i) - proc_stats->push_back(other_stats[i]); - return true; -} - -typedef std::map<std::string, std::string> ProcStatMap; -void ParseProcStat(const std::string& contents, ProcStatMap* output) { - StringPairs key_value_pairs; - SplitStringIntoKeyValuePairs(contents, ' ', '\n', &key_value_pairs); - for (size_t i = 0; i < key_value_pairs.size(); ++i) { - output->insert(key_value_pairs[i]); - } -} - -int64_t GetProcStatsFieldAsInt64(const std::vector<std::string>& proc_stats, - ProcStatsFields field_num) { - DCHECK_GE(field_num, VM_PPID); - CHECK_LT(static_cast<size_t>(field_num), proc_stats.size()); - - int64_t value; - return StringToInt64(proc_stats[field_num], &value) ? value : 0; -} - -size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats, - ProcStatsFields field_num) { - DCHECK_GE(field_num, VM_PPID); - CHECK_LT(static_cast<size_t>(field_num), proc_stats.size()); - - size_t value; - return StringToSizeT(proc_stats[field_num], &value) ? value : 0; -} - -int64_t ReadStatFileAndGetFieldAsInt64(const FilePath& stat_file, - ProcStatsFields field_num) { - std::string stats_data; - if (!ReadProcFile(stat_file, &stats_data)) - return 0; - std::vector<std::string> proc_stats; - if (!ParseProcStats(stats_data, &proc_stats)) - return 0; - return GetProcStatsFieldAsInt64(proc_stats, field_num); -} - -int64_t ReadProcStatsAndGetFieldAsInt64(pid_t pid, ProcStatsFields field_num) { - FilePath stat_file = internal::GetProcPidDir(pid).Append(kStatFile); - return ReadStatFileAndGetFieldAsInt64(stat_file, field_num); -} - -int64_t ReadProcSelfStatsAndGetFieldAsInt64(ProcStatsFields field_num) { - FilePath stat_file = FilePath(kProcDir).Append("self").Append(kStatFile); - return ReadStatFileAndGetFieldAsInt64(stat_file, field_num); -} - -size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid, ProcStatsFields field_num) { - std::string stats_data; - if (!ReadProcStats(pid, &stats_data)) - return 0; - std::vector<std::string> proc_stats; - if (!ParseProcStats(stats_data, &proc_stats)) - return 0; - return GetProcStatsFieldAsSizeT(proc_stats, field_num); -} - -Time GetBootTime() { - FilePath path("/proc/stat"); - std::string contents; - if (!ReadProcFile(path, &contents)) - return Time(); - ProcStatMap proc_stat; - ParseProcStat(contents, &proc_stat); - ProcStatMap::const_iterator btime_it = proc_stat.find("btime"); - if (btime_it == proc_stat.end()) - return Time(); - int btime; - if (!StringToInt(btime_it->second, &btime)) - return Time(); - return Time::FromTimeT(btime); -} - -TimeDelta GetUserCpuTimeSinceBoot() { - FilePath path("/proc/stat"); - std::string contents; - if (!ReadProcFile(path, &contents)) - return TimeDelta(); - - ProcStatMap proc_stat; - ParseProcStat(contents, &proc_stat); - ProcStatMap::const_iterator cpu_it = proc_stat.find("cpu"); - if (cpu_it == proc_stat.end()) - return TimeDelta(); - - std::vector<std::string> cpu = SplitString( - cpu_it->second, kWhitespaceASCII, TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); - - if (cpu.size() < 2 || cpu[0] != "cpu") - return TimeDelta(); - - uint64_t user; - uint64_t nice; - if (!StringToUint64(cpu[0], &user) || !StringToUint64(cpu[1], &nice)) - return TimeDelta(); - - return ClockTicksToTimeDelta(user + nice); -} - -TimeDelta ClockTicksToTimeDelta(int clock_ticks) { - // This queries the /proc-specific scaling factor which is - // conceptually the system hertz. To dump this value on another - // system, try - // od -t dL /proc/self/auxv - // and look for the number after 17 in the output; mine is - // 0000040 17 100 3 134512692 - // which means the answer is 100. - // It may be the case that this value is always 100. - static const int kHertz = sysconf(_SC_CLK_TCK); - - return TimeDelta::FromMicroseconds(Time::kMicrosecondsPerSecond * - clock_ticks / kHertz); -} - -} // namespace internal -} // namespace base
diff --git a/base/process/internal_linux.h b/base/process/internal_linux.h deleted file mode 100644 index 56c08e6..0000000 --- a/base/process/internal_linux.h +++ /dev/null
@@ -1,99 +0,0 @@ -// Copyright (c) 2013 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 contains internal routines that are called by other files in -// base/process/. - -#ifndef BASE_PROCESS_INTERNAL_LINUX_H_ -#define BASE_PROCESS_INTERNAL_LINUX_H_ - -#include <stddef.h> -#include <stdint.h> -#include <unistd.h> - -#include "base/files/file_path.h" - -namespace base { - -class Time; -class TimeDelta; - -namespace internal { - -// "/proc" -extern const char kProcDir[]; - -// "stat" -extern const char kStatFile[]; - -// Returns a FilePath to "/proc/pid". -base::FilePath GetProcPidDir(pid_t pid); - -// Take a /proc directory entry named |d_name|, and if it is the directory for -// a process, convert it to a pid_t. -// Returns 0 on failure. -// e.g. /proc/self/ will return 0, whereas /proc/1234 will return 1234. -pid_t ProcDirSlotToPid(const char* d_name); - -// Reads /proc/<pid>/stat into |buffer|. Returns true if the file can be read -// and is non-empty. -bool ReadProcStats(pid_t pid, std::string* buffer); - -// Takes |stats_data| and populates |proc_stats| with the values split by -// spaces. Taking into account the 2nd field may, in itself, contain spaces. -// Returns true if successful. -bool ParseProcStats(const std::string& stats_data, - std::vector<std::string>* proc_stats); - -// Fields from /proc/<pid>/stat, 0-based. See man 5 proc. -// If the ordering ever changes, carefully review functions that use these -// values. -enum ProcStatsFields { - VM_COMM = 1, // Filename of executable, without parentheses. - VM_STATE = 2, // Letter indicating the state of the process. - VM_PPID = 3, // PID of the parent. - VM_PGRP = 4, // Process group id. - VM_MINFLT = 9, // Minor page fault count excluding children. - VM_MAJFLT = 11, // Major page fault count excluding children. - VM_UTIME = 13, // Time scheduled in user mode in clock ticks. - VM_STIME = 14, // Time scheduled in kernel mode in clock ticks. - VM_NUMTHREADS = 19, // Number of threads. - VM_STARTTIME = 21, // The time the process started in clock ticks. - VM_VSIZE = 22, // Virtual memory size in bytes. - VM_RSS = 23, // Resident Set Size in pages. -}; - -// Reads the |field_num|th field from |proc_stats|. Returns 0 on failure. -// This version does not handle the first 3 values, since the first value is -// simply |pid|, and the next two values are strings. -int64_t GetProcStatsFieldAsInt64(const std::vector<std::string>& proc_stats, - ProcStatsFields field_num); - -// Same as GetProcStatsFieldAsInt64(), but for size_t values. -size_t GetProcStatsFieldAsSizeT(const std::vector<std::string>& proc_stats, - ProcStatsFields field_num); - -// Convenience wrappers around GetProcStatsFieldAsInt64(), ParseProcStats() and -// ReadProcStats(). See GetProcStatsFieldAsInt64() for details. -int64_t ReadStatsFilendGetFieldAsInt64(const FilePath& stat_file, - ProcStatsFields field_num); -int64_t ReadProcStatsAndGetFieldAsInt64(pid_t pid, ProcStatsFields field_num); -int64_t ReadProcSelfStatsAndGetFieldAsInt64(ProcStatsFields field_num); - -// Same as ReadProcStatsAndGetFieldAsInt64() but for size_t values. -size_t ReadProcStatsAndGetFieldAsSizeT(pid_t pid, ProcStatsFields field_num); - -// Returns the time that the OS started. Clock ticks are relative to this. -Time GetBootTime(); - -// Returns the amount of time spent in user space since boot across all CPUs. -TimeDelta GetUserCpuTimeSinceBoot(); - -// Converts Linux clock ticks to a wall time delta. -TimeDelta ClockTicksToTimeDelta(int clock_ticks); - -} // namespace internal -} // namespace base - -#endif // BASE_PROCESS_INTERNAL_LINUX_H_
diff --git a/base/process/kill.cc b/base/process/kill.cc deleted file mode 100644 index f73266d..0000000 --- a/base/process/kill.cc +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/kill.h" - -#include "base/bind.h" -#include "base/process/process_iterator.h" -#include "base/time/time.h" - -namespace base { - -bool KillProcesses(const FilePath::StringType& executable_name, - int exit_code, - const ProcessFilter* filter) { - bool result = true; - NamedProcessIterator iter(executable_name, filter); - while (const ProcessEntry* entry = iter.NextProcessEntry()) { - Process process = Process::Open(entry->pid()); - // Sometimes process open fails. This would cause a DCHECK in - // process.Terminate(). Maybe the process has killed itself between the - // time the process list was enumerated and the time we try to open the - // process? - if (!process.IsValid()) { - result = false; - continue; - } - result &= process.Terminate(exit_code, true); - } - return result; -} - -} // namespace base
diff --git a/base/process/kill.h b/base/process/kill.h deleted file mode 100644 index 89ab97b..0000000 --- a/base/process/kill.h +++ /dev/null
@@ -1,134 +0,0 @@ -// Copyright (c) 2013 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 contains routines to kill processes and get the exit code and -// termination status. - -#ifndef BASE_PROCESS_KILL_H_ -#define BASE_PROCESS_KILL_H_ - -#include "base/files/file_path.h" -#include "base/process/process.h" -#include "base/process/process_handle.h" -#include "base/time/time.h" -#include "build_config.h" - -namespace base { - -class ProcessFilter; - -#if defined(OS_WIN) -namespace win { - -// See definition in sandbox/win/src/sandbox_types.h -const DWORD kSandboxFatalMemoryExceeded = 7012; - -// Exit codes with special meanings on Windows. -const DWORD kNormalTerminationExitCode = 0; -const DWORD kDebuggerInactiveExitCode = 0xC0000354; -const DWORD kKeyboardInterruptExitCode = 0xC000013A; -const DWORD kDebuggerTerminatedExitCode = 0x40010004; - -// This exit code is used by the Windows task manager when it kills a -// process. It's value is obviously not that unique, and it's -// surprising to me that the task manager uses this value, but it -// seems to be common practice on Windows to test for it as an -// indication that the task manager has killed something if the -// process goes away. -const DWORD kProcessKilledExitCode = 1; - -} // namespace win - -#endif // OS_WIN - -// Return status values from GetTerminationStatus. Don't use these as -// exit code arguments to KillProcess*(), use platform/application -// specific values instead. -enum TerminationStatus { - TERMINATION_STATUS_NORMAL_TERMINATION, // zero exit status - TERMINATION_STATUS_ABNORMAL_TERMINATION, // non-zero exit status - TERMINATION_STATUS_PROCESS_WAS_KILLED, // e.g. SIGKILL or task manager kill - TERMINATION_STATUS_PROCESS_CRASHED, // e.g. Segmentation fault - TERMINATION_STATUS_STILL_RUNNING, // child hasn't exited yet - TERMINATION_STATUS_LAUNCH_FAILED, // child process never launched - TERMINATION_STATUS_OOM, // Process died due to oom - TERMINATION_STATUS_MAX_ENUM -}; - -// Attempts to kill all the processes on the current machine that were launched -// from the given executable name, ending them with the given exit code. If -// filter is non-null, then only processes selected by the filter are killed. -// Returns true if all processes were able to be killed off, false if at least -// one couldn't be killed. -bool KillProcesses(const FilePath::StringType& executable_name, - int exit_code, - const ProcessFilter* filter); - -#if defined(OS_POSIX) -// Attempts to kill the process group identified by |process_group_id|. Returns -// true on success. -bool KillProcessGroup(ProcessHandle process_group_id); -#endif // defined(OS_POSIX) - -// Get the termination status of the process by interpreting the -// circumstances of the child process' death. |exit_code| is set to -// the status returned by waitpid() on POSIX, and from GetExitCodeProcess() on -// Windows, and may not be null. Note that on Linux, this function -// will only return a useful result the first time it is called after -// the child exits (because it will reap the child and the information -// will no longer be available). -TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code); - -#if defined(OS_POSIX) && !defined(OS_FUCHSIA) -// Send a kill signal to the process and then wait for the process to exit -// and get the termination status. -// -// This is used in situations where it is believed that the process is dead -// or dying (because communication with the child process has been cut). -// In order to avoid erroneously returning that the process is still running -// because the kernel is still cleaning it up, this will wait for the process -// to terminate. In order to avoid the risk of hanging while waiting for the -// process to terminate, send a SIGKILL to the process before waiting for the -// termination status. -// -// Note that it is not an option to call WaitForExitCode and then -// GetTerminationStatus as the child will be reaped when WaitForExitCode -// returns, and this information will be lost. -// -TerminationStatus GetKnownDeadTerminationStatus(ProcessHandle handle, - int* exit_code); - -#if defined(OS_LINUX) -// Spawns a thread to wait asynchronously for the child |process| to exit -// and then reaps it. -void EnsureProcessGetsReaped(Process process); -#endif // defined(OS_LINUX) -#endif // defined(OS_POSIX) && !defined(OS_FUCHSIA) - -// These are only sparingly used, and not needed on Fuchsia. They could be -// implemented if necessary. -#if !defined(OS_FUCHSIA) -// Wait for all the processes based on the named executable to exit. If filter -// is non-null, then only processes selected by the filter are waited on. -// Returns after all processes have exited or wait_milliseconds have expired. -// Returns true if all the processes exited, false otherwise. -bool WaitForProcessesToExit(const FilePath::StringType& executable_name, - base::TimeDelta wait, - const ProcessFilter* filter); - -// Waits a certain amount of time (can be 0) for all the processes with a given -// executable name to exit, then kills off any of them that are still around. -// If filter is non-null, then only processes selected by the filter are waited -// on. Killed processes are ended with the given exit code. Returns false if -// any processes needed to be killed, true if they all exited cleanly within -// the wait_milliseconds delay. -bool CleanupProcesses(const FilePath::StringType& executable_name, - base::TimeDelta wait, - int exit_code, - const ProcessFilter* filter); -#endif // !defined(OS_FUCHSIA) - -} // namespace base - -#endif // BASE_PROCESS_KILL_H_
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc deleted file mode 100644 index 0e4e84d..0000000 --- a/base/process/kill_posix.cc +++ /dev/null
@@ -1,179 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/kill.h" - -#include <errno.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/process_iterator.h" -#include "base/threading/platform_thread.h" -#include "build_config.h" - -namespace base { - -namespace { - -TerminationStatus GetTerminationStatusImpl(ProcessHandle handle, - bool can_block, - int* exit_code) { - DCHECK(exit_code); - - int status = 0; - const pid_t result = - HANDLE_EINTR(waitpid(handle, &status, can_block ? 0 : WNOHANG)); - if (result == -1) { - DPLOG(ERROR) << "waitpid(" << handle << ")"; - *exit_code = 0; - return TERMINATION_STATUS_NORMAL_TERMINATION; - } else if (result == 0) { - // the child hasn't exited yet. - *exit_code = 0; - return TERMINATION_STATUS_STILL_RUNNING; - } - - *exit_code = status; - - if (WIFSIGNALED(status)) { - switch (WTERMSIG(status)) { - case SIGABRT: - case SIGBUS: - case SIGFPE: - case SIGILL: - case SIGSEGV: - case SIGTRAP: - case SIGSYS: - return TERMINATION_STATUS_PROCESS_CRASHED; - case SIGKILL: - case SIGINT: - case SIGTERM: - return TERMINATION_STATUS_PROCESS_WAS_KILLED; - default: - break; - } - } - - if (WIFEXITED(status) && WEXITSTATUS(status) != 0) - return TERMINATION_STATUS_ABNORMAL_TERMINATION; - - return TERMINATION_STATUS_NORMAL_TERMINATION; -} - -} // namespace - -#if !defined(OS_NACL_NONSFI) -bool KillProcessGroup(ProcessHandle process_group_id) { - bool result = kill(-1 * process_group_id, SIGKILL) == 0; - if (!result) - DPLOG(ERROR) << "Unable to terminate process group " << process_group_id; - return result; -} -#endif // !defined(OS_NACL_NONSFI) - -TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { - return GetTerminationStatusImpl(handle, false /* can_block */, exit_code); -} - -TerminationStatus GetKnownDeadTerminationStatus(ProcessHandle handle, - int* exit_code) { - bool result = kill(handle, SIGKILL) == 0; - - if (!result) - DPLOG(ERROR) << "Unable to terminate process " << handle; - - return GetTerminationStatusImpl(handle, true /* can_block */, exit_code); -} - -#if !defined(OS_NACL_NONSFI) -bool WaitForProcessesToExit(const FilePath::StringType& executable_name, - TimeDelta wait, - const ProcessFilter* filter) { - bool result = false; - - // TODO(port): This is inefficient, but works if there are multiple procs. - // TODO(port): use waitpid to avoid leaving zombies around - - TimeTicks end_time = TimeTicks::Now() + wait; - do { - NamedProcessIterator iter(executable_name, filter); - if (!iter.NextProcessEntry()) { - result = true; - break; - } - PlatformThread::Sleep(TimeDelta::FromMilliseconds(100)); - } while ((end_time - TimeTicks::Now()) > TimeDelta()); - - return result; -} - -bool CleanupProcesses(const FilePath::StringType& executable_name, - TimeDelta wait, - int exit_code, - const ProcessFilter* filter) { - bool exited_cleanly = WaitForProcessesToExit(executable_name, wait, filter); - if (!exited_cleanly) - KillProcesses(executable_name, exit_code, filter); - return exited_cleanly; -} - -#if !defined(OS_MACOSX) - -namespace { - -class BackgroundReaper : public PlatformThread::Delegate { - public: - BackgroundReaper(base::Process child_process, const TimeDelta& wait_time) - : child_process_(std::move(child_process)), wait_time_(wait_time) {} - - void ThreadMain() override { - if (!wait_time_.is_zero()) { - child_process_.WaitForExitWithTimeout(wait_time_, nullptr); - kill(child_process_.Handle(), SIGKILL); - } - child_process_.WaitForExit(nullptr); - delete this; - } - - private: - Process child_process_; - const TimeDelta wait_time_; - DISALLOW_COPY_AND_ASSIGN(BackgroundReaper); -}; - -} // namespace - -void EnsureProcessTerminated(Process process) { - DCHECK(!process.is_current()); - - if (process.WaitForExitWithTimeout(TimeDelta(), nullptr)) - return; - - PlatformThread::CreateNonJoinable( - 0, new BackgroundReaper(std::move(process), TimeDelta::FromSeconds(2))); -} - -#if defined(OS_LINUX) -void EnsureProcessGetsReaped(Process process) { - DCHECK(!process.is_current()); - - // If the child is already dead, then there's nothing to do. - if (process.WaitForExitWithTimeout(TimeDelta(), nullptr)) - return; - - PlatformThread::CreateNonJoinable( - 0, new BackgroundReaper(std::move(process), TimeDelta())); -} -#endif // defined(OS_LINUX) - -#endif // !defined(OS_MACOSX) -#endif // !defined(OS_NACL_NONSFI) - -} // namespace base
diff --git a/base/process/kill_win.cc b/base/process/kill_win.cc deleted file mode 100644 index f598c13..0000000 --- a/base/process/kill_win.cc +++ /dev/null
@@ -1,114 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/kill.h" - -#include <algorithm> - -#include <io.h> -#include <stdint.h> -#include <windows.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/process/memory.h" -#include "base/process/process_iterator.h" - -namespace base { - -TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { - DCHECK(exit_code); - - DWORD tmp_exit_code = 0; - - if (!::GetExitCodeProcess(handle, &tmp_exit_code)) { - DPLOG(FATAL) << "GetExitCodeProcess() failed"; - - // This really is a random number. We haven't received any - // information about the exit code, presumably because this - // process doesn't have permission to get the exit code, or - // because of some other cause for GetExitCodeProcess to fail - // (MSDN docs don't give the possible failure error codes for - // this function, so it could be anything). But we don't want - // to leave exit_code uninitialized, since that could cause - // random interpretations of the exit code. So we assume it - // terminated "normally" in this case. - *exit_code = win::kNormalTerminationExitCode; - - // Assume the child has exited normally if we can't get the exit - // code. - return TERMINATION_STATUS_NORMAL_TERMINATION; - } - if (tmp_exit_code == STILL_ACTIVE) { - DWORD wait_result = WaitForSingleObject(handle, 0); - if (wait_result == WAIT_TIMEOUT) { - *exit_code = wait_result; - return TERMINATION_STATUS_STILL_RUNNING; - } - - if (wait_result == WAIT_FAILED) { - DPLOG(ERROR) << "WaitForSingleObject() failed"; - } else { - DCHECK_EQ(WAIT_OBJECT_0, wait_result); - - // Strange, the process used 0x103 (STILL_ACTIVE) as exit code. - NOTREACHED(); - } - - return TERMINATION_STATUS_ABNORMAL_TERMINATION; - } - - *exit_code = tmp_exit_code; - - switch (tmp_exit_code) { - case win::kNormalTerminationExitCode: - return TERMINATION_STATUS_NORMAL_TERMINATION; - case win::kDebuggerInactiveExitCode: // STATUS_DEBUGGER_INACTIVE. - case win::kKeyboardInterruptExitCode: // Control-C/end session. - case win::kDebuggerTerminatedExitCode: // Debugger terminated process. - case win::kProcessKilledExitCode: // Task manager kill. - return TERMINATION_STATUS_PROCESS_WAS_KILLED; - case win::kSandboxFatalMemoryExceeded: // Terminated process due to - // exceeding the sandbox job - // object memory limits. - case win::kOomExceptionCode: // Ran out of memory. - return TERMINATION_STATUS_OOM; - default: - // All other exit codes indicate crashes. - return TERMINATION_STATUS_PROCESS_CRASHED; - } -} - -bool WaitForProcessesToExit(const FilePath::StringType& executable_name, - TimeDelta wait, - const ProcessFilter* filter) { - bool result = true; - DWORD start_time = GetTickCount(); - - NamedProcessIterator iter(executable_name, filter); - for (const ProcessEntry* entry = iter.NextProcessEntry(); entry; - entry = iter.NextProcessEntry()) { - DWORD remaining_wait = static_cast<DWORD>( - std::max(static_cast<int64_t>(0), - wait.InMilliseconds() - (GetTickCount() - start_time))); - HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, entry->th32ProcessID); - DWORD wait_result = WaitForSingleObject(process, remaining_wait); - CloseHandle(process); - result &= (wait_result == WAIT_OBJECT_0); - } - - return result; -} - -bool CleanupProcesses(const FilePath::StringType& executable_name, - TimeDelta wait, - int exit_code, - const ProcessFilter* filter) { - if (WaitForProcessesToExit(executable_name, wait, filter)) - return true; - KillProcesses(executable_name, exit_code, filter); - return false; -} - -} // namespace base
diff --git a/base/process/memory.cc b/base/process/memory.cc deleted file mode 100644 index 2e87fea..0000000 --- a/base/process/memory.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2014 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. - -#include "base/process/memory.h" -#include "base/logging.h" -#include "build_config.h" - -namespace base { - -// Defined in memory_win.cc for Windows. -#if !defined(OS_WIN) - -namespace { - -// Breakpad server classifies base::`anonymous namespace'::OnNoMemory as -// out-of-memory crash. -NOINLINE void OnNoMemory(size_t size) { - LOG(FATAL) << "Out of memory. size=" << size; -} - -} // namespace - -void TerminateBecauseOutOfMemory(size_t size) { - OnNoMemory(size); -} - -#endif - -// Defined in memory_mac.mm for Mac. -#if !defined(OS_MACOSX) - -bool UncheckedCalloc(size_t num_items, size_t size, void** result) { - const size_t alloc_size = num_items * size; - - // Overflow check - if (size && ((alloc_size / size) != num_items)) { - *result = nullptr; - return false; - } - - if (!UncheckedMalloc(alloc_size, result)) - return false; - - memset(*result, 0, alloc_size); - return true; -} - -#endif - -} // namespace base
diff --git a/base/process/memory.h b/base/process/memory.h deleted file mode 100644 index bbcff68..0000000 --- a/base/process/memory.h +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright (c) 2013 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. - -#ifndef BASE_PROCESS_MEMORY_H_ -#define BASE_PROCESS_MEMORY_H_ - -#include <stddef.h> - -#include "base/process/process_handle.h" -#include "build_config.h" - -#ifdef PVALLOC_AVAILABLE -// Build config explicitly tells us whether or not pvalloc is available. -#elif defined(LIBC_GLIBC) && !defined(USE_TCMALLOC) -#define PVALLOC_AVAILABLE 1 -#else -#define PVALLOC_AVAILABLE 0 -#endif - -namespace base { - -// Enables 'terminate on heap corruption' flag. Helps protect against heap -// overflow. Has no effect if the OS doesn't provide the necessary facility. -void EnableTerminationOnHeapCorruption(); - -// Turns on process termination if memory runs out. -void EnableTerminationOnOutOfMemory(); - -// Terminates process. Should be called only for out of memory errors. -// Crash reporting classifies such crashes as OOM. -void TerminateBecauseOutOfMemory(size_t size); - -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) -extern size_t g_oom_size; - -// The maximum allowed value for the OOM score. -const int kMaxOomScore = 1000; - -// This adjusts /proc/<pid>/oom_score_adj so the Linux OOM killer will -// prefer to kill certain process types over others. The range for the -// adjustment is [-1000, 1000], with [0, 1000] being user accessible. -// If the Linux system doesn't support the newer oom_score_adj range -// of [0, 1000], then we revert to using the older oom_adj, and -// translate the given value into [0, 15]. Some aliasing of values -// may occur in that case, of course. -bool AdjustOOMScore(ProcessId process, int score); -#endif - -#if defined(OS_WIN) -namespace win { - -// Custom Windows exception code chosen to indicate an out of memory error. -// See https://msdn.microsoft.com/en-us/library/het71c37.aspx. -// "To make sure that you do not define a code that conflicts with an existing -// exception code" ... "The resulting error code should therefore have the -// highest four bits set to hexadecimal E." -// 0xe0000008 was chosen arbitrarily, as 0x00000008 is ERROR_NOT_ENOUGH_MEMORY. -const DWORD kOomExceptionCode = 0xe0000008; - -} // namespace win -#endif - -// Special allocator functions for callers that want to check for OOM. -// These will not abort if the allocation fails even if -// EnableTerminationOnOutOfMemory has been called. -// This can be useful for huge and/or unpredictable size memory allocations. -// Please only use this if you really handle the case when the allocation -// fails. Doing otherwise would risk security. -// These functions may still crash on OOM when running under memory tools, -// specifically ASan and other sanitizers. -// Return value tells whether the allocation succeeded. If it fails |result| is -// set to NULL, otherwise it holds the memory address. -WARN_UNUSED_RESULT bool UncheckedMalloc(size_t size, void** result); -WARN_UNUSED_RESULT bool UncheckedCalloc(size_t num_items, - size_t size, - void** result); - -} // namespace base - -#endif // BASE_PROCESS_MEMORY_H_
diff --git a/base/process/memory_linux.cc b/base/process/memory_linux.cc deleted file mode 100644 index 9c75b78..0000000 --- a/base/process/memory_linux.cc +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/memory.h" - -#include <stddef.h> - -#include <new> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/process/internal_linux.h" -#include "base/strings/string_number_conversions.h" -#include "build_config.h" - -namespace base { - -size_t g_oom_size = 0U; - -namespace { - -void OnNoMemorySize(size_t size) { - g_oom_size = size; - - if (size != 0) - LOG(FATAL) << "Out of memory, size = " << size; - LOG(FATAL) << "Out of memory."; -} - -void OnNoMemory() { - OnNoMemorySize(0); -} - -} // namespace - -void EnableTerminationOnHeapCorruption() { - // On Linux, there nothing to do AFAIK. -} - -void EnableTerminationOnOutOfMemory() { - // Set the new-out of memory handler. - std::set_new_handler(&OnNoMemory); - // If we're using glibc's allocator, the above functions will override - // malloc and friends and make them die on out of memory. -} - -// NOTE: This is not the only version of this function in the source: -// the setuid sandbox (in process_util_linux.c, in the sandbox source) -// also has its own C version. -bool AdjustOOMScore(ProcessId process, int score) { - if (score < 0 || score > kMaxOomScore) - return false; - - FilePath oom_path(internal::GetProcPidDir(process)); - - // Attempt to write the newer oom_score_adj file first. - FilePath oom_file = oom_path.AppendASCII("oom_score_adj"); - if (PathExists(oom_file)) { - std::string score_str = IntToString(score); - int score_len = static_cast<int>(score_str.length()); - return (score_len == WriteFile(oom_file, score_str.c_str(), score_len)); - } - - // If the oom_score_adj file doesn't exist, then we write the old - // style file and translate the oom_adj score to the range 0-15. - oom_file = oom_path.AppendASCII("oom_adj"); - if (PathExists(oom_file)) { - // Max score for the old oom_adj range. Used for conversion of new - // values to old values. - const int kMaxOldOomScore = 15; - - int converted_score = score * kMaxOldOomScore / kMaxOomScore; - std::string score_str = IntToString(converted_score); - int score_len = static_cast<int>(score_str.length()); - return (score_len == WriteFile(oom_file, score_str.c_str(), score_len)); - } - - return false; -} - -bool UncheckedMalloc(size_t size, void** result) { - *result = malloc(size); - return *result != nullptr; -} - -} // namespace base
diff --git a/base/process/memory_mac.mm b/base/process/memory_mac.mm deleted file mode 100644 index 4fa31a1..0000000 --- a/base/process/memory_mac.mm +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/memory.h" - -#include "build_config.h" - -namespace base { - -namespace { -void oom_killer_new() { - TerminateBecauseOutOfMemory(0); -} -} // namespace - -void EnableTerminationOnHeapCorruption() { -#if !ARCH_CPU_64_BITS - DLOG(WARNING) << "EnableTerminationOnHeapCorruption only works on 64-bit"; -#endif -} - -bool UncheckedMalloc(size_t size, void** result) { - *result = malloc(size); - return *result != nullptr; -} - -bool UncheckedCalloc(size_t num_items, size_t size, void** result) { - *result = calloc(num_items, size); - return *result != nullptr; -} - -void EnableTerminationOnOutOfMemory() { - // Step 1: Enable OOM killer on C++ failures. - std::set_new_handler(oom_killer_new); - - // Step 2: Enable OOM killer on all other malloc zones (or just "all" without - // "other" if shim is disabled). - allocator::InterceptAllocationsMac(); -} - -} // namespace base
diff --git a/base/process/memory_stubs.cc b/base/process/memory_stubs.cc deleted file mode 100644 index df4657f..0000000 --- a/base/process/memory_stubs.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/memory.h" - -#include <stddef.h> -#include <stdlib.h> - -namespace base { - -void EnableTerminationOnOutOfMemory() {} - -void EnableTerminationOnHeapCorruption() {} - -bool AdjustOOMScore(ProcessId process, int score) { - return false; -} - -void TerminateBecauseOutOfMemory(size_t size) { - abort(); -} - -// UncheckedMalloc and Calloc exist so that platforms making use of -// EnableTerminationOnOutOfMemory have a way to allocate memory without -// crashing. This _stubs.cc file is for platforms that do not support -// EnableTerminationOnOutOfMemory (note the empty implementation above). As -// such, these two Unchecked.alloc functions need only trivially pass-through to -// their respective stdlib function since those functions will return null on a -// failure to allocate. - -bool UncheckedMalloc(size_t size, void** result) { - *result = malloc(size); - return *result != nullptr; -} - -bool UncheckedCalloc(size_t num_items, size_t size, void** result) { - *result = calloc(num_items, size); - return *result != nullptr; -} - -} // namespace base
diff --git a/base/process/memory_win.cc b/base/process/memory_win.cc deleted file mode 100644 index 77a2398..0000000 --- a/base/process/memory_win.cc +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/memory.h" - -#include <windows.h> // Must be in front of other Windows header files. - -#include <new.h> -#include <psapi.h> -#include <stddef.h> - -#if defined(__clang__) -// This global constructor is trivial and non-racy (per being const). -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wglobal-constructors" -#endif - -// malloc_unchecked is required to implement UncheckedMalloc properly. -// It's provided by allocator_shim_win.cc but since that's not always present, -// we provide a default that falls back to regular malloc. -typedef void* (*MallocFn)(size_t); -extern "C" void* (*const malloc_unchecked)(size_t); -extern "C" void* (*const malloc_default)(size_t) = &malloc; - -#if defined(__clang__) -#pragma clang diagnostic pop // -Wglobal-constructors -#endif - -#if defined(_M_IX86) -#pragma comment(linker, "/alternatename:_malloc_unchecked=_malloc_default") -#elif defined(_M_X64) || defined(_M_ARM) -#pragma comment(linker, "/alternatename:malloc_unchecked=malloc_default") -#else -#error Unsupported platform -#endif - -namespace base { - -namespace { - -#pragma warning(push) -#pragma warning(disable : 4702) // Unreachable code after the _exit. - -NOINLINE int OnNoMemory(size_t size) { - // Kill the process. This is important for security since most of code - // does not check the result of memory allocation. - // https://msdn.microsoft.com/en-us/library/het71c37.aspx - // Pass the size of the failed request in an exception argument. - ULONG_PTR exception_args[] = {size}; - ::RaiseException(win::kOomExceptionCode, EXCEPTION_NONCONTINUABLE, - arraysize(exception_args), exception_args); - - // Safety check, make sure process exits here. - _exit(win::kOomExceptionCode); - return 0; -} - -#pragma warning(pop) - -} // namespace - -void TerminateBecauseOutOfMemory(size_t size) { - OnNoMemory(size); -} - -void EnableTerminationOnHeapCorruption() { - // Ignore the result code. Supported on XP SP3 and Vista. - HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); -} - -void EnableTerminationOnOutOfMemory() { - _set_new_handler(&OnNoMemory); - _set_new_mode(1); -} - -// Implemented using a weak symbol. -bool UncheckedMalloc(size_t size, void** result) { - *result = malloc_unchecked(size); - return *result != NULL; -} - -} // namespace base
diff --git a/base/process/process.h b/base/process/process.h deleted file mode 100644 index 857bd6d..0000000 --- a/base/process/process.h +++ /dev/null
@@ -1,141 +0,0 @@ -// Copyright 2011 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. - -#ifndef BASE_PROCESS_PROCESS_H_ -#define BASE_PROCESS_PROCESS_H_ - -#include "base/macros.h" -#include "base/process/process_handle.h" -#include "base/time/time.h" -#include "build_config.h" - -#if defined(OS_WIN) -#include "base/win/scoped_handle.h" -#endif - -namespace base { - -// Provides a move-only encapsulation of a process. -// -// This object is not tied to the lifetime of the underlying process: the -// process may be killed and this object may still around, and it will still -// claim to be valid. The actual behavior in that case is OS dependent like so: -// -// Windows: The underlying ProcessHandle will be valid after the process dies -// and can be used to gather some information about that process, but most -// methods will obviously fail. -// -// POSIX: The underlying ProcessHandle is not guaranteed to remain valid after -// the process dies, and it may be reused by the system, which means that it may -// end up pointing to the wrong process. -class Process { - public: - // On Windows, this takes ownership of |handle|. On POSIX, this does not take - // ownership of |handle|. - explicit Process(ProcessHandle handle = kNullProcessHandle); - - Process(Process&& other); - - // The destructor does not terminate the process. - ~Process(); - - Process& operator=(Process&& other); - - // Returns an object for the current process. - static Process Current(); - - // Returns a Process for the given |pid|. - static Process Open(ProcessId pid); - - // Returns a Process for the given |pid|. On Windows the handle is opened - // with more access rights and must only be used by trusted code (can read the - // address space and duplicate handles). - static Process OpenWithExtraPrivileges(ProcessId pid); - -#if defined(OS_WIN) - // Returns a Process for the given |pid|, using some |desired_access|. - // See ::OpenProcess documentation for valid |desired_access|. - static Process OpenWithAccess(ProcessId pid, DWORD desired_access); -#endif - - // Terminates the current process immediately with |exit_code|. - [[noreturn]] static void TerminateCurrentProcessImmediately(int exit_code); - - // Returns true if this objects represents a valid process. - bool IsValid() const; - - // Returns a handle for this process. There is no guarantee about when that - // handle becomes invalid because this object retains ownership. - ProcessHandle Handle() const; - - // Returns a second object that represents this process. - Process Duplicate() const; - - // Get the PID for this process. - ProcessId Pid() const; - - // Returns true if this process is the current process. - bool is_current() const; - - // Close the process handle. This will not terminate the process. - void Close(); - -// Returns true if this process is still running. This is only safe on Windows -// (and maybe Fuchsia?), because the ProcessHandle will keep the zombie -// process information available until itself has been released. But on Posix, -// the OS may reuse the ProcessId. -#if defined(OS_WIN) - bool IsRunning() const { - return !WaitForExitWithTimeout(base::TimeDelta(), nullptr); - } -#endif - - // Terminates the process with extreme prejudice. The given |exit_code| will - // be the exit code of the process. If |wait| is true, this method will wait - // for up to one minute for the process to actually terminate. - // Returns true if the process terminates within the allowed time. - // NOTE: On POSIX |exit_code| is ignored. - bool Terminate(int exit_code, bool wait) const; - - // Waits for the process to exit. Returns true on success. - // On POSIX, if the process has been signaled then |exit_code| is set to -1. - // On Linux this must be a child process, however on Mac and Windows it can be - // any process. - // NOTE: |exit_code| is optional, nullptr can be passed if the exit code is - // not required. - bool WaitForExit(int* exit_code) const; - - // Same as WaitForExit() but only waits for up to |timeout|. - // NOTE: |exit_code| is optional, nullptr can be passed if the exit code - // is not required. - bool WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const; - - // Indicates that the process has exited with the specified |exit_code|. - // This should be called if process exit is observed outside of this class. - // (i.e. Not because Terminate or WaitForExit, above, was called.) - // Note that nothing prevents this being called multiple times for a dead - // process though that should be avoided. - void Exited(int exit_code) const; - - // Returns an integer representing the priority of a process. The meaning - // of this value is OS dependent. - int GetPriority() const; - - private: -#if defined(OS_WIN) - win::ScopedHandle process_; -#else - ProcessHandle process_; -#endif - -#if defined(OS_WIN) - bool is_current_process_; -#endif - - DISALLOW_COPY_AND_ASSIGN(Process); -}; - -} // namespace base - -#endif // BASE_PROCESS_PROCESS_H_
diff --git a/base/process/process_handle.cc b/base/process/process_handle.cc deleted file mode 100644 index fde631e..0000000 --- a/base/process/process_handle.cc +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2015 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. - -#include <stdint.h> - -#include "base/logging.h" -#include "base/process/process_handle.h" -#include "build_config.h" - -namespace base { - -namespace { -bool g_have_unique_id = false; -uint32_t g_unique_id; - -// The process which set |g_unique_id|. -ProcessId g_procid; - -// Mangle IDs so that they are not accidentally used as PIDs, e.g. as an -// argument to kill or waitpid. -uint32_t MangleProcessId(ProcessId process_id) { - // Add a large power of 10 so that the pid is still the pid is still readable - // inside the mangled id. - return static_cast<uint32_t>(process_id) + 1000000000U; -} - -} // namespace - -uint32_t GetUniqueIdForProcess() { - if (!g_have_unique_id) { - return MangleProcessId(GetCurrentProcId()); - } - - // Make sure we are the same process that set |g_procid|. This check may have - // false negatives (if a process ID was reused) but should have no false - // positives. - DCHECK_EQ(GetCurrentProcId(), g_procid); - return g_unique_id; -} - -#if defined(OS_LINUX) || defined(OS_AIX) - -void InitUniqueIdForProcessInPidNamespace(ProcessId pid_outside_of_namespace) { - g_unique_id = MangleProcessId(pid_outside_of_namespace); - g_procid = GetCurrentProcId(); - g_have_unique_id = true; -} - -#endif - -} // namespace base
diff --git a/base/process/process_handle.h b/base/process/process_handle.h deleted file mode 100644 index 0ec6bf4..0000000 --- a/base/process/process_handle.h +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright (c) 2013 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. - -#ifndef BASE_PROCESS_PROCESS_HANDLE_H_ -#define BASE_PROCESS_PROCESS_HANDLE_H_ - -#include <stdint.h> -#include <sys/types.h> - -#include "base/files/file_path.h" -#include "build_config.h" - -#if defined(OS_WIN) -#include "base/win/windows_types.h" -#endif - -namespace base { - -// ProcessHandle is a platform specific type which represents the underlying OS -// handle to a process. -// ProcessId is a number which identifies the process in the OS. -#if defined(OS_WIN) -typedef HANDLE ProcessHandle; -typedef DWORD ProcessId; -typedef HANDLE UserTokenHandle; -const ProcessHandle kNullProcessHandle = NULL; -const ProcessId kNullProcessId = 0; -#elif defined(OS_POSIX) -// On POSIX, our ProcessHandle will just be the PID. -typedef pid_t ProcessHandle; -typedef pid_t ProcessId; -const ProcessHandle kNullProcessHandle = 0; -const ProcessId kNullProcessId = 0; -#endif // defined(OS_WIN) - -// To print ProcessIds portably use CrPRIdPid (based on PRIuS and friends from -// C99 and format_macros.h) like this: -// base::StringPrintf("PID is %" CrPRIdPid ".\n", pid); -#if defined(OS_WIN) -#define CrPRIdPid "ld" -#else -#define CrPRIdPid "d" -#endif - -// Returns the id of the current process. -// Note that on some platforms, this is not guaranteed to be unique across -// processes (use GetUniqueIdForProcess if uniqueness is required). -ProcessId GetCurrentProcId(); - -// Returns a unique ID for the current process. The ID will be unique across all -// currently running processes within the chrome session, but IDs of terminated -// processes may be reused. This returns an opaque value that is different from -// a process's PID. -uint32_t GetUniqueIdForProcess(); - -#if defined(OS_LINUX) -// When a process is started in a different PID namespace from the browser -// process, this function must be called with the process's PID in the browser's -// PID namespace in order to initialize its unique ID. Not thread safe. -// WARNING: To avoid inconsistent results from GetUniqueIdForProcess, this -// should only be called very early after process startup - ideally as soon -// after process creation as possible. -void InitUniqueIdForProcessInPidNamespace(ProcessId pid_outside_of_namespace); -#endif - -// Returns the ProcessHandle of the current process. -ProcessHandle GetCurrentProcessHandle(); - -// Returns the process 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. -// DEPRECATED. New code should be using Process::Pid() instead. -// Note that on some platforms, this is not guaranteed to be unique across -// processes. -ProcessId GetProcId(ProcessHandle process); - -#if !defined(OS_FUCHSIA) -// Returns the ID for the parent of the given process. Not available on Fuchsia. -// Returning a negative value indicates an error, such as if the |process| does -// not exist. Returns 0 when |process| has no parent process. -ProcessId GetParentProcessId(ProcessHandle process); -#endif // !defined(OS_FUCHSIA) - -#if defined(OS_POSIX) -// Returns the path to the executable of the given process. -FilePath GetProcessExecutablePath(ProcessHandle process); -#endif - -} // namespace base - -#endif // BASE_PROCESS_PROCESS_HANDLE_H_
diff --git a/base/process/process_handle_freebsd.cc b/base/process/process_handle_freebsd.cc deleted file mode 100644 index bbbf660..0000000 --- a/base/process/process_handle_freebsd.cc +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright (c) 2011 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. - -#include "base/macros.h" -#include "base/process/process_handle.h" - -#include <limits.h> -#include <stddef.h> -#include <sys/sysctl.h> -#include <sys/types.h> -#include <sys/user.h> -#include <unistd.h> - -namespace base { - -ProcessId GetParentProcessId(ProcessHandle process) { - struct kinfo_proc info; - size_t length; - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, process}; - - if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) - return -1; - - return info.ki_ppid; -} - -FilePath GetProcessExecutablePath(ProcessHandle process) { - char pathname[PATH_MAX]; - size_t length; - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, process}; - - length = sizeof(pathname); - - if (sysctl(mib, arraysize(mib), pathname, &length, NULL, 0) < 0 || - length == 0) { - return FilePath(); - } - - return FilePath(std::string(pathname)); -} - -} // namespace base
diff --git a/base/process/process_handle_linux.cc b/base/process/process_handle_linux.cc deleted file mode 100644 index 43e9ce2..0000000 --- a/base/process/process_handle_linux.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_handle.h" - -#include "base/files/file_util.h" -#include "base/process/internal_linux.h" - -namespace base { - -ProcessId GetParentProcessId(ProcessHandle process) { - ProcessId pid = - internal::ReadProcStatsAndGetFieldAsInt64(process, internal::VM_PPID); - // TODO(zijiehe): Returns 0 if |process| does not have a parent process. - if (pid) - return pid; - return -1; -} - -FilePath GetProcessExecutablePath(ProcessHandle process) { - FilePath stat_file = internal::GetProcPidDir(process).Append("exe"); - FilePath exe_name; - if (!ReadSymbolicLink(stat_file, &exe_name)) { - // No such process. Happens frequently in e.g. TerminateAllChromeProcesses - return FilePath(); - } - return exe_name; -} - -} // namespace base
diff --git a/base/process/process_handle_mac.cc b/base/process/process_handle_mac.cc deleted file mode 100644 index 6b62406..0000000 --- a/base/process/process_handle_mac.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_handle.h" - -#include <libproc.h> -#include <stddef.h> -#include <sys/sysctl.h> -#include <sys/types.h> - -#include "base/logging.h" - -namespace base { - -ProcessId GetParentProcessId(ProcessHandle process) { - struct kinfo_proc info; - size_t length = sizeof(struct kinfo_proc); - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, process}; - if (sysctl(mib, 4, &info, &length, NULL, 0) < 0) { - DPLOG(ERROR) << "sysctl"; - return -1; - } - if (length == 0) - return -1; - return info.kp_eproc.e_ppid; -} - -FilePath GetProcessExecutablePath(ProcessHandle process) { - char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; - if (!proc_pidpath(process, pathbuf, sizeof(pathbuf))) - return FilePath(); - - return FilePath(pathbuf); -} - -} // namespace base
diff --git a/base/process/process_handle_openbsd.cc b/base/process/process_handle_openbsd.cc deleted file mode 100644 index 0e85770..0000000 --- a/base/process/process_handle_openbsd.cc +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright (c) 2011 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. - -#include "base/macros.h" -#include "base/process/process_handle.h" - -#include <stddef.h> -#include <sys/sysctl.h> -#include <sys/types.h> -#include <unistd.h> - -namespace base { - -ProcessId GetParentProcessId(ProcessHandle process) { - struct kinfo_proc info; - size_t length; - int mib[] = { - CTL_KERN, KERN_PROC, KERN_PROC_PID, process, sizeof(struct kinfo_proc), - 0}; - - if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) - return -1; - - mib[5] = (length / sizeof(struct kinfo_proc)); - - if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) - return -1; - - return info.p_ppid; -} - -FilePath GetProcessExecutablePath(ProcessHandle process) { - struct kinfo_proc kp; - size_t len; - int mib[] = { - CTL_KERN, KERN_PROC, KERN_PROC_PID, process, sizeof(struct kinfo_proc), - 0}; - - if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) == -1) - return FilePath(); - mib[5] = (len / sizeof(struct kinfo_proc)); - if (sysctl(mib, arraysize(mib), &kp, &len, NULL, 0) < 0) - return FilePath(); - if ((kp.p_flag & P_SYSTEM) != 0) - return FilePath(); - if (strcmp(kp.p_comm, "chrome") == 0) - return FilePath(kp.p_comm); - - return FilePath(); -} - -} // namespace base
diff --git a/base/process/process_handle_posix.cc b/base/process/process_handle_posix.cc deleted file mode 100644 index 4e332df..0000000 --- a/base/process/process_handle_posix.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_handle.h" - -#include <unistd.h> - -namespace base { - -ProcessId GetCurrentProcId() { - return getpid(); -} - -ProcessHandle GetCurrentProcessHandle() { - return GetCurrentProcId(); -} - -ProcessId GetProcId(ProcessHandle process) { - return process; -} - -} // namespace base
diff --git a/base/process/process_handle_win.cc b/base/process/process_handle_win.cc deleted file mode 100644 index cf7ab2c..0000000 --- a/base/process/process_handle_win.cc +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_handle.h" - -#include <windows.h> - -#include <tlhelp32.h> - -#include "base/win/scoped_handle.h" -#include "base/win/windows_version.h" - -namespace base { - -ProcessId GetCurrentProcId() { - return ::GetCurrentProcessId(); -} - -ProcessHandle GetCurrentProcessHandle() { - return ::GetCurrentProcess(); -} - -ProcessId GetProcId(ProcessHandle process) { - // This returns 0 if we have insufficient rights to query the process handle. - return GetProcessId(process); -} - -ProcessId GetParentProcessId(ProcessHandle process) { - ProcessId child_pid = GetProcId(process); - PROCESSENTRY32 process_entry; - process_entry.dwSize = sizeof(PROCESSENTRY32); - - win::ScopedHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); - if (snapshot.IsValid() && Process32First(snapshot.Get(), &process_entry)) { - do { - if (process_entry.th32ProcessID == child_pid) - return process_entry.th32ParentProcessID; - } while (Process32Next(snapshot.Get(), &process_entry)); - } - - // TODO(zijiehe): To match other platforms, -1 (UINT32_MAX) should be returned - // if |child_id| cannot be found in the |snapshot|. - return 0u; -} - -} // namespace base
diff --git a/base/process/process_info.h b/base/process/process_info.h deleted file mode 100644 index 291ad9d..0000000 --- a/base/process/process_info.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef BASE_PROCESS_PROCESS_INFO_H_ -#define BASE_PROCESS_PROCESS_INFO_H_ - -#include "build_config.h" - -namespace base { - -class Time; - -// Vends information about the current process. -class CurrentProcessInfo { - public: - // Returns the time at which the process was launched. May be empty if an - // error occurred retrieving the information. - static const Time CreationTime(); -}; - -#if defined(OS_WIN) -enum IntegrityLevel { - INTEGRITY_UNKNOWN, - LOW_INTEGRITY, - MEDIUM_INTEGRITY, - HIGH_INTEGRITY, -}; - -// Returns the integrity level of the process. Returns INTEGRITY_UNKNOWN in the -// case of an underlying system failure. -IntegrityLevel GetCurrentProcessIntegrityLevel(); - -// Determines whether the current process is elevated. -bool IsCurrentProcessElevated(); - -#endif // defined(OS_WIN) - -} // namespace base - -#endif // BASE_PROCESS_PROCESS_INFO_H_
diff --git a/base/process/process_info_linux.cc b/base/process/process_info_linux.cc deleted file mode 100644 index 2f22748..0000000 --- a/base/process/process_info_linux.cc +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2013 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. - -#include "base/process/process_info.h" - -#include <stdint.h> - -#include "base/logging.h" -#include "base/process/internal_linux.h" -#include "base/process/process_handle.h" -#include "base/time/time.h" - -namespace base { - -// static -const Time CurrentProcessInfo::CreationTime() { - int64_t start_ticks = - internal::ReadProcSelfStatsAndGetFieldAsInt64(internal::VM_STARTTIME); - if (!start_ticks) - return Time(); - TimeDelta start_offset = internal::ClockTicksToTimeDelta(start_ticks); - Time boot_time = internal::GetBootTime(); - if (boot_time.is_null()) - return Time(); - return Time(boot_time + start_offset); -} - -} // namespace base
diff --git a/base/process/process_info_mac.cc b/base/process/process_info_mac.cc deleted file mode 100644 index 3083e53..0000000 --- a/base/process/process_info_mac.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright (c) 2012 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. - -#include "base/process/process_info.h" - -#include <stddef.h> -#include <sys/sysctl.h> -#include <sys/time.h> -#include <unistd.h> - -#include <memory> - -#include "base/macros.h" -#include "base/memory/free_deleter.h" -#include "base/time/time.h" - -namespace base { - -// static -const Time CurrentProcessInfo::CreationTime() { - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; - size_t len = 0; - if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) - return Time(); - - std::unique_ptr<struct kinfo_proc, base::FreeDeleter> proc( - static_cast<struct kinfo_proc*>(malloc(len))); - if (sysctl(mib, arraysize(mib), proc.get(), &len, NULL, 0) < 0) - return Time(); - return Time::FromTimeVal(proc->kp_proc.p_un.__p_starttime); -} - -} // namespace base
diff --git a/base/process/process_info_win.cc b/base/process/process_info_win.cc deleted file mode 100644 index 23e93e3..0000000 --- a/base/process/process_info_win.cc +++ /dev/null
@@ -1,94 +0,0 @@ -// Copyright (c) 2012 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. - -#include "base/process/process_info.h" - -#include <windows.h> -#include <memory> - -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/time/time.h" -#include "base/win/scoped_handle.h" - -namespace base { - -namespace { - -HANDLE GetCurrentProcessToken() { - HANDLE process_token; - OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token); - DCHECK(process_token != NULL && process_token != INVALID_HANDLE_VALUE); - return process_token; -} - -} // namespace - -// static -const Time CurrentProcessInfo::CreationTime() { - FILETIME creation_time = {}; - FILETIME ignore1 = {}; - FILETIME ignore2 = {}; - FILETIME ignore3 = {}; - if (!::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore1, - &ignore2, &ignore3)) { - return Time(); - } - return Time::FromFileTime(creation_time); -} - -IntegrityLevel GetCurrentProcessIntegrityLevel() { - HANDLE process_token(GetCurrentProcessToken()); - - DWORD token_info_length = 0; - if (::GetTokenInformation(process_token, TokenIntegrityLevel, nullptr, 0, - &token_info_length) || - ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - return INTEGRITY_UNKNOWN; - } - - auto token_label_bytes = std::make_unique<char[]>(token_info_length); - TOKEN_MANDATORY_LABEL* token_label = - reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get()); - if (!::GetTokenInformation(process_token, TokenIntegrityLevel, token_label, - token_info_length, &token_info_length)) { - return INTEGRITY_UNKNOWN; - } - - DWORD integrity_level = *::GetSidSubAuthority( - token_label->Label.Sid, - static_cast<DWORD>(*::GetSidSubAuthorityCount(token_label->Label.Sid) - - 1)); - - if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID) - return LOW_INTEGRITY; - - if (integrity_level >= SECURITY_MANDATORY_MEDIUM_RID && - integrity_level < SECURITY_MANDATORY_HIGH_RID) { - return MEDIUM_INTEGRITY; - } - - if (integrity_level >= SECURITY_MANDATORY_HIGH_RID) - return HIGH_INTEGRITY; - - NOTREACHED(); - return INTEGRITY_UNKNOWN; -} - -bool IsCurrentProcessElevated() { - HANDLE process_token(GetCurrentProcessToken()); - - // Unlike TOKEN_ELEVATION_TYPE which returns TokenElevationTypeDefault when - // UAC is turned off, TOKEN_ELEVATION returns whether the process is elevated. - DWORD size; - TOKEN_ELEVATION elevation; - if (!GetTokenInformation(process_token, TokenElevation, &elevation, - sizeof(elevation), &size)) { - PLOG(ERROR) << "GetTokenInformation() failed"; - return false; - } - return !!elevation.TokenIsElevated; -} - -} // namespace base
diff --git a/base/process/process_iterator.cc b/base/process/process_iterator.cc deleted file mode 100644 index e56b349..0000000 --- a/base/process/process_iterator.cc +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_iterator.h" -#include "build_config.h" - -namespace base { - -#if defined(OS_POSIX) || defined(OS_FUCHSIA) -ProcessEntry::ProcessEntry() : pid_(0), ppid_(0), gid_(0) {} -ProcessEntry::ProcessEntry(const ProcessEntry& other) = default; -ProcessEntry::~ProcessEntry() = default; -#endif - -const ProcessEntry* ProcessIterator::NextProcessEntry() { - bool result = false; - do { - result = CheckForNextProcess(); - } while (result && !IncludeEntry()); - if (result) - return &entry_; - return nullptr; -} - -ProcessIterator::ProcessEntries ProcessIterator::Snapshot() { - ProcessEntries found; - while (const ProcessEntry* process_entry = NextProcessEntry()) { - found.push_back(*process_entry); - } - return found; -} - -bool ProcessIterator::IncludeEntry() { - return !filter_ || filter_->Includes(entry_); -} - -NamedProcessIterator::NamedProcessIterator( - const FilePath::StringType& executable_name, - const ProcessFilter* filter) - : ProcessIterator(filter), executable_name_(executable_name) {} - -NamedProcessIterator::~NamedProcessIterator() = default; - -int GetProcessCount(const FilePath::StringType& executable_name, - const ProcessFilter* filter) { - int count = 0; - NamedProcessIterator iter(executable_name, filter); - while (iter.NextProcessEntry()) - ++count; - return count; -} - -} // namespace base
diff --git a/base/process/process_iterator.h b/base/process/process_iterator.h deleted file mode 100644 index b0d96e4..0000000 --- a/base/process/process_iterator.h +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright (c) 2013 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 contains methods to iterate over processes on the system. - -#ifndef BASE_PROCESS_PROCESS_ITERATOR_H_ -#define BASE_PROCESS_PROCESS_ITERATOR_H_ - -#include <stddef.h> - -#include <list> -#include <string> -#include <vector> - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/process/process.h" -#include "build_config.h" - -#if defined(OS_WIN) -#include <windows.h> - -#include <tlhelp32.h> -#elif defined(OS_MACOSX) || defined(OS_OPENBSD) -#include <sys/sysctl.h> -#elif defined(OS_POSIX) || defined(OS_FUCHSIA) -#include <dirent.h> -#endif - -namespace base { - -#if defined(OS_WIN) -struct ProcessEntry : public PROCESSENTRY32 { - ProcessId pid() const { return th32ProcessID; } - ProcessId parent_pid() const { return th32ParentProcessID; } - const wchar_t* exe_file() const { return szExeFile; } -}; -#elif defined(OS_POSIX) || defined(OS_FUCHSIA) -struct ProcessEntry { - ProcessEntry(); - ProcessEntry(const ProcessEntry& other); - ~ProcessEntry(); - - ProcessId pid() const { return pid_; } - ProcessId parent_pid() const { return ppid_; } - ProcessId gid() const { return gid_; } - const char* exe_file() const { return exe_file_.c_str(); } - const std::vector<std::string>& cmd_line_args() const { - return cmd_line_args_; - } - - ProcessId pid_; - ProcessId ppid_; - ProcessId gid_; - std::string exe_file_; - std::vector<std::string> cmd_line_args_; -}; -#endif // defined(OS_WIN) - -// 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(const ProcessEntry& entry) const = 0; - - protected: - virtual ~ProcessFilter() = default; -}; - -// This class provides a way to iterate through a list of processes on the -// current machine with a specified filter. -// To use, create an instance and then call NextProcessEntry() until it returns -// false. -class ProcessIterator { - public: - typedef std::list<ProcessEntry> ProcessEntries; - - explicit ProcessIterator(const ProcessFilter* filter); - virtual ~ProcessIterator(); - - // 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(); - - // Takes a snapshot of all the ProcessEntry found. - ProcessEntries Snapshot(); - - protected: - virtual bool IncludeEntry(); - const ProcessEntry& entry() { return entry_; } - - private: - // 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(); - - // Initializes a PROCESSENTRY32 data structure so that it's ready for - // use with Process32First/Process32Next. - void InitProcessEntry(ProcessEntry* entry); - -#if defined(OS_WIN) - HANDLE snapshot_; - bool started_iteration_; -#elif defined(OS_MACOSX) || defined(OS_BSD) - std::vector<kinfo_proc> kinfo_procs_; - size_t index_of_kinfo_proc_; -#elif defined(OS_POSIX) || defined(OS_FUCHSIA) - DIR* procfs_dir_; -#endif - ProcessEntry entry_; - const ProcessFilter* filter_; - - DISALLOW_COPY_AND_ASSIGN(ProcessIterator); -}; - -// 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 ProcessIterator { - public: - NamedProcessIterator(const FilePath::StringType& executable_name, - const ProcessFilter* filter); - ~NamedProcessIterator() override; - - protected: - bool IncludeEntry() override; - - private: - FilePath::StringType executable_name_; - - DISALLOW_COPY_AND_ASSIGN(NamedProcessIterator); -}; - -// Returns the number of processes on the machine that are running from the -// given executable name. If filter is non-null, then only processes selected -// by the filter will be counted. -int GetProcessCount(const FilePath::StringType& executable_name, - const ProcessFilter* filter); - -} // namespace base - -#endif // BASE_PROCESS_PROCESS_ITERATOR_H_
diff --git a/base/process/process_iterator_freebsd.cc b/base/process/process_iterator_freebsd.cc deleted file mode 100644 index a69b2f0..0000000 --- a/base/process/process_iterator_freebsd.cc +++ /dev/null
@@ -1,128 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_iterator.h" - -#include <errno.h> -#include <stddef.h> -#include <sys/sysctl.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" - -namespace base { - -ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : index_of_kinfo_proc_(), filter_(filter) { - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid()}; - - bool done = false; - int try_num = 1; - const int max_tries = 10; - - do { - size_t len = 0; - if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) { - LOG(ERROR) << "failed to get the size needed for the process list"; - kinfo_procs_.resize(0); - done = true; - } else { - size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc); - // Leave some spare room for process table growth (more could show up - // between when we check and now) - num_of_kinfo_proc += 16; - kinfo_procs_.resize(num_of_kinfo_proc); - len = num_of_kinfo_proc * sizeof(struct kinfo_proc); - if (sysctl(mib, arraysize(mib), &kinfo_procs_[0], &len, NULL, 0) < 0) { - // If we get a mem error, it just means we need a bigger buffer, so - // loop around again. Anything else is a real error and give up. - if (errno != ENOMEM) { - LOG(ERROR) << "failed to get the process list"; - kinfo_procs_.resize(0); - done = true; - } - } else { - // Got the list, just make sure we're sized exactly right - size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc); - kinfo_procs_.resize(num_of_kinfo_proc); - done = true; - } - } - } while (!done && (try_num++ < max_tries)); - - if (!done) { - LOG(ERROR) << "failed to collect the process list in a few tries"; - kinfo_procs_.resize(0); - } -} - -ProcessIterator::~ProcessIterator() {} - -bool ProcessIterator::CheckForNextProcess() { - std::string data; - - for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) { - size_t length; - struct kinfo_proc kinfo = kinfo_procs_[index_of_kinfo_proc_]; - int mib[] = {CTL_KERN, KERN_PROC_ARGS, kinfo.ki_pid}; - - if ((kinfo.ki_pid > 0) && (kinfo.ki_stat == SZOMB)) - continue; - - length = 0; - if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) { - LOG(ERROR) << "failed to figure out the buffer size for a command line"; - continue; - } - - data.resize(length); - - if (sysctl(mib, arraysize(mib), &data[0], &length, NULL, 0) < 0) { - LOG(ERROR) << "failed to fetch a commandline"; - continue; - } - - std::string delimiters; - delimiters.push_back('\0'); - entry_.cmd_line_args_ = - SplitString(data, delimiters, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); - - size_t exec_name_end = data.find('\0'); - if (exec_name_end == std::string::npos) { - LOG(ERROR) << "command line data didn't match expected format"; - continue; - } - - entry_.pid_ = kinfo.ki_pid; - entry_.ppid_ = kinfo.ki_ppid; - entry_.gid_ = kinfo.ki_pgid; - - size_t last_slash = data.rfind('/', exec_name_end); - if (last_slash == std::string::npos) { - entry_.exe_file_.assign(data, 0, exec_name_end); - } else { - entry_.exe_file_.assign(data, last_slash + 1, - exec_name_end - last_slash - 1); - } - - // Start w/ the next entry next time through - ++index_of_kinfo_proc_; - - return true; - } - return false; -} - -bool NamedProcessIterator::IncludeEntry() { - if (executable_name_ != entry().exe_file()) - return false; - - return ProcessIterator::IncludeEntry(); -} - -} // namespace base
diff --git a/base/process/process_iterator_linux.cc b/base/process/process_iterator_linux.cc deleted file mode 100644 index 9894052..0000000 --- a/base/process/process_iterator_linux.cc +++ /dev/null
@@ -1,147 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_iterator.h" - -#include <stddef.h> - -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/process/internal_linux.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" - -namespace base { - -namespace { - -// Reads the |field_num|th field from |proc_stats|. -// Returns an empty string on failure. -// This version only handles VM_COMM and VM_STATE, which are the only fields -// that are strings. -std::string GetProcStatsFieldAsString( - const std::vector<std::string>& proc_stats, - internal::ProcStatsFields field_num) { - if (field_num < internal::VM_COMM || field_num > internal::VM_STATE) { - NOTREACHED(); - return std::string(); - } - - if (proc_stats.size() > static_cast<size_t>(field_num)) - return proc_stats[field_num]; - - NOTREACHED(); - return nullptr; -} - -// Reads /proc/<pid>/cmdline and populates |proc_cmd_line_args| with the command -// line arguments. Returns true if successful. -// Note: /proc/<pid>/cmdline contains command line arguments separated by single -// null characters. We tokenize it into a vector of strings using '\0' as a -// delimiter. -bool GetProcCmdline(pid_t pid, std::vector<std::string>* proc_cmd_line_args) { - FilePath cmd_line_file = internal::GetProcPidDir(pid).Append("cmdline"); - std::string cmd_line; - if (!ReadFileToString(cmd_line_file, &cmd_line)) - return false; - std::string delimiters; - delimiters.push_back('\0'); - *proc_cmd_line_args = - SplitString(cmd_line, delimiters, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); - return true; -} - -} // namespace - -ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : filter_(filter) { - procfs_dir_ = opendir(internal::kProcDir); - if (!procfs_dir_) { - // On Android, SELinux may prevent reading /proc. See - // https://crbug.com/581517 for details. - PLOG(ERROR) << "opendir " << internal::kProcDir; - } -} - -ProcessIterator::~ProcessIterator() { - if (procfs_dir_) { - closedir(procfs_dir_); - procfs_dir_ = nullptr; - } -} - -bool ProcessIterator::CheckForNextProcess() { - // TODO(port): skip processes owned by different UID - - if (!procfs_dir_) { - DLOG(ERROR) << "Skipping CheckForNextProcess(), no procfs_dir_"; - return false; - } - - pid_t pid = kNullProcessId; - std::vector<std::string> cmd_line_args; - std::string stats_data; - std::vector<std::string> proc_stats; - - // Arbitrarily guess that there will never be more than 200 non-process - // files in /proc. Hardy has 53 and Lucid has 61. - int skipped = 0; - const int kSkipLimit = 200; - while (skipped < kSkipLimit) { - dirent* slot = readdir(procfs_dir_); - // all done looking through /proc? - if (!slot) - return false; - - // If not a process, keep looking for one. - pid = internal::ProcDirSlotToPid(slot->d_name); - if (!pid) { - skipped++; - continue; - } - - if (!GetProcCmdline(pid, &cmd_line_args)) - continue; - - if (!internal::ReadProcStats(pid, &stats_data)) - continue; - if (!internal::ParseProcStats(stats_data, &proc_stats)) - continue; - - std::string runstate = - GetProcStatsFieldAsString(proc_stats, internal::VM_STATE); - if (runstate.size() != 1) { - NOTREACHED(); - continue; - } - - // Is the process in 'Zombie' state, i.e. dead but waiting to be reaped? - // Allowed values: D R S T Z - if (runstate[0] != 'Z') - break; - - // Nope, it's a zombie; somebody isn't cleaning up after their children. - // (e.g. WaitForProcessesToExit doesn't clean up after dead children yet.) - // There could be a lot of zombies, can't really decrement i here. - } - if (skipped >= kSkipLimit) { - NOTREACHED(); - return false; - } - - entry_.pid_ = pid; - entry_.ppid_ = GetProcStatsFieldAsInt64(proc_stats, internal::VM_PPID); - entry_.gid_ = GetProcStatsFieldAsInt64(proc_stats, internal::VM_PGRP); - entry_.cmd_line_args_.assign(cmd_line_args.begin(), cmd_line_args.end()); - entry_.exe_file_ = GetProcessExecutablePath(pid).BaseName().value(); - return true; -} - -bool NamedProcessIterator::IncludeEntry() { - if (executable_name_ != entry().exe_file()) - return false; - return ProcessIterator::IncludeEntry(); -} - -} // namespace base
diff --git a/base/process/process_iterator_mac.cc b/base/process/process_iterator_mac.cc deleted file mode 100644 index 10d712b..0000000 --- a/base/process/process_iterator_mac.cc +++ /dev/null
@@ -1,134 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_iterator.h" - -#include <errno.h> -#include <stddef.h> -#include <sys/sysctl.h> -#include <sys/types.h> -#include <unistd.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" - -namespace base { - -ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : index_of_kinfo_proc_(0), filter_(filter) { - // Get a snapshot of all of my processes (yes, as we loop it can go stale, but - // but trying to find where we were in a constantly changing list is basically - // impossible. - - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, static_cast<int>(geteuid())}; - - // Since more processes could start between when we get the size and when - // we get the list, we do a loop to keep trying until we get it. - bool done = false; - int try_num = 1; - const int max_tries = 10; - do { - // Get the size of the buffer - size_t len = 0; - if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) { - DLOG(ERROR) << "failed to get the size needed for the process list"; - kinfo_procs_.resize(0); - done = true; - } else { - size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc); - // Leave some spare room for process table growth (more could show up - // between when we check and now) - num_of_kinfo_proc += 16; - kinfo_procs_.resize(num_of_kinfo_proc); - len = num_of_kinfo_proc * sizeof(struct kinfo_proc); - // Load the list of processes - if (sysctl(mib, arraysize(mib), &kinfo_procs_[0], &len, NULL, 0) < 0) { - // If we get a mem error, it just means we need a bigger buffer, so - // loop around again. Anything else is a real error and give up. - if (errno != ENOMEM) { - DLOG(ERROR) << "failed to get the process list"; - kinfo_procs_.resize(0); - done = true; - } - } else { - // Got the list, just make sure we're sized exactly right - kinfo_procs_.resize(len / sizeof(struct kinfo_proc)); - done = true; - } - } - } while (!done && (try_num++ < max_tries)); - - if (!done) { - DLOG(ERROR) << "failed to collect the process list in a few tries"; - kinfo_procs_.resize(0); - } -} - -ProcessIterator::~ProcessIterator() {} - -bool ProcessIterator::CheckForNextProcess() { - std::string data; - for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) { - kinfo_proc& kinfo = kinfo_procs_[index_of_kinfo_proc_]; - - // Skip processes just awaiting collection - if ((kinfo.kp_proc.p_pid > 0) && (kinfo.kp_proc.p_stat == SZOMB)) - continue; - - int mib[] = {CTL_KERN, KERN_PROCARGS, kinfo.kp_proc.p_pid}; - - // Find out what size buffer we need. - size_t data_len = 0; - if (sysctl(mib, arraysize(mib), NULL, &data_len, NULL, 0) < 0) { - continue; - } - - data.resize(data_len); - if (sysctl(mib, arraysize(mib), &data[0], &data_len, NULL, 0) < 0) { - continue; - } - - // |data| contains all the command line parameters of the process, separated - // by blocks of one or more null characters. We tokenize |data| into a - // vector of strings using '\0' as a delimiter and populate - // |entry_.cmd_line_args_|. - std::string delimiters; - delimiters.push_back('\0'); - entry_.cmd_line_args_ = - SplitString(data, delimiters, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); - - // |data| starts with the full executable path followed by a null character. - // We search for the first instance of '\0' and extract everything before it - // to populate |entry_.exe_file_|. - size_t exec_name_end = data.find('\0'); - if (exec_name_end == std::string::npos) { - DLOG(ERROR) << "command line data didn't match expected format"; - continue; - } - - entry_.pid_ = kinfo.kp_proc.p_pid; - entry_.ppid_ = kinfo.kp_eproc.e_ppid; - entry_.gid_ = kinfo.kp_eproc.e_pgid; - size_t last_slash = data.rfind('/', exec_name_end); - if (last_slash == std::string::npos) - entry_.exe_file_.assign(data, 0, exec_name_end); - else - entry_.exe_file_.assign(data, last_slash + 1, - exec_name_end - last_slash - 1); - // Start w/ the next entry next time through - ++index_of_kinfo_proc_; - // Done - return true; - } - return false; -} - -bool NamedProcessIterator::IncludeEntry() { - return (executable_name_ == entry().exe_file() && - ProcessIterator::IncludeEntry()); -} - -} // namespace base
diff --git a/base/process/process_iterator_openbsd.cc b/base/process/process_iterator_openbsd.cc deleted file mode 100644 index 4362c9a..0000000 --- a/base/process/process_iterator_openbsd.cc +++ /dev/null
@@ -1,128 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_iterator.h" - -#include <errno.h> -#include <stddef.h> -#include <sys/sysctl.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" - -namespace base { - -ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : index_of_kinfo_proc_(), filter_(filter) { - int mib[] = { - CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid(), sizeof(struct kinfo_proc), - 0}; - - bool done = false; - int try_num = 1; - const int max_tries = 10; - - do { - size_t len = 0; - if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) { - DLOG(ERROR) << "failed to get the size needed for the process list"; - kinfo_procs_.resize(0); - done = true; - } else { - size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc); - // Leave some spare room for process table growth (more could show up - // between when we check and now) - num_of_kinfo_proc += 16; - kinfo_procs_.resize(num_of_kinfo_proc); - len = num_of_kinfo_proc * sizeof(struct kinfo_proc); - if (sysctl(mib, arraysize(mib), &kinfo_procs_[0], &len, NULL, 0) < 0) { - // If we get a mem error, it just means we need a bigger buffer, so - // loop around again. Anything else is a real error and give up. - if (errno != ENOMEM) { - DLOG(ERROR) << "failed to get the process list"; - kinfo_procs_.resize(0); - done = true; - } - } else { - // Got the list, just make sure we're sized exactly right - size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc); - kinfo_procs_.resize(num_of_kinfo_proc); - done = true; - } - } - } while (!done && (try_num++ < max_tries)); - - if (!done) { - DLOG(ERROR) << "failed to collect the process list in a few tries"; - kinfo_procs_.resize(0); - } -} - -ProcessIterator::~ProcessIterator() {} - -bool ProcessIterator::CheckForNextProcess() { - std::string data; - for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) { - kinfo_proc& kinfo = kinfo_procs_[index_of_kinfo_proc_]; - - // Skip processes just awaiting collection - if ((kinfo.p_pid > 0) && (kinfo.p_stat == SZOMB)) - continue; - - int mib[] = {CTL_KERN, KERN_PROC_ARGS, kinfo.p_pid}; - - // Find out what size buffer we need. - size_t data_len = 0; - if (sysctl(mib, arraysize(mib), NULL, &data_len, NULL, 0) < 0) { - continue; - } - - data.resize(data_len); - if (sysctl(mib, arraysize(mib), &data[0], &data_len, NULL, 0) < 0) { - continue; - } - - // |data| contains all the command line parameters of the process, separated - // by blocks of one or more null characters. We tokenize |data| into a - // vector of strings using '\0' as a delimiter and populate - // |entry_.cmd_line_args_|. - std::string delimiters; - delimiters.push_back('\0'); - entry_.cmd_line_args_ = - SplitString(data, delimiters, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); - - // |data| starts with the full executable path followed by a null character. - // We search for the first instance of '\0' and extract everything before it - // to populate |entry_.exe_file_|. - size_t exec_name_end = data.find('\0'); - if (exec_name_end == std::string::npos) { - DLOG(ERROR) << "command line data didn't match expected format"; - continue; - } - - entry_.pid_ = kinfo.p_pid; - entry_.ppid_ = kinfo.p_ppid; - entry_.gid_ = kinfo.p__pgid; - size_t last_slash = data.rfind('/', exec_name_end); - if (last_slash == std::string::npos) - entry_.exe_file_.assign(data, 0, exec_name_end); - else - entry_.exe_file_.assign(data, last_slash + 1, - exec_name_end - last_slash - 1); - // Start w/ the next entry next time through - ++index_of_kinfo_proc_; - // Done - return true; - } - return false; -} - -bool NamedProcessIterator::IncludeEntry() { - return (executable_name_ == entry().exe_file() && - ProcessIterator::IncludeEntry()); -} - -} // namespace base
diff --git a/base/process/process_iterator_win.cc b/base/process/process_iterator_win.cc deleted file mode 100644 index e1bf808..0000000 --- a/base/process/process_iterator_win.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2013 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. - -#include "base/process/process_iterator.h" - -namespace base { - -ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : started_iteration_(false), filter_(filter) { - snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); -} - -ProcessIterator::~ProcessIterator() { - CloseHandle(snapshot_); -} - -bool ProcessIterator::CheckForNextProcess() { - InitProcessEntry(&entry_); - - if (!started_iteration_) { - started_iteration_ = true; - return !!Process32First(snapshot_, &entry_); - } - - return !!Process32Next(snapshot_, &entry_); -} - -void ProcessIterator::InitProcessEntry(ProcessEntry* entry) { - memset(entry, 0, sizeof(*entry)); - entry->dwSize = sizeof(*entry); -} - -bool NamedProcessIterator::IncludeEntry() { - // Case insensitive. - return _wcsicmp(executable_name_.c_str(), entry().exe_file()) == 0 && - ProcessIterator::IncludeEntry(); -} - -} // namespace base
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc deleted file mode 100644 index 5c9ce05..0000000 --- a/base/process/process_posix.cc +++ /dev/null
@@ -1,338 +0,0 @@ -// Copyright 2011 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. - -#include "base/process/process.h" - -#include <errno.h> -#include <signal.h> -#include <stdint.h> -#include <sys/resource.h> -#include <sys/wait.h> - -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/kill.h" -#include "build_config.h" - -#if defined(OS_MACOSX) -#include <sys/event.h> -#endif - -namespace { - -#if !defined(OS_NACL_NONSFI) - -bool WaitpidWithTimeout(base::ProcessHandle handle, - int* status, - base::TimeDelta wait) { - // This POSIX version of this function only guarantees that we wait no less - // than |wait| for the process to exit. The child process may - // exit sometime before the timeout has ended but we may still block for up - // to 256 milliseconds after the fact. - // - // waitpid() has no direct support on POSIX for specifying a timeout, you can - // either ask it to block indefinitely or return immediately (WNOHANG). - // When a child process terminates a SIGCHLD signal is sent to the parent. - // Catching this signal would involve installing a signal handler which may - // affect other parts of the application and would be difficult to debug. - // - // Our strategy is to call waitpid() once up front to check if the process - // has already exited, otherwise to loop for |wait|, sleeping for - // at most 256 milliseconds each time using usleep() and then calling - // waitpid(). The amount of time we sleep starts out at 1 milliseconds, and - // we double it every 4 sleep cycles. - // - // usleep() is speced to exit if a signal is received for which a handler - // has been installed. This means that when a SIGCHLD is sent, it will exit - // depending on behavior external to this function. - // - // This function is used primarily for unit tests, if we want to use it in - // the application itself it would probably be best to examine other routes. - - if (wait == base::TimeDelta::Max()) { - return HANDLE_EINTR(waitpid(handle, status, 0)) > 0; - } - - pid_t ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG)); - static const int64_t kMaxSleepInMicroseconds = 1 << 18; // ~256 milliseconds. - int64_t max_sleep_time_usecs = 1 << 10; // ~1 milliseconds. - int64_t double_sleep_time = 0; - - // If the process hasn't exited yet, then sleep and try again. - base::TimeTicks wakeup_time = base::TimeTicks::Now() + wait; - while (ret_pid == 0) { - base::TimeTicks now = base::TimeTicks::Now(); - if (now > wakeup_time) - break; - // Guaranteed to be non-negative! - int64_t sleep_time_usecs = (wakeup_time - now).InMicroseconds(); - // Sleep for a bit while we wait for the process to finish. - if (sleep_time_usecs > max_sleep_time_usecs) - sleep_time_usecs = max_sleep_time_usecs; - - // usleep() will return 0 and set errno to EINTR on receipt of a signal - // such as SIGCHLD. - usleep(sleep_time_usecs); - ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG)); - - if ((max_sleep_time_usecs < kMaxSleepInMicroseconds) && - (double_sleep_time++ % 4 == 0)) { - max_sleep_time_usecs *= 2; - } - } - - return ret_pid > 0; -} - -#if defined(OS_MACOSX) -// Using kqueue on Mac so that we can wait on non-child processes. -// We can't use kqueues on child processes because we need to reap -// our own children using wait. -bool WaitForSingleNonChildProcess(base::ProcessHandle handle, - base::TimeDelta wait) { - DCHECK_GT(handle, 0); - - base::ScopedFD kq(kqueue()); - if (!kq.is_valid()) { - DPLOG(ERROR) << "kqueue"; - return false; - } - - struct kevent change = {0}; - EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); - int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL)); - if (result == -1) { - if (errno == ESRCH) { - // If the process wasn't found, it must be dead. - return true; - } - - DPLOG(ERROR) << "kevent (setup " << handle << ")"; - return false; - } - - // Keep track of the elapsed time to be able to restart kevent if it's - // interrupted. - bool wait_forever = (wait == base::TimeDelta::Max()); - base::TimeDelta remaining_delta; - base::TimeTicks deadline; - if (!wait_forever) { - remaining_delta = wait; - deadline = base::TimeTicks::Now() + remaining_delta; - } - - result = -1; - struct kevent event = {0}; - - do { - struct timespec remaining_timespec; - struct timespec* remaining_timespec_ptr; - if (wait_forever) { - remaining_timespec_ptr = NULL; - } else { - remaining_timespec = remaining_delta.ToTimeSpec(); - remaining_timespec_ptr = &remaining_timespec; - } - - result = kevent(kq.get(), NULL, 0, &event, 1, remaining_timespec_ptr); - - if (result == -1 && errno == EINTR) { - if (!wait_forever) { - remaining_delta = deadline - base::TimeTicks::Now(); - } - result = 0; - } else { - break; - } - } while (wait_forever || remaining_delta > base::TimeDelta()); - - if (result < 0) { - DPLOG(ERROR) << "kevent (wait " << handle << ")"; - return false; - } else if (result > 1) { - DLOG(ERROR) << "kevent (wait " << handle << "): unexpected result " - << result; - return false; - } else if (result == 0) { - // Timed out. - return false; - } - - DCHECK_EQ(result, 1); - - if (event.filter != EVFILT_PROC || (event.fflags & NOTE_EXIT) == 0 || - event.ident != static_cast<uintptr_t>(handle)) { - DLOG(ERROR) << "kevent (wait " << handle - << "): unexpected event: filter=" << event.filter - << ", fflags=" << event.fflags << ", ident=" << event.ident; - return false; - } - - return true; -} -#endif // OS_MACOSX - -bool WaitForExitWithTimeoutImpl(base::ProcessHandle handle, - int* exit_code, - base::TimeDelta timeout) { - const base::ProcessHandle our_pid = base::GetCurrentProcessHandle(); - if (handle == our_pid) { - // We won't be able to wait for ourselves to exit. - return false; - } - - const base::ProcessHandle parent_pid = base::GetParentProcessId(handle); - const bool exited = (parent_pid < 0); - - if (!exited && parent_pid != our_pid) { -#if defined(OS_MACOSX) - // On Mac we can wait on non child processes. - return WaitForSingleNonChildProcess(handle, timeout); -#else - // Currently on Linux we can't handle non child processes. - NOTIMPLEMENTED(); -#endif // OS_MACOSX - } - - int status; - if (!WaitpidWithTimeout(handle, &status, timeout)) { - // If multiple threads wait on the same |handle| then one wait will succeed - // and the other will fail with errno set to ECHILD. - return exited || (errno == ECHILD); - } - if (WIFSIGNALED(status)) { - if (exit_code) - *exit_code = -1; - return true; - } - if (WIFEXITED(status)) { - if (exit_code) - *exit_code = WEXITSTATUS(status); - return true; - } - return exited; -} -#endif // !defined(OS_NACL_NONSFI) - -} // namespace - -namespace base { - -Process::Process(ProcessHandle handle) : process_(handle) {} - -Process::~Process() = default; - -Process::Process(Process&& other) : process_(other.process_) { - other.Close(); -} - -Process& Process::operator=(Process&& other) { - process_ = other.process_; - other.Close(); - return *this; -} - -// static -Process Process::Current() { - return Process(GetCurrentProcessHandle()); -} - -// static -Process Process::Open(ProcessId pid) { - if (pid == GetCurrentProcId()) - return Current(); - - // On POSIX process handles are the same as PIDs. - return Process(pid); -} - -// static -Process Process::OpenWithExtraPrivileges(ProcessId pid) { - // On POSIX there are no privileges to set. - return Open(pid); -} - -// static -void Process::TerminateCurrentProcessImmediately(int exit_code) { - _exit(exit_code); -} - -bool Process::IsValid() const { - return process_ != kNullProcessHandle; -} - -ProcessHandle Process::Handle() const { - return process_; -} - -Process Process::Duplicate() const { - if (is_current()) - return Current(); - - return Process(process_); -} - -ProcessId Process::Pid() const { - DCHECK(IsValid()); - return GetProcId(process_); -} - -bool Process::is_current() const { - return process_ == GetCurrentProcessHandle(); -} - -void Process::Close() { - process_ = kNullProcessHandle; - // if the process wasn't terminated (so we waited) or the state - // wasn't already collected w/ a wait from process_utils, we're gonna - // end up w/ a zombie when it does finally exit. -} - -#if !defined(OS_NACL_NONSFI) -bool Process::Terminate(int exit_code, bool wait) const { - // exit_code isn't supportable. - DCHECK(IsValid()); - CHECK_GT(process_, 0); - - bool did_terminate = kill(process_, SIGTERM) == 0; - - if (wait && did_terminate) { - if (WaitForExitWithTimeout(TimeDelta::FromSeconds(60), nullptr)) - return true; - did_terminate = kill(process_, SIGKILL) == 0; - if (did_terminate) - return WaitForExit(nullptr); - } - - if (!did_terminate) - DPLOG(ERROR) << "Unable to terminate process " << process_; - - return did_terminate; -} -#endif // !defined(OS_NACL_NONSFI) - -bool Process::WaitForExit(int* exit_code) const { - return WaitForExitWithTimeout(TimeDelta::Max(), exit_code); -} - -bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const { - int local_exit_code; - bool exited = WaitForExitWithTimeoutImpl(Handle(), &local_exit_code, timeout); - if (exited) { - Exited(local_exit_code); - if (exit_code) - *exit_code = local_exit_code; - } - return exited; -} - -void Process::Exited(int exit_code) const {} - -int Process::GetPriority() const { - DCHECK(IsValid()); - return getpriority(PRIO_PROCESS, process_); -} - -} // namespace base
diff --git a/base/process/process_win.cc b/base/process/process_win.cc deleted file mode 100644 index ce2b394..0000000 --- a/base/process/process_win.cc +++ /dev/null
@@ -1,167 +0,0 @@ -// Copyright (c) 2011 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. - -#include "base/process/process.h" - -#include "base/logging.h" -#include "base/numerics/safe_conversions.h" -#include "base/process/kill.h" - -#include <windows.h> - -namespace { - -DWORD kBasicProcessAccess = - PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | SYNCHRONIZE; - -} // namespace - -namespace base { - -Process::Process(ProcessHandle handle) - : process_(handle), is_current_process_(false) { - CHECK_NE(handle, ::GetCurrentProcess()); -} - -Process::Process(Process&& other) - : process_(other.process_.Take()), - is_current_process_(other.is_current_process_) { - other.Close(); -} - -Process::~Process() {} - -Process& Process::operator=(Process&& other) { - DCHECK_NE(this, &other); - process_.Set(other.process_.Take()); - is_current_process_ = other.is_current_process_; - other.Close(); - return *this; -} - -// static -Process Process::Current() { - Process process; - process.is_current_process_ = true; - return process; -} - -// static -Process Process::Open(ProcessId pid) { - return Process(::OpenProcess(kBasicProcessAccess, FALSE, pid)); -} - -// static -Process Process::OpenWithExtraPrivileges(ProcessId pid) { - DWORD access = kBasicProcessAccess | PROCESS_DUP_HANDLE | PROCESS_VM_READ; - return Process(::OpenProcess(access, FALSE, pid)); -} - -// static -Process Process::OpenWithAccess(ProcessId pid, DWORD desired_access) { - return Process(::OpenProcess(desired_access, FALSE, pid)); -} - -// static -void Process::TerminateCurrentProcessImmediately(int exit_code) { - ::TerminateProcess(GetCurrentProcess(), exit_code); - // There is some ambiguity over whether the call above can return. Rather than - // hitting confusing crashes later on we should crash right here. - IMMEDIATE_CRASH(); -} - -bool Process::IsValid() const { - return process_.IsValid() || is_current(); -} - -ProcessHandle Process::Handle() const { - return is_current_process_ ? GetCurrentProcess() : process_.Get(); -} - -Process Process::Duplicate() const { - if (is_current()) - return Current(); - - ProcessHandle out_handle; - if (!IsValid() || - !::DuplicateHandle(GetCurrentProcess(), Handle(), GetCurrentProcess(), - &out_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { - return Process(); - } - return Process(out_handle); -} - -ProcessId Process::Pid() const { - DCHECK(IsValid()); - return GetProcId(Handle()); -} - -bool Process::is_current() const { - return is_current_process_; -} - -void Process::Close() { - is_current_process_ = false; - if (!process_.IsValid()) - return; - - process_.Close(); -} - -bool Process::Terminate(int exit_code, bool wait) const { - constexpr DWORD kWaitMs = 60 * 1000; - - // exit_code cannot be implemented. - DCHECK(IsValid()); - bool result = (::TerminateProcess(Handle(), exit_code) != FALSE); - if (result) { - // The process may not end immediately due to pending I/O - if (wait && ::WaitForSingleObject(Handle(), kWaitMs) != WAIT_OBJECT_0) - DPLOG(ERROR) << "Error waiting for process exit"; - Exited(exit_code); - } else { - // The process can't be terminated, perhaps because it has already - // exited or is in the process of exiting. A non-zero timeout is necessary - // here for the same reasons as above. - DPLOG(ERROR) << "Unable to terminate process"; - if (::WaitForSingleObject(Handle(), kWaitMs) == WAIT_OBJECT_0) { - DWORD actual_exit; - Exited(::GetExitCodeProcess(Handle(), &actual_exit) ? actual_exit - : exit_code); - result = true; - } - } - return result; -} - -bool Process::WaitForExit(int* exit_code) const { - return WaitForExitWithTimeout(TimeDelta::FromMilliseconds(INFINITE), - exit_code); -} - -bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const { - // Limit timeout to INFINITE. - DWORD timeout_ms = saturated_cast<DWORD>(timeout.InMilliseconds()); - if (::WaitForSingleObject(Handle(), timeout_ms) != WAIT_OBJECT_0) - return false; - - DWORD temp_code; // Don't clobber out-parameters in case of failure. - if (!::GetExitCodeProcess(Handle(), &temp_code)) - return false; - - if (exit_code) - *exit_code = temp_code; - - Exited(temp_code); - return true; -} - -void Process::Exited(int exit_code) const {} - -int Process::GetPriority() const { - DCHECK(IsValid()); - return ::GetPriorityClass(Handle()); -} - -} // namespace base
diff --git a/build/gen.py b/build/gen.py index ffd2bbe..ff6084e 100755 --- a/build/gen.py +++ b/build/gen.py
@@ -244,10 +244,6 @@ 'base/md5.cc', 'base/memory/ref_counted.cc', 'base/memory/weak_ptr.cc', - 'base/process/kill.cc', - 'base/process/memory.cc', - 'base/process/process_handle.cc', - 'base/process/process_iterator.cc', 'base/sha1.cc', 'base/strings/string_number_conversions.cc', 'base/strings/string_piece.cc', @@ -471,9 +467,6 @@ 'base/files/file_util_posix.cc', 'base/posix/file_descriptor_shuffle.cc', 'base/posix/safe_strerror.cc', - 'base/process/kill_posix.cc', - 'base/process/process_handle_posix.cc', - 'base/process/process_posix.cc', 'base/strings/string16.cc', 'base/synchronization/condition_variable_posix.cc', 'base/synchronization/lock_impl_posix.cc', @@ -483,11 +476,6 @@ if is_linux: static_libraries['base']['sources'].extend([ - 'base/process/internal_linux.cc', - 'base/process/memory_linux.cc', - 'base/process/process_handle_linux.cc', - 'base/process/process_info_linux.cc', - 'base/process/process_iterator_linux.cc', 'base/strings/sys_string_conversions_posix.cc', 'base/synchronization/waitable_event_posix.cc', 'base/time/time_exploded_posix.cc', @@ -512,9 +500,6 @@ 'base/mac/mach_logging.cc', 'base/mac/scoped_mach_port.cc', 'base/mac/scoped_nsautorelease_pool.mm', - 'base/process/process_handle_mac.cc', - 'base/process/process_info_mac.cc', - 'base/process/process_iterator_mac.cc', 'base/strings/sys_string_conversions_mac.mm', 'base/synchronization/waitable_event_mac.cc', 'base/time/time_exploded_posix.cc', @@ -534,12 +519,6 @@ 'base/files/file_enumerator_win.cc', 'base/files/file_util_win.cc', 'base/files/file_win.cc', - 'base/process/kill_win.cc', - 'base/process/memory_win.cc', - 'base/process/process_handle_win.cc', - 'base/process/process_info_win.cc', - 'base/process/process_iterator_win.cc', - 'base/process/process_win.cc', 'base/strings/sys_string_conversions_win.cc', 'base/synchronization/condition_variable_win.cc', 'base/synchronization/lock_impl_win.cc',
diff --git a/tools/gn/exec_process.cc b/tools/gn/exec_process.cc index 6afc8a1..662fd68 100644 --- a/tools/gn/exec_process.cc +++ b/tools/gn/exec_process.cc
@@ -11,8 +11,6 @@ #include "base/command_line.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "base/process/kill.h" -#include "base/process/process.h" #include "build_config.h" #if defined(OS_WIN) @@ -23,6 +21,7 @@ #else #include <errno.h> #include <fcntl.h> +#include <sys/wait.h> #include <unistd.h> #include "base/posix/eintr_wrapper.h" @@ -37,6 +36,15 @@ std::string* std_out, std::string* std_err, int* exit_code) { + return ExecProcess(cmdline.GetCommandLineString(), startup_dir, std_out, + std_err, exit_code); +} + +bool ExecProcess(const base::string16& cmdline_str, + const base::FilePath& startup_dir, + std::string* std_out, + std::string* std_err, + int* exit_code) { SECURITY_ATTRIBUTES sa_attr; // Set the bInheritHandle flag so pipe handles are inherited. sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -65,16 +73,14 @@ // Ensure the read handle to the pipe for STDOUT/STDERR is not inherited. if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) { - NOTREACHED() << "Failed to disabled pipe inheritance"; + NOTREACHED() << "Failed to disable pipe inheritance"; return false; } if (!SetHandleInformation(err_read, HANDLE_FLAG_INHERIT, 0)) { - NOTREACHED() << "Failed to disabled pipe inheritance"; + NOTREACHED() << "Failed to disable pipe inheritance"; return false; } - base::FilePath::StringType cmdline_str(cmdline.GetCommandLineString()); - STARTUPINFO start_info = {}; start_info.cb = sizeof(STARTUPINFO); @@ -86,9 +92,11 @@ start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); start_info.dwFlags |= STARTF_USESTDHANDLES; + base::string16 cmdline_writable = cmdline_str; + // Create the child process. PROCESS_INFORMATION temp_process_info = {}; - if (!CreateProcess(nullptr, &cmdline_str[0], nullptr, nullptr, + if (!CreateProcess(nullptr, &cmdline_writable[0], nullptr, nullptr, TRUE, // Handles are inherited. NORMAL_PRIORITY_CLASS, nullptr, startup_dir.value().c_str(), &start_info, @@ -97,8 +105,8 @@ } base::win::ScopedProcessInformation proc_info(temp_process_info); - // Close our writing end of pipes now. Otherwise later read would not be able - // to detect end of child's output. + // Close our writing end of pipes now. Otherwise later read would not be + // able to detect end of child's output. scoped_out_write.Close(); scoped_err_write.Close(); @@ -143,6 +151,24 @@ return true; } +bool WaitForExit(int pid, int *exit_code) { + int status; + if (waitpid(pid, &status, 0) < 0) { + PLOG(ERROR) << "waitpid"; + return false; + } + + if (WIFEXITED(status)) { + *exit_code = WEXITSTATUS(status); + return true; + } else if (WIFSIGNALED(status)) { + if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM + || WTERMSIG(status) == SIGHUP) + return false; + } + return false; +} + bool ExecProcess(const base::CommandLine& cmdline, const base::FilePath& startup_dir, std::string* std_out, @@ -243,8 +269,7 @@ err_open = ReadFromPipe(err_read.get(), std_err); } - base::Process process(pid); - return process.WaitForExit(exit_code); + return WaitForExit(pid, exit_code); } }
diff --git a/tools/gn/exec_process.h b/tools/gn/exec_process.h index 43c2a1d..f361ba8 100644 --- a/tools/gn/exec_process.h +++ b/tools/gn/exec_process.h
@@ -7,6 +7,9 @@ #include <string> +#include "base/strings/string16.h" +#include "build_config.h" + namespace base { class CommandLine; class FilePath; @@ -20,6 +23,14 @@ std::string* std_err, int* exit_code); +#if defined(OS_WIN) +bool ExecProcess(const base::string16& cmdline_str, + const base::FilePath& startup_dir, + std::string* std_out, + std::string* std_err, + int* exit_code); +#endif // OS_WIN + } // namespace internal #endif // TOOLS_GN_EXEC_PROCESS_H_
diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc index 7953939..f1933f6 100644 --- a/tools/gn/ninja_build_writer.cc +++ b/tools/gn/ninja_build_writer.cc
@@ -13,7 +13,6 @@ #include "base/command_line.h" #include "base/files/file_util.h" -#include "base/process/process_handle.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build_config.h"
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc index 726b037..0b27244 100644 --- a/tools/gn/setup.cc +++ b/tools/gn/setup.cc
@@ -16,7 +16,6 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/memory/ref_counted.h" -#include "base/process/kill.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" @@ -24,6 +23,7 @@ #include "build_config.h" #include "tools/gn/command_format.h" #include "tools/gn/commands.h" +#include "tools/gn/exec_process.h" #include "tools/gn/filesystem_utils.h" #include "tools/gn/input_file.h" #include "tools/gn/parse_tree.h" @@ -190,83 +190,6 @@ #if defined(OS_WIN) -bool GetAppOutput(const base::StringPiece16& cl, std::string* output) { - HANDLE out_read = nullptr; - HANDLE out_write = nullptr; - - SECURITY_ATTRIBUTES sa_attr; - // Set the bInheritHandle flag so pipe handles are inherited. - sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); - sa_attr.bInheritHandle = TRUE; - sa_attr.lpSecurityDescriptor = nullptr; - - // Create the pipe for the child process's STDOUT. - if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) { - NOTREACHED() << "Failed to create pipe"; - return false; - } - - // Ensure we don't leak the handles. - base::win::ScopedHandle scoped_out_read(out_read); - base::win::ScopedHandle scoped_out_write(out_write); - - // Ensure the read handles to the pipes are not inherited. - if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) { - NOTREACHED() << "Failed to disabled pipe inheritance"; - return false; - } - - base::FilePath::StringType writable_command_line_string; - writable_command_line_string.assign(cl.data(), cl.size()); - - STARTUPINFO start_info = {}; - - start_info.cb = sizeof(STARTUPINFO); - start_info.hStdOutput = out_write; - // Keep the normal stdin/stderr. - start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); - start_info.dwFlags |= STARTF_USESTDHANDLES; - - // Create the child process. - PROCESS_INFORMATION temp_process_info = {}; - if (!CreateProcess(nullptr, &writable_command_line_string[0], nullptr, - nullptr, - TRUE, // Handles are inherited. - 0, nullptr, nullptr, &start_info, &temp_process_info)) { - NOTREACHED() << "Failed to start process"; - return false; - } - - base::win::ScopedProcessInformation proc_info(temp_process_info); - - // Close our writing end of pipe now. Otherwise later read would not be able - // to detect end of child's output. - scoped_out_write.Close(); - - // Read output from the child process's pipe for STDOUT - const int kBufferSize = 1024; - char buffer[kBufferSize]; - - for (;;) { - DWORD bytes_read = 0; - BOOL success = - ::ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr); - if (!success || bytes_read == 0) - break; - output->append(buffer, bytes_read); - } - - // Let's wait for the process to finish. - WaitForSingleObject(proc_info.process_handle(), INFINITE); - - int exit_code; - base::TerminationStatus status = - base::GetTerminationStatus(proc_info.process_handle(), &exit_code); - return status != base::TERMINATION_STATUS_PROCESS_CRASHED && - status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION; -} - // Given the path to a batch file that runs Python, extracts the name of the // executable actually implementing Python. Generally people write a batch file // to put something named "python" on the path, which then just redirects to @@ -283,7 +206,12 @@ command.append(L"\" -c \"import sys; print sys.executable\"\""); std::string python_path; - if (GetAppOutput(command, &python_path)) { + std::string std_err; + int exit_code; + base::FilePath cwd; + GetCurrentDirectory(&cwd); + if (internal::ExecProcess(command, cwd, &python_path, &std_err, &exit_code) && + exit_code == 0 && std_err.empty()) { base::TrimWhitespaceASCII(python_path, base::TRIM_ALL, &python_path); // Python uses the system multibyte code page for sys.executable.