1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker // This file contains methods to iterate over processes on the system. 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker #ifndef BASE_PROCESS_PROCESS_ITERATOR_H_ 8*6777b538SAndroid Build Coastguard Worker #define BASE_PROCESS_PROCESS_ITERATOR_H_ 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include <list> 13*6777b538SAndroid Build Coastguard Worker #include <string> 14*6777b538SAndroid Build Coastguard Worker #include <vector> 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 19*6777b538SAndroid Build Coastguard Worker #include "base/process/process.h" 20*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h" 21*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 24*6777b538SAndroid Build Coastguard Worker #include <windows.h> 25*6777b538SAndroid Build Coastguard Worker 26*6777b538SAndroid Build Coastguard Worker #include <tlhelp32.h> 27*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_OPENBSD) 28*6777b538SAndroid Build Coastguard Worker #include <sys/sysctl.h> 29*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FREEBSD) 30*6777b538SAndroid Build Coastguard Worker #include <sys/user.h> 31*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 32*6777b538SAndroid Build Coastguard Worker #include <dirent.h> 33*6777b538SAndroid Build Coastguard Worker #endif 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker namespace base { 36*6777b538SAndroid Build Coastguard Worker 37*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 38*6777b538SAndroid Build Coastguard Worker struct ProcessEntry : public PROCESSENTRY32 { pidProcessEntry39*6777b538SAndroid Build Coastguard Worker ProcessId pid() const { return th32ProcessID; } parent_pidProcessEntry40*6777b538SAndroid Build Coastguard Worker ProcessId parent_pid() const { return th32ParentProcessID; } exe_fileProcessEntry41*6777b538SAndroid Build Coastguard Worker const wchar_t* exe_file() const { return szExeFile; } 42*6777b538SAndroid Build Coastguard Worker }; 43*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 44*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT ProcessEntry { 45*6777b538SAndroid Build Coastguard Worker ProcessEntry(); 46*6777b538SAndroid Build Coastguard Worker ProcessEntry(const ProcessEntry& other); 47*6777b538SAndroid Build Coastguard Worker ~ProcessEntry(); 48*6777b538SAndroid Build Coastguard Worker 49*6777b538SAndroid Build Coastguard Worker ProcessId pid() const { return pid_; } 50*6777b538SAndroid Build Coastguard Worker ProcessId parent_pid() const { return ppid_; } 51*6777b538SAndroid Build Coastguard Worker ProcessId gid() const { return gid_; } 52*6777b538SAndroid Build Coastguard Worker const char* exe_file() const { return exe_file_.c_str(); } 53*6777b538SAndroid Build Coastguard Worker const std::vector<std::string>& cmd_line_args() const { 54*6777b538SAndroid Build Coastguard Worker return cmd_line_args_; 55*6777b538SAndroid Build Coastguard Worker } 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker ProcessId pid_; 58*6777b538SAndroid Build Coastguard Worker ProcessId ppid_; 59*6777b538SAndroid Build Coastguard Worker ProcessId gid_; 60*6777b538SAndroid Build Coastguard Worker std::string exe_file_; 61*6777b538SAndroid Build Coastguard Worker std::vector<std::string> cmd_line_args_; 62*6777b538SAndroid Build Coastguard Worker }; 63*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN) 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // Used to filter processes by process ID. 66*6777b538SAndroid Build Coastguard Worker class ProcessFilter { 67*6777b538SAndroid Build Coastguard Worker public: 68*6777b538SAndroid Build Coastguard Worker // Returns true to indicate set-inclusion and false otherwise. This method 69*6777b538SAndroid Build Coastguard Worker // should not have side-effects and should be idempotent. 70*6777b538SAndroid Build Coastguard Worker virtual bool Includes(const ProcessEntry& entry) const = 0; 71*6777b538SAndroid Build Coastguard Worker 72*6777b538SAndroid Build Coastguard Worker protected: 73*6777b538SAndroid Build Coastguard Worker virtual ~ProcessFilter() = default; 74*6777b538SAndroid Build Coastguard Worker }; 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker // This class provides a way to iterate through a list of processes on the 77*6777b538SAndroid Build Coastguard Worker // current machine with a specified filter. 78*6777b538SAndroid Build Coastguard Worker // To use, create an instance and then call NextProcessEntry() until it returns 79*6777b538SAndroid Build Coastguard Worker // false. 80*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ProcessIterator { 81*6777b538SAndroid Build Coastguard Worker public: 82*6777b538SAndroid Build Coastguard Worker typedef std::list<ProcessEntry> ProcessEntries; 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker explicit ProcessIterator(const ProcessFilter* filter); 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker ProcessIterator(const ProcessIterator&) = delete; 87*6777b538SAndroid Build Coastguard Worker ProcessIterator& operator=(const ProcessIterator&) = delete; 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker virtual ~ProcessIterator(); 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker // If there's another process that matches the given executable name, 92*6777b538SAndroid Build Coastguard Worker // returns a const pointer to the corresponding PROCESSENTRY32. 93*6777b538SAndroid Build Coastguard Worker // If there are no more matching processes, returns NULL. 94*6777b538SAndroid Build Coastguard Worker // The returned pointer will remain valid until NextProcessEntry() 95*6777b538SAndroid Build Coastguard Worker // is called again or this NamedProcessIterator goes out of scope. 96*6777b538SAndroid Build Coastguard Worker const ProcessEntry* NextProcessEntry(); 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker // Takes a snapshot of all the ProcessEntry found. 99*6777b538SAndroid Build Coastguard Worker ProcessEntries Snapshot(); 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker protected: 102*6777b538SAndroid Build Coastguard Worker virtual bool IncludeEntry(); entry()103*6777b538SAndroid Build Coastguard Worker const ProcessEntry& entry() { return entry_; } 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker private: 106*6777b538SAndroid Build Coastguard Worker // Determines whether there's another process (regardless of executable) 107*6777b538SAndroid Build Coastguard Worker // left in the list of all processes. Returns true and sets entry_ to 108*6777b538SAndroid Build Coastguard Worker // that process's info if there is one, false otherwise. 109*6777b538SAndroid Build Coastguard Worker bool CheckForNextProcess(); 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker // Initializes a PROCESSENTRY32 data structure so that it's ready for 112*6777b538SAndroid Build Coastguard Worker // use with Process32First/Process32Next. 113*6777b538SAndroid Build Coastguard Worker void InitProcessEntry(ProcessEntry* entry); 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 116*6777b538SAndroid Build Coastguard Worker HANDLE snapshot_; 117*6777b538SAndroid Build Coastguard Worker bool started_iteration_ = false; 118*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_BSD) 119*6777b538SAndroid Build Coastguard Worker std::vector<kinfo_proc> kinfo_procs_; 120*6777b538SAndroid Build Coastguard Worker size_t index_of_kinfo_proc_ = 0; 121*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) 122*6777b538SAndroid Build Coastguard Worker struct DIRClose { operatorDIRClose123*6777b538SAndroid Build Coastguard Worker inline void operator()(DIR* x) const { 124*6777b538SAndroid Build Coastguard Worker if (x) 125*6777b538SAndroid Build Coastguard Worker closedir(x); 126*6777b538SAndroid Build Coastguard Worker } 127*6777b538SAndroid Build Coastguard Worker }; 128*6777b538SAndroid Build Coastguard Worker std::unique_ptr<DIR, DIRClose> procfs_dir_; 129*6777b538SAndroid Build Coastguard Worker #endif 130*6777b538SAndroid Build Coastguard Worker ProcessEntry entry_; 131*6777b538SAndroid Build Coastguard Worker raw_ptr<const ProcessFilter> filter_; 132*6777b538SAndroid Build Coastguard Worker }; 133*6777b538SAndroid Build Coastguard Worker 134*6777b538SAndroid Build Coastguard Worker // This class provides a way to iterate through the list of processes 135*6777b538SAndroid Build Coastguard Worker // on the current machine that were started from the given executable 136*6777b538SAndroid Build Coastguard Worker // name. To use, create an instance and then call NextProcessEntry() 137*6777b538SAndroid Build Coastguard Worker // until it returns false. 138*6777b538SAndroid Build Coastguard Worker // If `use_prefix_match` is true, this iterates all processes that 139*6777b538SAndroid Build Coastguard Worker // begin with `executable_name`; for example, "Google Chrome Helper" would 140*6777b538SAndroid Build Coastguard Worker // match "Google Chrome Helper", "Google Chrome Helper (Renderer)" and 141*6777b538SAndroid Build Coastguard Worker // "Google Chrome Helper (GPU)" if `use_prefix_match` is true and otherwise 142*6777b538SAndroid Build Coastguard Worker // only "Google Chrome Helper". This option is only implemented on Mac. 143*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT NamedProcessIterator : public ProcessIterator { 144*6777b538SAndroid Build Coastguard Worker public: 145*6777b538SAndroid Build Coastguard Worker NamedProcessIterator(const FilePath::StringType& executable_name, 146*6777b538SAndroid Build Coastguard Worker const ProcessFilter* filter, 147*6777b538SAndroid Build Coastguard Worker bool use_prefix_match = false); 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker NamedProcessIterator(const NamedProcessIterator&) = delete; 150*6777b538SAndroid Build Coastguard Worker NamedProcessIterator& operator=(const NamedProcessIterator&) = delete; 151*6777b538SAndroid Build Coastguard Worker 152*6777b538SAndroid Build Coastguard Worker ~NamedProcessIterator() override; 153*6777b538SAndroid Build Coastguard Worker 154*6777b538SAndroid Build Coastguard Worker protected: 155*6777b538SAndroid Build Coastguard Worker bool IncludeEntry() override; 156*6777b538SAndroid Build Coastguard Worker 157*6777b538SAndroid Build Coastguard Worker private: 158*6777b538SAndroid Build Coastguard Worker FilePath::StringType executable_name_; 159*6777b538SAndroid Build Coastguard Worker const bool use_prefix_match_; 160*6777b538SAndroid Build Coastguard Worker }; 161*6777b538SAndroid Build Coastguard Worker 162*6777b538SAndroid Build Coastguard Worker // Returns the number of processes on the machine that are running from the 163*6777b538SAndroid Build Coastguard Worker // given executable name. If filter is non-null, then only processes selected 164*6777b538SAndroid Build Coastguard Worker // by the filter will be counted. 165*6777b538SAndroid Build Coastguard Worker BASE_EXPORT int GetProcessCount(const FilePath::StringType& executable_name, 166*6777b538SAndroid Build Coastguard Worker const ProcessFilter* filter); 167*6777b538SAndroid Build Coastguard Worker 168*6777b538SAndroid Build Coastguard Worker } // namespace base 169*6777b538SAndroid Build Coastguard Worker 170*6777b538SAndroid Build Coastguard Worker #endif // BASE_PROCESS_PROCESS_ITERATOR_H_ 171