1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This file contains methods to iterate over processes on the system.
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef BASE_PROCESS_PROCESS_ITERATOR_H_
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define BASE_PROCESS_PROCESS_ITERATOR_H_
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <list>
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string>
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector>
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/base_export.h"
1558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/basictypes.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_path.h"
1758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process.h"
1858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "build/build_config.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN)
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <windows.h>
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <tlhelp32.h>
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_MACOSX) || defined(OS_OPENBSD)
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <sys/sysctl.h>
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_FREEBSD)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <sys/user.h>
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_POSIX)
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <dirent.h>
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace base {
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN)
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct ProcessEntry : public PROCESSENTRY32 {
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId pid() const { return th32ProcessID; }
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId parent_pid() const { return th32ParentProcessID; }
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const wchar_t* exe_file() const { return szExeFile; }
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Process access masks. These constants provide platform-independent
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// definitions for the standard Windows access masks.
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// See http://msdn.microsoft.com/en-us/library/ms684880(VS.85).aspx for
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// the specific semantics of each mask value.
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessTerminate              = PROCESS_TERMINATE;
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessCreateThread           = PROCESS_CREATE_THREAD;
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSetSessionId           = PROCESS_SET_SESSIONID;
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessVMOperation            = PROCESS_VM_OPERATION;
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessVMRead                 = PROCESS_VM_READ;
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessVMWrite                = PROCESS_VM_WRITE;
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessDuplicateHandle        = PROCESS_DUP_HANDLE;
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessCreateProcess          = PROCESS_CREATE_PROCESS;
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSetQuota               = PROCESS_SET_QUOTA;
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSetInformation         = PROCESS_SET_INFORMATION;
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessQueryInformation       = PROCESS_QUERY_INFORMATION;
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSuspendResume          = PROCESS_SUSPEND_RESUME;
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessQueryLimitedInfomation =
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    PROCESS_QUERY_LIMITED_INFORMATION;
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessWaitForTermination     = SYNCHRONIZE;
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_POSIX)
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct BASE_EXPORT ProcessEntry {
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessEntry();
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ~ProcessEntry();
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId pid() const { return pid_; }
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId parent_pid() const { return ppid_; }
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId gid() const { return gid_; }
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const char* exe_file() const { return exe_file_.c_str(); }
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const std::vector<std::string>& cmd_line_args() const {
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return cmd_line_args_;
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId pid_;
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId ppid_;
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessId gid_;
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string exe_file_;
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<std::string> cmd_line_args_;
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Process access masks. They are not used on Posix because access checking
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// does not happen during handle creation.
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessTerminate              = 0;
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessCreateThread           = 0;
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSetSessionId           = 0;
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessVMOperation            = 0;
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessVMRead                 = 0;
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessVMWrite                = 0;
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessDuplicateHandle        = 0;
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessCreateProcess          = 0;
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSetQuota               = 0;
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSetInformation         = 0;
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessQueryInformation       = 0;
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessSuspendResume          = 0;
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessQueryLimitedInfomation = 0;
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32 kProcessAccessWaitForTermination     = 0;
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // defined(OS_POSIX)
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Used to filter processes by process ID.
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ProcessFilter {
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Returns true to indicate set-inclusion and false otherwise.  This method
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // should not have side-effects and should be idempotent.
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual bool Includes(const ProcessEntry& entry) const = 0;
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~ProcessFilter() {}
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This class provides a way to iterate through a list of processes on the
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// current machine with a specified filter.
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// To use, create an instance and then call NextProcessEntry() until it returns
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// false.
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class BASE_EXPORT ProcessIterator {
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  typedef std::list<ProcessEntry> ProcessEntries;
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit ProcessIterator(const ProcessFilter* filter);
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~ProcessIterator();
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If there's another process that matches the given executable name,
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // returns a const pointer to the corresponding PROCESSENTRY32.
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If there are no more matching processes, returns NULL.
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The returned pointer will remain valid until NextProcessEntry()
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // is called again or this NamedProcessIterator goes out of scope.
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const ProcessEntry* NextProcessEntry();
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Takes a snapshot of all the ProcessEntry found.
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessEntries Snapshot();
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual bool IncludeEntry();
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const ProcessEntry& entry() { return entry_; }
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Determines whether there's another process (regardless of executable)
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // left in the list of all processes.  Returns true and sets entry_ to
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // that process's info if there is one, false otherwise.
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool CheckForNextProcess();
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Initializes a PROCESSENTRY32 data structure so that it's ready for
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // use with Process32First/Process32Next.
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void InitProcessEntry(ProcessEntry* entry);
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN)
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HANDLE snapshot_;
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool started_iteration_;
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_MACOSX) || defined(OS_BSD)
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<kinfo_proc> kinfo_procs_;
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t index_of_kinfo_proc_;
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#elif defined(OS_POSIX)
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DIR* procfs_dir_;
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProcessEntry entry_;
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const ProcessFilter* filter_;
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ProcessIterator);
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This class provides a way to iterate through the list of processes
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// on the current machine that were started from the given executable
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// name.  To use, create an instance and then call NextProcessEntry()
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// until it returns false.
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class BASE_EXPORT NamedProcessIterator : public ProcessIterator {
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NamedProcessIterator(const FilePath::StringType& executable_name,
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const ProcessFilter* filter);
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~NamedProcessIterator();
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual bool IncludeEntry() OVERRIDE;
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FilePath::StringType executable_name_;
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NamedProcessIterator);
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Returns the number of processes on the machine that are running from the
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// given executable name.  If filter is non-null, then only processes selected
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// by the filter will be counted.
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)BASE_EXPORT int GetProcessCount(const FilePath::StringType& executable_name,
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                const ProcessFilter* filter);
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace base
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // BASE_PROCESS_PROCESS_ITERATOR_H_
186