| 1 | // Take a look at the license at the top of the repository in the LICENSE file. |
| 2 | |
| 3 | use std::fs::File; |
| 4 | use std::io::{self, Read, Seek}; |
| 5 | use std::path::Path; |
| 6 | |
| 7 | #[cfg (feature = "system" )] |
| 8 | pub(crate) fn get_all_data_from_file(file: &mut File, size: usize) -> io::Result<Vec<u8>> { |
| 9 | let mut buf = Vec::with_capacity(size); |
| 10 | file.rewind()?; |
| 11 | file.read_to_end(&mut buf)?; |
| 12 | Ok(buf) |
| 13 | } |
| 14 | |
| 15 | pub(crate) fn get_all_utf8_data_from_file(file: &mut File, size: usize) -> io::Result<String> { |
| 16 | let mut buf: String = String::with_capacity(size); |
| 17 | file.rewind()?; |
| 18 | file.read_to_string(&mut buf)?; |
| 19 | Ok(buf) |
| 20 | } |
| 21 | |
| 22 | pub(crate) fn get_all_utf8_data<P: AsRef<Path>>(file_path: P, size: usize) -> io::Result<String> { |
| 23 | let mut file: File = File::open(file_path.as_ref())?; |
| 24 | get_all_utf8_data_from_file(&mut file, size) |
| 25 | } |
| 26 | |
| 27 | #[cfg (feature = "system" )] |
| 28 | #[allow (clippy::useless_conversion)] |
| 29 | pub(crate) fn realpath(path: &Path) -> Option<std::path::PathBuf> { |
| 30 | match std::fs::read_link(path) { |
| 31 | Ok(path) => Some(path), |
| 32 | Err(_e) => { |
| 33 | sysinfo_debug!("failed to get real path for {:?}: {:?}" , path, _e); |
| 34 | None |
| 35 | } |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | /// This type is used in `retrieve_all_new_process_info` because we have a "parent" path and |
| 40 | /// from it, we `pop`/`join` every time because it's more memory efficient than using `Path::join`. |
| 41 | #[cfg (feature = "system" )] |
| 42 | pub(crate) struct PathHandler(std::path::PathBuf); |
| 43 | |
| 44 | #[cfg (feature = "system" )] |
| 45 | impl PathHandler { |
| 46 | pub(crate) fn new(path: &Path) -> Self { |
| 47 | // `path` is the "parent" for all paths which will follow so we add a fake element at |
| 48 | // the end since every `PathHandler::join` call will first call `pop` internally. |
| 49 | Self(path.join("a" )) |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | #[cfg (feature = "system" )] |
| 54 | pub(crate) trait PathPush { |
| 55 | fn join(&mut self, p: &str) -> &Path; |
| 56 | } |
| 57 | |
| 58 | #[cfg (feature = "system" )] |
| 59 | impl PathPush for PathHandler { |
| 60 | fn join(&mut self, p: &str) -> &Path { |
| 61 | self.0.pop(); |
| 62 | self.0.push(p); |
| 63 | self.0.as_path() |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | // This implementation allows to skip one allocation that is done in `PathHandler`. |
| 68 | #[cfg (feature = "system" )] |
| 69 | impl PathPush for std::path::PathBuf { |
| 70 | fn join(&mut self, p: &str) -> &Path { |
| 71 | self.push(p); |
| 72 | self.as_path() |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | #[cfg (feature = "system" )] |
| 77 | pub(crate) fn to_u64(v: &[u8]) -> u64 { |
| 78 | let mut x = 0; |
| 79 | |
| 80 | for c in v { |
| 81 | x *= 10; |
| 82 | x += u64::from(c - b'0' ); |
| 83 | } |
| 84 | x |
| 85 | } |
| 86 | |
| 87 | /// Converts a path to a NUL-terminated `Vec<u8>` suitable for use with C functions. |
| 88 | pub(crate) fn to_cpath(path: &std::path::Path) -> Vec<u8> { |
| 89 | use std::{ffi::OsStr, os::unix::ffi::OsStrExt}; |
| 90 | |
| 91 | let path_os: &OsStr = path.as_ref(); |
| 92 | let mut cpath: Vec = path_os.as_bytes().to_vec(); |
| 93 | cpath.push(0); |
| 94 | cpath |
| 95 | } |
| 96 | |