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"]
pipes = []
process = ["libc"]
proc-info = ["walkdir"]
proc-info = ["tty", "walkdir"]
quoting-style = []
ranges = []
ringbuffer = []

View file

@ -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(&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]