Skip to content

Commit

Permalink
pmap: add initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvestre committed Feb 6, 2024
1 parent f580c6a commit 0b6d165
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ feat_common_core = [
"free",
"w",
"watch",
"pmap",
]

[workspace.dependencies]
Expand Down Expand Up @@ -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"
Expand Down
15 changes: 15 additions & 0 deletions src/uu/pmap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
7 changes: 7 additions & 0 deletions src/uu/pmap/pmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# pmap

```
pmap [options] pid [...]
```

Report memory map of a process
1 change: 1 addition & 0 deletions src/uu/pmap/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uucore::bin!(uu_pmap);
145 changes: 145 additions & 0 deletions src/uu/pmap/src/pmap.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
12 changes: 12 additions & 0 deletions tests/by-util/test_pmap.rs
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 4 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit 0b6d165

Please sign in to comment.