diff options
author | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-05 21:44:13 +0000 |
---|---|---|
committer | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-05 21:44:13 +0000 |
commit | 962dd31f9cff7017d90da505e077ea84db9c5e48 (patch) | |
tree | 821a70988ea4e963be58314c5b9b7becab7312fe /base/process_util_mac.mm | |
parent | 3115504c55a338fb3de3684a85b2383b4c4dbbc0 (diff) | |
download | chromium_src-962dd31f9cff7017d90da505e077ea84db9c5e48.zip chromium_src-962dd31f9cff7017d90da505e077ea84db9c5e48.tar.gz chromium_src-962dd31f9cff7017d90da505e077ea84db9c5e48.tar.bz2 |
Implement NamedProcessIterator in base/process_util_mac.mm. Patch by Naoki
Takano <takano.naoki@gmail.com>
Review URL: http://codereview.chromium.org/18192
Review URL: http://codereview.chromium.org/21097
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9263 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process_util_mac.mm')
-rw-r--r-- | base/process_util_mac.mm | 118 |
1 files changed, 104 insertions, 14 deletions
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm index 6dd865b..501205c 100644 --- a/base/process_util_mac.mm +++ b/base/process_util_mac.mm @@ -3,16 +3,21 @@ // found in the LICENSE file. -#include "base/logging.h" #include "base/process_util.h" #import <Cocoa/Cocoa.h> #include <crt_externs.h> #include <spawn.h> -#include <string> +#include <sys/sysctl.h> #include <sys/types.h> #include <sys/wait.h> +#include <string> + +#include "base/logging.h" +#include "base/string_util.h" +#include "base/time.h" + namespace base { bool LaunchApp(const std::vector<std::string>& argv, @@ -73,7 +78,7 @@ bool LaunchApp(const std::vector<std::string>& argv, if (wait) waitpid(pid, 0, 0); - if(process_handle) + if (process_handle) *process_handle = pid; } @@ -87,21 +92,106 @@ bool LaunchApp(const CommandLine& cl, return LaunchApp(cl.argv(), no_files, wait, process_handle); } -bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) { - // TODO(pinkerton): can we implement this? On linux it relies on /proc. - return false; +NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name, + const ProcessFilter* filter) + : executable_name_(executable_name), + index_of_kinfo_proc_(0), + filter_(filter) { } -int GetProcessCount(const std::wstring& executable_name, - const ProcessFilter* filter) { - NOTIMPLEMENTED(); - return 0; +NamedProcessIterator::~NamedProcessIterator() { } -bool CleanupProcesses(const std::wstring& executable_name, - int wait_milliseconds, - int exit_code, - const ProcessFilter* filter) { +const ProcessEntry* NamedProcessIterator::NextProcessEntry() { + // Every call, you have to get new kinfo_procs_. + // Because the process status might be changed. + int num_of_kinfo_proc = 0; + index_of_kinfo_proc_ = 0; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; + size_t len = 0; + + if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) + return NULL; + + num_of_kinfo_proc = len / sizeof(struct kinfo_proc); + // Leave some spare room for process table growth. + 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) + return NULL; + + num_of_kinfo_proc = len / sizeof(struct kinfo_proc); + kinfo_procs_.resize(num_of_kinfo_proc); + + bool result = false; + do { + result = CheckForNextProcess(); + } while (result && !IncludeEntry()); + + if (result) + return &entry_; + + return NULL; +} + +bool NamedProcessIterator::CheckForNextProcess() { + std::string exec_name; + kinfo_proc* kinfo = NULL; + for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) { + if (kinfo_procs_[index_of_kinfo_proc_].kp_proc.p_stat != SZOMB) { + kinfo = &kinfo_procs_[index_of_kinfo_proc_]; + + int mib[] = { KERN_PROCARGS, KERN_PROCARGS, kinfo->kp_proc.p_pid }; + + size_t data_len = 0; + if (sysctl(mib, arraysize(mib), NULL, &data_len, NULL, 0) < 0) + continue; + + std::string data; + data.resize(data_len); + if (sysctl(mib, arraysize(mib), &data[0], &data_len, NULL, 0) < 0) + continue; + + // "data" has absolute process path with '/', + // so we get the last part as execution process name. + + int exec_name_end = data.find('\0'); + int last_slash = data.rfind('/', exec_name_end); + + // If the index is not -1, it means valid exec name is found. + // Get the exec name and store the name into exec_name and break. + // "last_slash" point is '/', so get substr from the next. + if (last_slash != -1) { + exec_name = data.substr(exec_name_end - last_slash - 1); + } else { + exec_name = data.substr(0, exec_name_end); + } + break; + } + } + + if (index_of_kinfo_proc_ >= kinfo_procs_.size()) + return false; + + entry_.pid = kinfo->kp_proc.p_pid; + entry_.ppid = kinfo->kp_proc.p_oppid; + + base::strlcpy(entry_.szExeFile, exec_name.c_str(), sizeof(entry_.szExeFile)); + + return true; +} + +bool NamedProcessIterator::IncludeEntry() { + if (WideToUTF8(executable_name_) != entry_.szExeFile) + return false; + if (!filter_) + return true; + return filter_->Includes(entry_.pid, entry_.ppid); +} + +bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) { + // TODO(pinkerton): can we implement this? On linux it relies on /proc. NOTIMPLEMENTED(); return false; } |