Skip to content

Commit

Permalink
Merge pull request #6597 from Krysztal112233/fix_proc_info
Browse files Browse the repository at this point in the history
uucore: Fix return value of `ProcessInfomation::tty`
  • Loading branch information
sylvestre authored Jul 28, 2024
2 parents ecc6450 + c0081d3 commit 810ec0f
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/uucore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ mode = ["libc"]
perms = ["libc", "walkdir"]
pipes = []
process = ["libc"]
proc-info = ["walkdir"]
proc-info = ["tty", "walkdir"]
quoting-style = []
ranges = []
ringbuffer = []
Expand Down
51 changes: 18 additions & 33 deletions src/uucore/src/lib/features/proc_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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]
Expand Down

0 comments on commit 810ec0f

Please sign in to comment.