diff options
Diffstat (limited to 'vendor/sysinfo-0.26.7/src/linux/utils.rs')
-rw-r--r-- | vendor/sysinfo-0.26.7/src/linux/utils.rs | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/vendor/sysinfo-0.26.7/src/linux/utils.rs b/vendor/sysinfo-0.26.7/src/linux/utils.rs new file mode 100644 index 000000000..60a9aa2b0 --- /dev/null +++ b/vendor/sysinfo-0.26.7/src/linux/utils.rs @@ -0,0 +1,123 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use std::fs::File; +use std::io::{self, Read, Seek, SeekFrom}; +use std::path::{Path, PathBuf}; + +use crate::sys::system::REMAINING_FILES; + +pub(crate) fn get_all_data_from_file(file: &mut File, size: usize) -> io::Result<String> { + let mut buf = String::with_capacity(size); + file.seek(SeekFrom::Start(0))?; + file.read_to_string(&mut buf)?; + Ok(buf) +} + +pub(crate) fn get_all_data<P: AsRef<Path>>(file_path: P, size: usize) -> io::Result<String> { + let mut file = File::open(file_path.as_ref())?; + get_all_data_from_file(&mut file, size) +} + +#[allow(clippy::useless_conversion)] +pub(crate) fn realpath(path: &Path) -> std::path::PathBuf { + match std::fs::read_link(path) { + Ok(f) => f, + Err(_e) => { + sysinfo_debug!("failed to get real path for {:?}: {:?}", path, _e); + PathBuf::new() + } + } +} + +/// Type used to correctly handle the `REMAINING_FILES` global. +pub(crate) struct FileCounter(File); + +impl FileCounter { + pub(crate) fn new(f: File) -> Option<Self> { + unsafe { + if let Ok(ref mut x) = REMAINING_FILES.lock() { + if **x > 0 { + **x -= 1; + return Some(Self(f)); + } + // All file descriptors we were allowed are being used. + } + } + None + } +} + +impl std::ops::Deref for FileCounter { + type Target = File; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl std::ops::DerefMut for FileCounter { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl Drop for FileCounter { + fn drop(&mut self) { + unsafe { + if let Ok(ref mut x) = crate::sys::system::REMAINING_FILES.lock() { + **x += 1; + } + } + } +} + +/// This type is used in `retrieve_all_new_process_info` because we have a "parent" path and +/// from it, we `pop`/`join` every time because it's more memory efficient than using `Path::join`. +pub(crate) struct PathHandler(PathBuf); + +impl PathHandler { + pub(crate) fn new(path: &Path) -> Self { + // `path` is the "parent" for all paths which will follow so we add a fake element at + // the end since every `PathHandler::join` call will first call `pop` internally. + Self(path.join("a")) + } +} + +pub(crate) trait PathPush { + fn join(&mut self, p: &str) -> &Path; +} + +impl PathPush for PathHandler { + fn join(&mut self, p: &str) -> &Path { + self.0.pop(); + self.0.push(p); + self.0.as_path() + } +} + +// This implementation allows to skip one allocation that is done in `PathHandler`. +impl PathPush for PathBuf { + fn join(&mut self, p: &str) -> &Path { + self.push(p); + self.as_path() + } +} + +pub(crate) fn to_u64(v: &[u8]) -> u64 { + let mut x = 0; + + for c in v { + x *= 10; + x += u64::from(c - b'0'); + } + x +} + +/// Converts a path to a NUL-terminated `Vec<u8>` suitable for use with C functions. +pub(crate) fn to_cpath(path: &std::path::Path) -> Vec<u8> { + use std::{ffi::OsStr, os::unix::ffi::OsStrExt}; + + let path_os: &OsStr = path.as_ref(); + let mut cpath = path_os.as_bytes().to_vec(); + cpath.push(0); + cpath +} |