1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::fs::File;
4use std::io::{self, Read, Seek};
5use std::path::Path;
6
7#[cfg(feature = "system")]
8pub(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
15pub(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
22pub(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)]
29pub(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")]
42pub(crate) struct PathHandler(std::path::PathBuf);
43
44#[cfg(feature = "system")]
45impl 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")]
54pub(crate) trait PathPush {
55 fn join(&mut self, p: &str) -> &Path;
56}
57
58#[cfg(feature = "system")]
59impl 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")]
69impl 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")]
77pub(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.
88pub(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