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 <stddef.h> 11 12 #include <list> 13 #include <string> 14 #include <vector> 15 16 #include "base/base_export.h" 17 #include "base/files/file_path.h" 18 #include "base/macros.h" 19 #include "base/process/process.h" 20 #include "build/build_config.h" 21 22 #if defined(OS_WIN) 23 #include <windows.h> 24 #include <tlhelp32.h> 25 #elif defined(OS_MACOSX) || defined(OS_OPENBSD) 26 #include <sys/sysctl.h> 27 #elif defined(OS_FREEBSD) 28 #include <sys/user.h> 29 #elif defined(OS_POSIX) 30 #include <dirent.h> 31 #endif 32 33 namespace base { 34 35 #if defined(OS_WIN) 36 struct ProcessEntry : public PROCESSENTRY32 { pidProcessEntry37 ProcessId pid() const { return th32ProcessID; } parent_pidProcessEntry38 ProcessId parent_pid() const { return th32ParentProcessID; } exe_fileProcessEntry39 const wchar_t* exe_file() const { return szExeFile; } 40 }; 41 #elif defined(OS_POSIX) 42 struct BASE_EXPORT ProcessEntry { 43 ProcessEntry(); 44 ProcessEntry(const ProcessEntry& other); 45 ~ProcessEntry(); 46 47 ProcessId pid() const { return pid_; } 48 ProcessId parent_pid() const { return ppid_; } 49 ProcessId gid() const { return gid_; } 50 const char* exe_file() const { return exe_file_.c_str(); } 51 const std::vector<std::string>& cmd_line_args() const { 52 return cmd_line_args_; 53 } 54 55 ProcessId pid_; 56 ProcessId ppid_; 57 ProcessId gid_; 58 std::string exe_file_; 59 std::vector<std::string> cmd_line_args_; 60 }; 61 #endif // defined(OS_POSIX) 62 63 // Used to filter processes by process ID. 64 class ProcessFilter { 65 public: 66 // Returns true to indicate set-inclusion and false otherwise. This method 67 // should not have side-effects and should be idempotent. 68 virtual bool Includes(const ProcessEntry& entry) const = 0; 69 70 protected: ~ProcessFilter()71 virtual ~ProcessFilter() {} 72 }; 73 74 // This class provides a way to iterate through a list of processes on the 75 // current machine with a specified filter. 76 // To use, create an instance and then call NextProcessEntry() until it returns 77 // false. 78 class BASE_EXPORT ProcessIterator { 79 public: 80 typedef std::list<ProcessEntry> ProcessEntries; 81 82 explicit ProcessIterator(const ProcessFilter* filter); 83 virtual ~ProcessIterator(); 84 85 // If there's another process that matches the given executable name, 86 // returns a const pointer to the corresponding PROCESSENTRY32. 87 // If there are no more matching processes, returns NULL. 88 // The returned pointer will remain valid until NextProcessEntry() 89 // is called again or this NamedProcessIterator goes out of scope. 90 const ProcessEntry* NextProcessEntry(); 91 92 // Takes a snapshot of all the ProcessEntry found. 93 ProcessEntries Snapshot(); 94 95 protected: 96 virtual bool IncludeEntry(); entry()97 const ProcessEntry& entry() { return entry_; } 98 99 private: 100 // Determines whether there's another process (regardless of executable) 101 // left in the list of all processes. Returns true and sets entry_ to 102 // that process's info if there is one, false otherwise. 103 bool CheckForNextProcess(); 104 105 // Initializes a PROCESSENTRY32 data structure so that it's ready for 106 // use with Process32First/Process32Next. 107 void InitProcessEntry(ProcessEntry* entry); 108 109 #if defined(OS_WIN) 110 HANDLE snapshot_; 111 bool started_iteration_; 112 #elif defined(OS_MACOSX) || defined(OS_BSD) 113 std::vector<kinfo_proc> kinfo_procs_; 114 size_t index_of_kinfo_proc_; 115 #elif defined(OS_POSIX) 116 DIR* procfs_dir_; 117 #endif 118 ProcessEntry entry_; 119 const ProcessFilter* filter_; 120 121 DISALLOW_COPY_AND_ASSIGN(ProcessIterator); 122 }; 123 124 // This class provides a way to iterate through the list of processes 125 // on the current machine that were started from the given executable 126 // name. To use, create an instance and then call NextProcessEntry() 127 // until it returns false. 128 class BASE_EXPORT NamedProcessIterator : public ProcessIterator { 129 public: 130 NamedProcessIterator(const FilePath::StringType& executable_name, 131 const ProcessFilter* filter); 132 ~NamedProcessIterator() override; 133 134 protected: 135 bool IncludeEntry() override; 136 137 private: 138 FilePath::StringType executable_name_; 139 140 DISALLOW_COPY_AND_ASSIGN(NamedProcessIterator); 141 }; 142 143 // Returns the number of processes on the machine that are running from the 144 // given executable name. If filter is non-null, then only processes selected 145 // by the filter will be counted. 146 BASE_EXPORT int GetProcessCount(const FilePath::StringType& executable_name, 147 const ProcessFilter* filter); 148 149 } // namespace base 150 151 #endif // BASE_PROCESS_PROCESS_ITERATOR_H_ 152