mirror of
https://github.com/uutils/procps.git
synced 2026-05-06 06:06:43 -04:00
pmap: add initial version
This commit is contained in:
Generated
+9
@@ -440,6 +440,7 @@ dependencies = [
|
||||
"tempfile",
|
||||
"textwrap",
|
||||
"uu_free",
|
||||
"uu_pmap",
|
||||
"uu_pwdx",
|
||||
"uu_w",
|
||||
"uu_watch",
|
||||
@@ -777,6 +778,14 @@ dependencies = [
|
||||
"uucore",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uu_pmap"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uu_pwdx"
|
||||
version = "0.0.1"
|
||||
|
||||
@@ -29,6 +29,7 @@ feat_common_core = [
|
||||
"free",
|
||||
"w",
|
||||
"watch",
|
||||
"pmap",
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
@@ -61,6 +62,7 @@ pwdx = { optional = true, version = "0.0.1", package = "uu_pwdx", path = "src/uu
|
||||
free = { optional = true, version = "0.0.1", package = "uu_free", path = "src/uu/free" }
|
||||
w = { optional = true, version = "0.0.1", package = "uu_w", path = "src/uu/w" }
|
||||
watch = { optional = true, version = "0.0.1", package = "uu_watch", path = "src/uu/watch" }
|
||||
pmap = { optional = true, version = "0.0.1", package = "uu_pmap", path = "src/uu/pmap" }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "uu_pmap"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
uucore = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
|
||||
[lib]
|
||||
path = "src/pmap.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "pmap"
|
||||
path = "src/main.rs"
|
||||
@@ -0,0 +1,7 @@
|
||||
# pmap
|
||||
|
||||
```
|
||||
pmap [options] pid [...]
|
||||
```
|
||||
|
||||
Report memory map of a process
|
||||
@@ -0,0 +1 @@
|
||||
uucore::bin!(uu_pmap);
|
||||
@@ -0,0 +1,145 @@
|
||||
// This file is part of the uutils procps package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use clap::{crate_version, Arg, ArgAction, Command};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Error;
|
||||
use std::process;
|
||||
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
||||
|
||||
const ABOUT: &str = help_about!("pmap.md");
|
||||
const USAGE: &str = help_usage!("pmap.md");
|
||||
|
||||
fn parse_cmdline(pid: &str) -> Result<String, Error> {
|
||||
let path = format!("/proc/{}/cmdline", pid);
|
||||
let contents = fs::read(path)?;
|
||||
// Command line arguments are separated by null bytes.
|
||||
// Replace them with spaces for display.
|
||||
let cmdline = contents
|
||||
.split(|&c| c == 0)
|
||||
.filter_map(|c| std::str::from_utf8(c).ok())
|
||||
.collect::<Vec<&str>>()
|
||||
.join(" ");
|
||||
Ok(cmdline)
|
||||
}
|
||||
|
||||
fn parse_maps(pid: &str) -> Result<(), Error> {
|
||||
let path = format!("/proc/{}/maps", pid);
|
||||
let contents = fs::read_to_string(path)?;
|
||||
|
||||
println!("Address Perms Offset Dev Inode Path");
|
||||
for line in contents.lines() {
|
||||
println!("{}", line);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(env!("CARGO_PKG_NAME"))
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.override_usage(format_usage(USAGE))
|
||||
.infer_long_args(true)
|
||||
.arg(
|
||||
Arg::new("pid")
|
||||
.help("Process ID")
|
||||
.required_unless_present_any(["create-rc", "create-rc-to"]) // Adjusted for -n, -N note
|
||||
.action(ArgAction::Set)
|
||||
.conflicts_with_all(&["create-rc", "create-rc-to"]),
|
||||
) // Ensure pid is not used with -n, -N
|
||||
.arg(
|
||||
Arg::new("extended")
|
||||
.short('x')
|
||||
.long("extended")
|
||||
.help("show details"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("very-extended")
|
||||
.short('X')
|
||||
.help("show even more details"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("all-details")
|
||||
.long("XX")
|
||||
.help("show everything the kernel provides"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("read-rc")
|
||||
.short('c')
|
||||
.long("read-rc")
|
||||
.help("read the default rc"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("read-rc-from")
|
||||
.short('C')
|
||||
.long("read-rc-from")
|
||||
.num_args(1)
|
||||
.help("read the rc from file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("create-rc")
|
||||
.short('n')
|
||||
.long("create-rc")
|
||||
.help("create new default rc"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("create-rc-to")
|
||||
.short('N')
|
||||
.long("create-rc-to")
|
||||
.num_args(1)
|
||||
.help("create new rc to file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("device")
|
||||
.short('d')
|
||||
.long("device")
|
||||
.help("show the device format"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("quiet")
|
||||
.short('q')
|
||||
.long("quiet")
|
||||
.help("do not display header and footer"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("show-path")
|
||||
.short('p')
|
||||
.long("show-path")
|
||||
.help("show path in the mapping"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("range")
|
||||
.short('A')
|
||||
.long("range")
|
||||
.num_args(1..=2)
|
||||
.help("limit results to the given range"),
|
||||
)
|
||||
}
|
||||
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches = uu_app().try_get_matches_from(args)?;
|
||||
let pid = matches.get_one::<String>("pid").expect("PID required");
|
||||
|
||||
match parse_cmdline(pid) {
|
||||
Ok(cmdline) => {
|
||||
println!("{}: {}", pid, cmdline);
|
||||
}
|
||||
Err(e) => {
|
||||
process::exit(42);
|
||||
}
|
||||
}
|
||||
|
||||
match parse_maps(pid) {
|
||||
Ok(_) => println!("Memory map displayed successfully."),
|
||||
Err(e) => {
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// This file is part of the uutils procps package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore (words) symdir somefakedir
|
||||
|
||||
use crate::common::util::TestScenario;
|
||||
|
||||
#[test]
|
||||
fn test_invalid_arg() {
|
||||
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
|
||||
}
|
||||
@@ -20,3 +20,7 @@ mod test_w;
|
||||
#[cfg(feature = "watch")]
|
||||
#[path = "by-util/test_watch.rs"]
|
||||
mod test_watch;
|
||||
|
||||
#[cfg(feature = "pmap")]
|
||||
#[path = "by-util/test_pmap.rs"]
|
||||
mod test_pmap;
|
||||
|
||||
Reference in New Issue
Block a user