Ps: add cwd column on linux and macos (#10347)

# Description
Close:  #7484

Just found that I want `cwd` column on linux/macos as well..
This commit is contained in:
WindSoilder 2023-09-14 21:10:15 +08:00 committed by GitHub
parent 026e18399e
commit 2c176a7f14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 1 deletions

View File

@ -143,6 +143,7 @@ fn run_ps(engine_state: &EngineState, call: &Call) -> Result<PipelineData, Shell
// record.push("tpg_id", Value::int(proc_stat.tpgid as i64, span)); // record.push("tpg_id", Value::int(proc_stat.tpgid as i64, span));
record.push("priority", Value::int(proc_stat.priority, span)); record.push("priority", Value::int(proc_stat.priority, span));
record.push("process_threads", Value::int(proc_stat.num_threads, span)); record.push("process_threads", Value::int(proc_stat.num_threads, span));
record.push("cwd", Value::string(proc.cwd(), span));
} }
#[cfg(windows)] #[cfg(windows)]
{ {
@ -184,6 +185,10 @@ fn run_ps(engine_state: &EngineState, call: &Call) -> Result<PipelineData, Shell
), ),
); );
} }
#[cfg(target_os = "macos")]
{
record.push("cwd", Value::string(proc.cwd(), span));
}
} }
output.push(Value::record(record, span)); output.push(Value::record(record, span));

View File

@ -1,6 +1,7 @@
use log::info; use log::info;
use procfs::process::{FDInfo, Io, Process, Stat, Status}; use procfs::process::{FDInfo, Io, Process, Stat, Status};
use procfs::{ProcError, ProcessCgroup}; use procfs::{ProcError, ProcessCgroup};
use std::path::PathBuf;
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -70,6 +71,7 @@ pub struct ProcessInfo {
pub prev_stat: Option<Stat>, pub prev_stat: Option<Stat>,
pub curr_status: Option<Status>, pub curr_status: Option<Status>,
pub interval: Duration, pub interval: Duration,
pub cwd: PathBuf,
} }
pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo> { pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo> {
@ -98,6 +100,7 @@ pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo>
info!("failed to retrieve info for pid={curr_proc_pid}, process probably died between snapshots"); info!("failed to retrieve info for pid={curr_proc_pid}, process probably died between snapshots");
continue; continue;
}; };
let cwd = curr_proc.cwd().unwrap_or_default();
let curr_io = curr_proc.io().ok(); let curr_io = curr_proc.io().ok();
let curr_stat = curr_proc.stat().ok(); let curr_stat = curr_proc.stat().ok();
@ -117,6 +120,7 @@ pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec<ProcessInfo>
prev_stat, prev_stat,
curr_status, curr_status,
interval, interval,
cwd,
}; };
ret.push(proc); ret.push(proc);
@ -165,6 +169,10 @@ impl ProcessInfo {
} }
} }
pub fn cwd(&self) -> String {
self.cwd.display().to_string()
}
/// Get the status of the process /// Get the status of the process
pub fn status(&self) -> String { pub fn status(&self) -> String {
if let Ok(p) = self.curr_proc.stat() { if let Ok(p) = self.curr_proc.stat() {

View File

@ -142,6 +142,7 @@ pub struct PathInfo {
pub root: PathBuf, pub root: PathBuf,
pub cmd: Vec<String>, pub cmd: Vec<String>,
pub env: Vec<String>, pub env: Vec<String>,
pub cwd: PathBuf,
} }
#[cfg_attr(tarpaulin, skip)] #[cfg_attr(tarpaulin, skip)]
@ -213,12 +214,17 @@ fn get_path_info(pid: i32, mut size: size_t) -> Option<PathInfo> {
} }
start = cp; start = cp;
let mut env = Vec::new(); let mut env = Vec::new();
let mut cwd = PathBuf::default();
while cp < ptr.add(size) { while cp < ptr.add(size) {
if *cp == 0 { if *cp == 0 {
if cp == start { if cp == start {
break; break;
} }
env.push(get_unchecked_str(cp, start)); let env_str = get_unchecked_str(cp, start);
if let Some(pwd) = env_str.strip_prefix("PWD=") {
cwd = PathBuf::from(pwd)
}
env.push(env_str);
start = cp.offset(1); start = cp.offset(1);
} }
cp = cp.offset(1); cp = cp.offset(1);
@ -238,6 +244,7 @@ fn get_path_info(pid: i32, mut size: size_t) -> Option<PathInfo> {
root, root,
cmd, cmd,
env, env,
cwd,
}) })
} else { } else {
None None
@ -394,6 +401,13 @@ impl ProcessInfo {
pub fn virtual_size(&self) -> u64 { pub fn virtual_size(&self) -> u64 {
self.curr_task.ptinfo.pti_virtual_size self.curr_task.ptinfo.pti_virtual_size
} }
pub fn cwd(&self) -> String {
self.curr_path
.as_ref()
.map(|cur_path| cur_path.cwd.display().to_string())
.unwrap_or_else(|| "".to_string())
}
} }
/// The Macos kernel returns process times in mach ticks rather than nanoseconds. To get times in /// The Macos kernel returns process times in mach ticks rather than nanoseconds. To get times in