summaryrefslogtreecommitdiffstats
path: root/base/process_util_mac.mm
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-05 21:44:13 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-05 21:44:13 +0000
commit962dd31f9cff7017d90da505e077ea84db9c5e48 (patch)
tree821a70988ea4e963be58314c5b9b7becab7312fe /base/process_util_mac.mm
parent3115504c55a338fb3de3684a85b2383b4c4dbbc0 (diff)
downloadchromium_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.mm118
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;
}