Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use clap::{App, Arg, ArgMatches};
- use std::path::{Path, PathBuf};
- use std::process;
- use std::fs;
- use std::ffi::OsString;
- use std::io;
- use std::os::unix::fs::MetadataExt;
- const PROC_PATH: &str = "/proc";
- const FD_FOLDER: &str = "fd";
- const EXE_SYMLINK: &str = "exe";
- fn get_filename_from_matches<'a>(matches: &'a ArgMatches) -> &'a str {
- matches.value_of("file").unwrap()
- }
- fn get_current_directory() -> PathBuf {
- std::env::current_dir().unwrap()
- }
- fn get_path_from_match(matches: &ArgMatches) -> PathBuf {
- PathBuf::from(get_filename_from_matches(&matches))
- }
- fn get_only_process_pid(dir_result: &Result<std::fs::DirEntry, std::io::Error>) -> bool {
- dir_result.as_ref().unwrap()
- .file_name().to_str().unwrap()
- .chars().all(char::is_numeric)
- }
- fn get_only_process_directory(dir_result: &Result<std::fs::DirEntry, std::io::Error>) -> bool {
- dir_result.as_ref().unwrap()
- .path().is_dir()
- }
- fn map_to_process_struct<'a>(dir_result: Result<std::fs::DirEntry, std::io::Error>) -> Process {
- let pid = dir_result.unwrap()
- .path().into_os_string();
- Process::new(pid)
- }
- fn get_reachable_launched_programs(dir_result: &Result<std::fs::DirEntry, std::io::Error>) -> bool {
- let pid = dir_result.as_ref().unwrap().file_name();
- get_running_program_name(pid.to_str().unwrap()).is_ok()
- }
- fn get_running_program_name(pid: &str) -> io::Result<PathBuf> {
- Path::new(PROC_PATH)
- .join(pid)
- .join(EXE_SYMLINK)
- .read_link()
- }
- fn process_using_file(process: &Process, inode: &u64) -> bool {
- fs::read_dir(process.get_fd_directory()).unwrap()
- .filter(|file| fs::metadata(file.as_ref().unwrap().path()).unwrap().ino() == *inode )
- .count() > 0
- }
- #[derive(Debug)]
- struct Process {
- pid: OsString,
- running_program_name: String
- }
- impl Process {
- fn new(pid: OsString) -> Process {
- let running_program_name = get_running_program_name(pid.to_str().unwrap())
- .unwrap().to_str().unwrap().to_owned();
- Process{ pid, running_program_name }
- }
- fn get_fd_directory(&self) -> PathBuf {
- let pid_path = Path::new(self.pid.to_str().unwrap());
- pid_path.join(FD_FOLDER)
- }
- }
- fn main() -> io::Result<()> {
- let matches = App::new("FOWP")
- .version("1.0")
- .author("XXX <xxx@gmail.com>")
- .about("Tell which process has opened a given file")
- .arg(Arg::with_name("file")
- .short("f")
- .long("file")
- .value_name("FILE")
- .required(true)
- .help("Path to the file"))
- .get_matches();
- let full_path = get_path_from_match(&matches);
- let inode = fs::metadata(&full_path)?.ino();
- println!("Running program that using the file {:?} are : ", full_path);
- if !full_path.exists(){
- eprintln!("The file {} does not exists", full_path.to_str().unwrap());
- process::exit(1);
- }
- fs::read_dir(PROC_PATH).unwrap()
- .filter(get_only_process_pid)
- .filter(get_only_process_directory)
- .filter(get_reachable_launched_programs)
- .map(map_to_process_struct)
- .filter(|process| process_using_file(process, &inode))
- .for_each(|process| println!("Running process is {:?}", process) );
- Ok(())
- }
Add Comment
Please, Sign In to add comment