use crate::process::Pid;
use std::fs;
use std::io;
use std::os::unix::fs::MetadataExt;
use std::path::Path;
use std::path::PathBuf;
#[derive(Debug, PartialEq)]
struct FileId {
inode: u64,
device: u64,
size: u64,
}
impl FileId {
fn new(path: &Path) -> io::Result<Self> {
let metadata = fs::metadata(path)?;
Ok(FileId {
inode: metadata.ino(),
device: metadata.dev(),
size: metadata.size(),
})
}
}
pub fn executable_path(pid: Pid, path: &Path) -> PathBuf {
debug_assert!(
path.is_absolute(),
"paths from procfs /maps are expected to be absolute but was {}",
path.display()
);
let procfs_path = format!("/proc/{}/root{}", pid, path.to_string_lossy());
let procfs_path = PathBuf::from(procfs_path);
if let (Ok(file_id_left), Ok(file_id_right)) = (FileId::new(&procfs_path), FileId::new(path)) {
if file_id_left == file_id_right {
return path.to_path_buf();
}
}
procfs_path
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_file_id() {
assert_eq!(
FileId::new(&PathBuf::from("/")).unwrap(),
FileId::new(&PathBuf::from("/")).unwrap()
);
}
}