mirror of
https://github.com/uutils/procps.git
synced 2026-06-10 16:14:00 -07:00
pmap: fixed to hide the header when permission is denied (#378)
* pmap: fixed to hide the header when permission is denied * pmap: fixed lint error
This commit is contained in:
+51
-39
@@ -81,13 +81,17 @@ fn parse_cmdline(pid: &str) -> Result<String, Error> {
|
||||
Ok(cmdline.into())
|
||||
}
|
||||
|
||||
fn process_maps<F>(pid: &str, mut process_line: F) -> Result<(), Error>
|
||||
fn process_maps<F>(pid: &str, header: Option<&str>, mut process_line: F) -> Result<(), Error>
|
||||
where
|
||||
F: FnMut(&MapLine),
|
||||
{
|
||||
let path = format!("/proc/{pid}/maps");
|
||||
let contents = fs::read_to_string(path)?;
|
||||
|
||||
if let Some(header) = header {
|
||||
println!("{header}");
|
||||
}
|
||||
|
||||
for line in contents.lines() {
|
||||
let map_line = parse_map_line(line)?;
|
||||
process_line(&map_line);
|
||||
@@ -96,7 +100,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_smaps<F>(pid: &str, mut process_entry: F) -> Result<(), Error>
|
||||
fn process_smaps<F>(pid: &str, header: Option<&str>, mut process_entry: F) -> Result<(), Error>
|
||||
where
|
||||
F: FnMut(&SmapEntry),
|
||||
{
|
||||
@@ -104,6 +108,10 @@ where
|
||||
let contents = fs::read_to_string(path)?;
|
||||
let smap_entries = parse_smap_entries(&contents)?;
|
||||
|
||||
if let Some(header) = header {
|
||||
println!("{header}");
|
||||
}
|
||||
|
||||
for entry in smap_entries {
|
||||
process_entry(&entry);
|
||||
}
|
||||
@@ -114,7 +122,7 @@ where
|
||||
fn output_default_format(pid: &str) -> Result<(), Error> {
|
||||
let mut total = 0;
|
||||
|
||||
process_maps(pid, |map_line| {
|
||||
process_maps(pid, None, |map_line| {
|
||||
println!(
|
||||
"{} {:>6}K {} {}",
|
||||
map_line.address, map_line.size_in_kb, map_line.perms, map_line.mapping
|
||||
@@ -132,22 +140,24 @@ fn output_extended_format(pid: &str) -> Result<(), Error> {
|
||||
let mut total_rss = 0;
|
||||
let mut total_dirty = 0;
|
||||
|
||||
println!("Address Kbytes RSS Dirty Mode Mapping");
|
||||
|
||||
process_smaps(pid, |smap_entry| {
|
||||
println!(
|
||||
"{} {:>7} {:>7} {:>7} {} {}",
|
||||
smap_entry.map_line.address,
|
||||
smap_entry.map_line.size_in_kb,
|
||||
smap_entry.rss_in_kb,
|
||||
smap_entry.shared_dirty_in_kb + smap_entry.private_dirty_in_kb,
|
||||
smap_entry.map_line.perms,
|
||||
smap_entry.map_line.mapping
|
||||
);
|
||||
total_mapped += smap_entry.map_line.size_in_kb;
|
||||
total_rss += smap_entry.rss_in_kb;
|
||||
total_dirty += smap_entry.shared_dirty_in_kb + smap_entry.private_dirty_in_kb;
|
||||
})?;
|
||||
process_smaps(
|
||||
pid,
|
||||
Some("Address Kbytes RSS Dirty Mode Mapping"),
|
||||
|smap_entry| {
|
||||
println!(
|
||||
"{} {:>7} {:>7} {:>7} {} {}",
|
||||
smap_entry.map_line.address,
|
||||
smap_entry.map_line.size_in_kb,
|
||||
smap_entry.rss_in_kb,
|
||||
smap_entry.shared_dirty_in_kb + smap_entry.private_dirty_in_kb,
|
||||
smap_entry.map_line.perms,
|
||||
smap_entry.map_line.mapping
|
||||
);
|
||||
total_mapped += smap_entry.map_line.size_in_kb;
|
||||
total_rss += smap_entry.rss_in_kb;
|
||||
total_dirty += smap_entry.shared_dirty_in_kb + smap_entry.private_dirty_in_kb;
|
||||
},
|
||||
)?;
|
||||
|
||||
println!("---------------- ------- ------- ------- ");
|
||||
println!("total kB {total_mapped:>7} {total_rss:>7} {total_dirty:>7}");
|
||||
@@ -160,28 +170,30 @@ fn output_device_format(pid: &str) -> Result<(), Error> {
|
||||
let mut total_writeable_private = 0;
|
||||
let mut total_shared = 0;
|
||||
|
||||
println!("Address Kbytes Mode Offset Device Mapping");
|
||||
process_maps(
|
||||
pid,
|
||||
Some("Address Kbytes Mode Offset Device Mapping"),
|
||||
|map_line| {
|
||||
println!(
|
||||
"{} {:>7} {} {} {} {}",
|
||||
map_line.address,
|
||||
map_line.size_in_kb,
|
||||
map_line.perms,
|
||||
map_line.offset,
|
||||
map_line.device,
|
||||
map_line.mapping
|
||||
);
|
||||
total_mapped += map_line.size_in_kb;
|
||||
|
||||
process_maps(pid, |map_line| {
|
||||
println!(
|
||||
"{} {:>7} {} {} {} {}",
|
||||
map_line.address,
|
||||
map_line.size_in_kb,
|
||||
map_line.perms,
|
||||
map_line.offset,
|
||||
map_line.device,
|
||||
map_line.mapping
|
||||
);
|
||||
total_mapped += map_line.size_in_kb;
|
||||
if map_line.perms.writable && !map_line.perms.shared {
|
||||
total_writeable_private += map_line.size_in_kb;
|
||||
}
|
||||
|
||||
if map_line.perms.writable && !map_line.perms.shared {
|
||||
total_writeable_private += map_line.size_in_kb;
|
||||
}
|
||||
|
||||
if map_line.perms.shared {
|
||||
total_shared += map_line.size_in_kb;
|
||||
}
|
||||
})?;
|
||||
if map_line.perms.shared {
|
||||
total_shared += map_line.size_in_kb;
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
println!(
|
||||
"mapped: {total_mapped}K writeable/private: {total_writeable_private}K shared: {total_shared}K"
|
||||
|
||||
@@ -10,6 +10,8 @@ use regex::Regex;
|
||||
use std::process;
|
||||
|
||||
const NON_EXISTING_PID: &str = "999999";
|
||||
#[cfg(target_os = "linux")]
|
||||
const INIT_PID: &str = "1";
|
||||
|
||||
#[test]
|
||||
fn test_no_args() {
|
||||
@@ -73,6 +75,20 @@ fn test_non_existing_pid() {
|
||||
.no_output();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_permission_denied() {
|
||||
let result = new_ucmd!()
|
||||
.arg(INIT_PID)
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.no_stderr()
|
||||
.clone()
|
||||
.stdout_move_str();
|
||||
|
||||
assert_cmdline_only(INIT_PID, &result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_extended() {
|
||||
@@ -89,6 +105,23 @@ fn test_extended() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_extended_permission_denied() {
|
||||
for arg in ["-x", "--extended"] {
|
||||
let result = new_ucmd!()
|
||||
.arg(arg)
|
||||
.arg(INIT_PID)
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.no_stderr()
|
||||
.clone()
|
||||
.stdout_move_str();
|
||||
|
||||
assert_cmdline_only(INIT_PID, &result);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_device() {
|
||||
@@ -105,11 +138,38 @@ fn test_device() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_device_permission_denied() {
|
||||
for arg in ["-d", "--device"] {
|
||||
let result = new_ucmd!()
|
||||
.arg(arg)
|
||||
.arg(INIT_PID)
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.no_stderr()
|
||||
.clone()
|
||||
.stdout_move_str();
|
||||
|
||||
assert_cmdline_only(INIT_PID, &result);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
|
||||
}
|
||||
|
||||
// Ensure `s` has the following format:
|
||||
//
|
||||
// 1234: /some/path
|
||||
#[cfg(target_os = "linux")]
|
||||
fn assert_cmdline_only(pid: &str, s: &str) {
|
||||
let s = s.trim_end();
|
||||
let re = Regex::new(&format!("^{pid}: .+[^ ]$")).unwrap();
|
||||
assert!(re.is_match(s));
|
||||
}
|
||||
|
||||
// Ensure `s` has the following format:
|
||||
//
|
||||
// 1234: /some/path
|
||||
|
||||
Reference in New Issue
Block a user