Merge pull request #6597 from Krysztal112233/fix_proc_info

uucore: Fix return value of `ProcessInfomation::tty`
This commit is contained in:
Sylvestre Ledru 2024-07-28 20:24:55 +02:00 committed by GitHub
commit 810ec0f3cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 34 deletions

View file

@ -88,7 +88,7 @@ mode = ["libc"]
perms = ["libc", "walkdir"] perms = ["libc", "walkdir"]
pipes = [] pipes = []
process = ["libc"] process = ["libc"]
proc-info = ["walkdir"] proc-info = ["tty", "walkdir"]
quoting-style = [] quoting-style = []
ranges = [] ranges = []
ringbuffer = [] ringbuffer = []

View file

@ -22,7 +22,7 @@
use crate::features::tty::Teletype; use crate::features::tty::Teletype;
use std::hash::Hash; use std::hash::Hash;
use std::{ use std::{
collections::{HashMap, HashSet}, collections::HashMap,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
fs, io, fs, io,
path::PathBuf, path::PathBuf,
@ -120,7 +120,6 @@ pub struct ProcessInformation {
cached_stat: Option<Rc<Vec<String>>>, cached_stat: Option<Rc<Vec<String>>>,
cached_start_time: Option<u64>, cached_start_time: Option<u64>,
cached_tty: Option<Rc<HashSet<Teletype>>>,
} }
impl ProcessInformation { impl ProcessInformation {
@ -242,42 +241,26 @@ impl ProcessInformation {
/// This function will scan the `/proc/<pid>/fd` directory /// 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]. /// the result will contain [TerminalType::Unknown].
/// ///
/// Otherwise [TerminalType::Unknown] does not appear in the result. /// Otherwise [TerminalType::Unknown] does not appear in the result.
/// pub fn tty(&self) -> Teletype {
/// # 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));
}
let path = PathBuf::from(format!("/proc/{}/fd", self.pid)); let path = PathBuf::from(format!("/proc/{}/fd", self.pid));
let Ok(result) = fs::read_dir(path) else { let Ok(result) = fs::read_dir(path) else {
return Ok(Rc::new(HashSet::from_iter([Teletype::Unknown]))); return Teletype::Unknown;
}; };
let mut result = result for dir in result.flatten().filter(|it| it.path().is_symlink()) {
.flatten() if let Ok(path) = fs::read_link(dir.path()) {
.filter(|it| it.path().is_symlink()) if let Ok(tty) = Teletype::try_from(path) {
.flat_map(|it| fs::read_link(it.path())) return tty;
.flat_map(Teletype::try_from) }
.collect::<HashSet<_>>(); }
if result.is_empty() {
result.insert(Teletype::Unknown);
} }
let result = Rc::new(result); Teletype::Unknown
self.cached_tty = Some(Rc::clone(&result));
Ok(result)
} }
} }
@ -344,11 +327,9 @@ pub fn walk_process() -> impl Iterator<Item = ProcessInformation> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::features::tty::Teletype;
use super::*; use super::*;
use std::str::FromStr; use crate::features::tty::Teletype;
use std::{collections::HashSet, str::FromStr};
#[test] #[test]
fn test_run_state_conversion() { fn test_run_state_conversion() {
@ -402,7 +383,11 @@ mod tests {
.flat_map(Teletype::try_from) .flat_map(Teletype::try_from)
.collect::<HashSet<_>>(); .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] #[test]