|  | // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // This file contains methods to iterate over processes on the system. | 
|  |  | 
|  | #ifndef BASE_PROCESS_PROCESS_ITERATOR_H_ | 
|  | #define BASE_PROCESS_PROCESS_ITERATOR_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  |  | 
|  | #include <list> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/base_export.h" | 
|  | #include "base/files/file_path.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/process/process.h" | 
|  | #include "build_config.h" | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | #include <windows.h> | 
|  | #include <tlhelp32.h> | 
|  | #elif defined(OS_MACOSX) || defined(OS_OPENBSD) | 
|  | #include <sys/sysctl.h> | 
|  | #elif defined(OS_FREEBSD) | 
|  | #include <sys/user.h> | 
|  | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) | 
|  | #include <dirent.h> | 
|  | #endif | 
|  |  | 
|  | namespace base { | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | struct ProcessEntry : public PROCESSENTRY32 { | 
|  | ProcessId pid() const { return th32ProcessID; } | 
|  | ProcessId parent_pid() const { return th32ParentProcessID; } | 
|  | const wchar_t* exe_file() const { return szExeFile; } | 
|  | }; | 
|  | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) | 
|  | struct BASE_EXPORT ProcessEntry { | 
|  | ProcessEntry(); | 
|  | ProcessEntry(const ProcessEntry& other); | 
|  | ~ProcessEntry(); | 
|  |  | 
|  | ProcessId pid() const { return pid_; } | 
|  | ProcessId parent_pid() const { return ppid_; } | 
|  | ProcessId gid() const { return gid_; } | 
|  | const char* exe_file() const { return exe_file_.c_str(); } | 
|  | const std::vector<std::string>& cmd_line_args() const { | 
|  | return cmd_line_args_; | 
|  | } | 
|  |  | 
|  | ProcessId pid_; | 
|  | ProcessId ppid_; | 
|  | ProcessId gid_; | 
|  | std::string exe_file_; | 
|  | std::vector<std::string> cmd_line_args_; | 
|  | }; | 
|  | #endif  // defined(OS_WIN) | 
|  |  | 
|  | // Used to filter processes by process ID. | 
|  | class ProcessFilter { | 
|  | public: | 
|  | // Returns true to indicate set-inclusion and false otherwise.  This method | 
|  | // should not have side-effects and should be idempotent. | 
|  | virtual bool Includes(const ProcessEntry& entry) const = 0; | 
|  |  | 
|  | protected: | 
|  | virtual ~ProcessFilter() = default; | 
|  | }; | 
|  |  | 
|  | // This class provides a way to iterate through a list of processes on the | 
|  | // current machine with a specified filter. | 
|  | // To use, create an instance and then call NextProcessEntry() until it returns | 
|  | // false. | 
|  | class BASE_EXPORT ProcessIterator { | 
|  | public: | 
|  | typedef std::list<ProcessEntry> ProcessEntries; | 
|  |  | 
|  | explicit ProcessIterator(const ProcessFilter* filter); | 
|  | virtual ~ProcessIterator(); | 
|  |  | 
|  | // If there's another process that matches the given executable name, | 
|  | // returns a const pointer to the corresponding PROCESSENTRY32. | 
|  | // If there are no more matching processes, returns NULL. | 
|  | // The returned pointer will remain valid until NextProcessEntry() | 
|  | // is called again or this NamedProcessIterator goes out of scope. | 
|  | const ProcessEntry* NextProcessEntry(); | 
|  |  | 
|  | // Takes a snapshot of all the ProcessEntry found. | 
|  | ProcessEntries Snapshot(); | 
|  |  | 
|  | protected: | 
|  | virtual bool IncludeEntry(); | 
|  | const ProcessEntry& entry() { return entry_; } | 
|  |  | 
|  | private: | 
|  | // Determines whether there's another process (regardless of executable) | 
|  | // left in the list of all processes.  Returns true and sets entry_ to | 
|  | // that process's info if there is one, false otherwise. | 
|  | bool CheckForNextProcess(); | 
|  |  | 
|  | // Initializes a PROCESSENTRY32 data structure so that it's ready for | 
|  | // use with Process32First/Process32Next. | 
|  | void InitProcessEntry(ProcessEntry* entry); | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | HANDLE snapshot_; | 
|  | bool started_iteration_; | 
|  | #elif defined(OS_MACOSX) || defined(OS_BSD) | 
|  | std::vector<kinfo_proc> kinfo_procs_; | 
|  | size_t index_of_kinfo_proc_; | 
|  | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) | 
|  | DIR* procfs_dir_; | 
|  | #endif | 
|  | ProcessEntry entry_; | 
|  | const ProcessFilter* filter_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(ProcessIterator); | 
|  | }; | 
|  |  | 
|  | // This class provides a way to iterate through the list of processes | 
|  | // on the current machine that were started from the given executable | 
|  | // name.  To use, create an instance and then call NextProcessEntry() | 
|  | // until it returns false. | 
|  | class BASE_EXPORT NamedProcessIterator : public ProcessIterator { | 
|  | public: | 
|  | NamedProcessIterator(const FilePath::StringType& executable_name, | 
|  | const ProcessFilter* filter); | 
|  | ~NamedProcessIterator() override; | 
|  |  | 
|  | protected: | 
|  | bool IncludeEntry() override; | 
|  |  | 
|  | private: | 
|  | FilePath::StringType executable_name_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(NamedProcessIterator); | 
|  | }; | 
|  |  | 
|  | // Returns the number of processes on the machine that are running from the | 
|  | // given executable name.  If filter is non-null, then only processes selected | 
|  | // by the filter will be counted. | 
|  | BASE_EXPORT int GetProcessCount(const FilePath::StringType& executable_name, | 
|  | const ProcessFilter* filter); | 
|  |  | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_PROCESS_PROCESS_ITERATOR_H_ |