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 | |