diff options
author | Krysztal Huang <krysztal.huang@outlook.com> | 2024-07-29 00:17:30 +0800 |
---|---|---|
committer | Krysztal Huang <krysztal.huang@outlook.com> | 2024-07-29 00:17:30 +0800 |
commit | eafed7ede401a4a6bb67b1d1cdc164914bc3b5b0 (patch) | |
tree | ec310451f8dd447c16fec922b4d541761e18cc29 | |
parent | 3494acc304993dcc43538a16914a8ff1900f46b7 (diff) |
uucore: Refactor `ProcessInformation::tty`
-rw-r--r-- | src/uucore/src/lib/features/proc_info.rs | 51 |
1 files changed, 18 insertions, 33 deletions
diff --git a/src/uucore/src/lib/features/proc_info.rs b/src/uucore/src/lib/features/proc_info.rs index f6c4edf4c..cd36ab427 100644 --- a/src/uucore/src/lib/features/proc_info.rs +++ b/src/uucore/src/lib/features/proc_info.rs @@ -22,7 +22,7 @@ use crate::features::tty::Teletype; use std::hash::Hash; use std::{ - collections::{HashMap, HashSet}, + collections::HashMap, fmt::{self, Display, Formatter}, fs, io, path::PathBuf, @@ -120,7 +120,6 @@ pub struct ProcessInformation { cached_stat: Option<Rc<Vec<String>>>, cached_start_time: Option<u64>, - cached_tty: Option<Rc<HashSet<Teletype>>>, } impl ProcessInformation { @@ -242,42 +241,26 @@ impl ProcessInformation { /// This function will scan the `/proc/<pid>/fd` directory /// - /// If the process does not belong to any terminal, + /// If the process does not belong to any terminal and mismatched permission, /// the result will contain [TerminalType::Unknown]. /// /// Otherwise [TerminalType::Unknown] does not appear in the result. - /// - /// # Error - /// - /// If scanned pid had mismatched permission, - /// it will caused [std::io::ErrorKind::PermissionDenied] error. - pub fn ttys(&mut self) -> Result<Rc<HashSet<Teletype>>, io::Error> { - if let Some(tty) = &self.cached_tty { - return Ok(Rc::clone(tty)); - } - + pub fn tty(&mut self) -> Teletype { let path = PathBuf::from(format!("/proc/{}/fd", self.pid)); let Ok(result) = fs::read_dir(path) else { - return Ok(Rc::new(HashSet::from_iter([Teletype::Unknown]))); + return Teletype::Unknown; }; - let mut result = result - .flatten() - .filter(|it| it.path().is_symlink()) - .flat_map(|it| fs::read_link(it.path())) - .flat_map(Teletype::try_from) - .collect::<HashSet<_>>(); - - if result.is_empty() { - result.insert(Teletype::Unknown); + for dir in result.flatten().filter(|it| it.path().is_symlink()) { + if let Ok(path) = fs::read_link(dir.path()) { + if let Ok(tty) = Teletype::try_from(path) { + return tty; + } + } } - let result = Rc::new(result); - - self.cached_tty = Some(Rc::clone(&result)); - - Ok(result) + Teletype::Unknown } } @@ -344,11 +327,9 @@ pub fn walk_process() -> impl Iterator<Item = ProcessInformation> { #[cfg(test)] mod tests { - - use crate::features::tty::Teletype; - use super::*; - use std::str::FromStr; + use crate::features::tty::Teletype; + use std::{collections::HashSet, str::FromStr}; #[test] fn test_run_state_conversion() { @@ -402,7 +383,11 @@ mod tests { .flat_map(Teletype::try_from) .collect::<HashSet<_>>(); - assert_eq!(pid_entry.ttys().unwrap(), result.into()); + assert_eq!(result.len(), 1); + assert_eq!( + pid_entry.tty(), + Vec::from_iter(result.into_iter()).first().unwrap().clone() + ); } #[test] |