1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file contains methods to iterate over processes on the system.
6
7#ifndef BASE_PROCESS_PROCESS_ITERATOR_H_
8#define BASE_PROCESS_PROCESS_ITERATOR_H_
9
10#include <list>
11#include <string>
12#include <vector>
13
14#include "base/base_export.h"
15#include "base/basictypes.h"
16#include "base/files/file_path.h"
17#include "base/process/process.h"
18#include "build/build_config.h"
19
20#if defined(OS_WIN)
21#include <windows.h>
22#include <tlhelp32.h>
23#elif defined(OS_MACOSX) || defined(OS_OPENBSD)
24#include <sys/sysctl.h>
25#elif defined(OS_FREEBSD)
26#include <sys/user.h>
27#elif defined(OS_POSIX)
28#include <dirent.h>
29#endif
30
31namespace base {
32
33#if defined(OS_WIN)
34struct ProcessEntry : public PROCESSENTRY32 {
35  ProcessId pid() const { return th32ProcessID; }
36  ProcessId parent_pid() const { return th32ParentProcessID; }
37  const wchar_t* exe_file() const { return szExeFile; }
38};
39
40// Process access masks. These constants provide platform-independent
41// definitions for the standard Windows access masks.
42// See http://msdn.microsoft.com/en-us/library/ms684880(VS.85).aspx for
43// the specific semantics of each mask value.
44const uint32 kProcessAccessTerminate              = PROCESS_TERMINATE;
45const uint32 kProcessAccessCreateThread           = PROCESS_CREATE_THREAD;
46const uint32 kProcessAccessSetSessionId           = PROCESS_SET_SESSIONID;
47const uint32 kProcessAccessVMOperation            = PROCESS_VM_OPERATION;
48const uint32 kProcessAccessVMRead                 = PROCESS_VM_READ;
49const uint32 kProcessAccessVMWrite                = PROCESS_VM_WRITE;
50const uint32 kProcessAccessDuplicateHandle        = PROCESS_DUP_HANDLE;
51const uint32 kProcessAccessCreateProcess          = PROCESS_CREATE_PROCESS;
52const uint32 kProcessAccessSetQuota               = PROCESS_SET_QUOTA;
53const uint32 kProcessAccessSetInformation         = PROCESS_SET_INFORMATION;
54const uint32 kProcessAccessQueryInformation       = PROCESS_QUERY_INFORMATION;
55const uint32 kProcessAccessSuspendResume          = PROCESS_SUSPEND_RESUME;
56const uint32 kProcessAccessQueryLimitedInfomation =
57    PROCESS_QUERY_LIMITED_INFORMATION;
58const uint32 kProcessAccessWaitForTermination     = SYNCHRONIZE;
59#elif defined(OS_POSIX)
60struct BASE_EXPORT ProcessEntry {
61  ProcessEntry();
62  ~ProcessEntry();
63
64  ProcessId pid() const { return pid_; }
65  ProcessId parent_pid() const { return ppid_; }
66  ProcessId gid() const { return gid_; }
67  const char* exe_file() const { return exe_file_.c_str(); }
68  const std::vector<std::string>& cmd_line_args() const {
69    return cmd_line_args_;
70  }
71
72  ProcessId pid_;
73  ProcessId ppid_;
74  ProcessId gid_;
75  std::string exe_file_;
76  std::vector<std::string> cmd_line_args_;
77};
78
79// Process access masks. They are not used on Posix because access checking
80// does not happen during handle creation.
81const uint32 kProcessAccessTerminate              = 0;
82const uint32 kProcessAccessCreateThread           = 0;
83const uint32 kProcessAccessSetSessionId           = 0;
84const uint32 kProcessAccessVMOperation            = 0;
85const uint32 kProcessAccessVMRead                 = 0;
86const uint32 kProcessAccessVMWrite                = 0;
87const uint32 kProcessAccessDuplicateHandle        = 0;
88const uint32 kProcessAccessCreateProcess          = 0;
89const uint32 kProcessAccessSetQuota               = 0;
90const uint32 kProcessAccessSetInformation         = 0;
91const uint32 kProcessAccessQueryInformation       = 0;
92const uint32 kProcessAccessSuspendResume          = 0;
93const uint32 kProcessAccessQueryLimitedInfomation = 0;
94const uint32 kProcessAccessWaitForTermination     = 0;
95#endif  // defined(OS_POSIX)
96
97// Used to filter processes by process ID.
98class ProcessFilter {
99 public:
100  // Returns true to indicate set-inclusion and false otherwise.  This method
101  // should not have side-effects and should be idempotent.
102  virtual bool Includes(const ProcessEntry& entry) const = 0;
103
104 protected:
105  virtual ~ProcessFilter() {}
106};
107
108// This class provides a way to iterate through a list of processes on the
109// current machine with a specified filter.
110// To use, create an instance and then call NextProcessEntry() until it returns
111// false.
112class BASE_EXPORT ProcessIterator {
113 public:
114  typedef std::list<ProcessEntry> ProcessEntries;
115
116  explicit ProcessIterator(const ProcessFilter* filter);
117  virtual ~ProcessIterator();
118
119  // If there's another process that matches the given executable name,
120  // returns a const pointer to the corresponding PROCESSENTRY32.
121  // If there are no more matching processes, returns NULL.
122  // The returned pointer will remain valid until NextProcessEntry()
123  // is called again or this NamedProcessIterator goes out of scope.
124  const ProcessEntry* NextProcessEntry();
125
126  // Takes a snapshot of all the ProcessEntry found.
127  ProcessEntries Snapshot();
128
129 protected:
130  virtual bool IncludeEntry();
131  const ProcessEntry& entry() { return entry_; }
132
133 private:
134  // Determines whether there's another process (regardless of executable)
135  // left in the list of all processes.  Returns true and sets entry_ to
136  // that process's info if there is one, false otherwise.
137  bool CheckForNextProcess();
138
139  // Initializes a PROCESSENTRY32 data structure so that it's ready for
140  // use with Process32First/Process32Next.
141  void InitProcessEntry(ProcessEntry* entry);
142
143#if defined(OS_WIN)
144  HANDLE snapshot_;
145  bool started_iteration_;
146#elif defined(OS_MACOSX) || defined(OS_BSD)
147  std::vector<kinfo_proc> kinfo_procs_;
148  size_t index_of_kinfo_proc_;
149#elif defined(OS_POSIX)
150  DIR* procfs_dir_;
151#endif
152  ProcessEntry entry_;
153  const ProcessFilter* filter_;
154
155  DISALLOW_COPY_AND_ASSIGN(ProcessIterator);
156};
157
158// This class provides a way to iterate through the list of processes
159// on the current machine that were started from the given executable
160// name.  To use, create an instance and then call NextProcessEntry()
161// until it returns false.
162class BASE_EXPORT NamedProcessIterator : public ProcessIterator {
163 public:
164  NamedProcessIterator(const FilePath::StringType& executable_name,
165                       const ProcessFilter* filter);
166  virtual ~NamedProcessIterator();
167
168 protected:
169  virtual bool IncludeEntry() OVERRIDE;
170
171 private:
172  FilePath::StringType executable_name_;
173
174  DISALLOW_COPY_AND_ASSIGN(NamedProcessIterator);
175};
176
177// Returns the number of processes on the machine that are running from the
178// given executable name.  If filter is non-null, then only processes selected
179// by the filter will be counted.
180BASE_EXPORT int GetProcessCount(const FilePath::StringType& executable_name,
181                                const ProcessFilter* filter);
182
183}  // namespace base
184
185#endif  // BASE_PROCESS_PROCESS_ITERATOR_H_
186