extern crate alloc;
use alloc::vec::Vec;
use crate::io;
pub fn lsmod(_argc: i32, _argv: *const *const u8) -> i32 {
io::write_str(1, b"Module Size Used by\n");
let fd = io::open(b"/proc/modules", libc::O_RDONLY, 0);
if fd < 0 {
return 1;
}
let mut buf = [0u8; 65536];
let n = io::read(fd, &mut buf);
io::close(fd);
if n <= 0 {
return 0;
}
let content = &buf[..n as usize];
for line in content.split(|&c| c == b'\n') {
if line.is_empty() {
continue;
}
let fields: Vec<&[u8]> = line.split(|&c| c == b' ')
.filter(|s| !s.is_empty())
.collect();
if fields.len() < 3 {
continue;
}
let name = fields[0];
let size = fields[1];
let refcount = fields[2];
let deps = if fields.len() > 3 { fields[3] } else { b"-" };
io::write_all(1, name);
let name_padding = 20usize.saturating_sub(name.len());
for _ in 0..name_padding {
io::write_str(1, b" ");
}
let size_padding = 8usize.saturating_sub(size.len());
for _ in 0..size_padding {
io::write_str(1, b" ");
}
io::write_all(1, size);
io::write_str(1, b" ");
io::write_all(1, refcount);
if deps != b"-" && !deps.is_empty() {
io::write_str(1, b" ");
if deps.ends_with(b",") {
io::write_all(1, &deps[..deps.len() - 1]);
} else {
io::write_all(1, deps);
}
}
io::write_str(1, b"\n");
}
0
}
#[cfg(test)]
mod tests {
extern crate std;
use std::process::Command;
use std::path::PathBuf;
fn get_armybox_path() -> PathBuf {
if let Ok(path) = std::env::var("ARMYBOX_PATH") {
return PathBuf::from(path);
}
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| std::env::current_dir().unwrap());
let release = manifest_dir.join("target/release/armybox");
if release.exists() { return release; }
manifest_dir.join("target/debug/armybox")
}
#[test]
fn test_lsmod_runs() {
let armybox = get_armybox_path();
if !armybox.exists() { return; }
let output = Command::new(&armybox)
.args(["lsmod"])
.output()
.unwrap();
assert_eq!(output.status.code(), Some(0));
let stdout = std::string::String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Module"));
}
#[test]
fn test_lsmod_has_columns() {
let armybox = get_armybox_path();
if !armybox.exists() { return; }
let output = Command::new(&armybox)
.args(["lsmod"])
.output()
.unwrap();
assert_eq!(output.status.code(), Some(0));
let stdout = std::string::String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Module"));
assert!(stdout.contains("Size"));
assert!(stdout.contains("Used by"));
}
}