1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// This file is part of dpdk. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/dpdk/master/COPYRIGHT. No part of predicator, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
// Copyright © 2017 The developers of dpdk. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/dpdk/master/COPYRIGHT.


/// Represents `/proc`.
///
/// Frankly, there are files in `/proc` that really belong in `/sys`.
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[derive(Deserialize, Serialize)]
pub struct ProcPath(PathBuf);

impl Default for ProcPath
{
	#[inline(always)]
	fn default() -> Self
	{
		ProcPath(PathBuf::from("/proc"))
	}
}

impl ProcPath
{
	/// Memory statistics (from `/proc/vmstat`).
	///
	/// Interpret this by multiplying counts by page size.
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub fn global_zoned_virtual_memory_statistics(&self) -> io::Result<HashMap<VirtualMemoryStatisticName, u64>>
	{
		self.file_path("vmstat").parse_virtual_memory_statistics_file()
	}
	
	/// Memory information (from `/proc/meminfo`).
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub fn memory_information(&self, memory_information_name_prefix: &str) -> Result<MemoryInformation, MemoryInformationParseError>
	{
		self.file_path("meminfo").parse_memory_information_file(memory_information_name_prefix)
	}
	
	/// File systems (from `/proc/filesystems`).
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub fn filesystems(&self) -> Result<FileSystemTypeList, io::Error>
	{
		let file_path = self.file_path("filesystems");
		FileSystemTypeList::parse(&file_path)
	}
	
	/// Current mounts (from `/proc/self/mounts`).
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub fn mounts(&self) -> Result<Mounts, io::Error>
	{
		let file_path = self.file_path("self/mounts");
		Mounts::parse(&file_path)
	}
	
	/// Current loaded Linux kernel modules (from `/proc/modules`).
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub fn modules(&self) -> Result<LinuxKernelModulesList, LinuxKernelModulesListParseError>
	{
		let file_path = self.file_path("modules");
		LinuxKernelModulesList::parse(&file_path)
	}
	
	/// Command line parameters used to start Linux.
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub fn linux_command_line_parameters(&self) -> Result<LinuxKernelCommandLineParameters, io::Error>
	{
		let file_path = self.file_path("cmdline");
		LinuxKernelCommandLineParameters::parse(&file_path)
	}
	
	/// Only execute this afte any kernel modules have loaded.
	///
	/// We ignore failures.
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub fn write_system_control_values(&self, settings: HashMap<String, u64>) -> io::Result<()>
	{
		for (setting_name, setting_value) in settings.iter()
		{
			let file_path = self.file_path(&format!("sys/{}", setting_name));
			file_path.write_value(setting_value)?;
		}
		Ok(())
	}
	
	#[inline(always)]
	#[cfg(any(target_os = "android", target_os = "linux"))]
	pub(crate) fn maximum_number_of_open_file_descriptors(&self) -> io::Result<u64>
	{
		self.file_path("sys/fs/nr_open").read_value()
	}
	
	#[cfg(any(target_os = "android", target_os = "linux"))]
	#[inline(always)]
	fn file_path(&self, file_name: &str) -> PathBuf
	{
		let mut path = self.path();
		path.push(file_name);
		path
	}
	
	#[cfg(any(target_os = "android", target_os = "linux"))]
	#[inline(always)]
	fn path(&self) -> PathBuf
	{
		self.0.to_owned()
	}
}