Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions src/uu/lsns/src/lsns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod errors;
#[cfg(target_os = "linux")]
mod smartcols;

use clap::{Command, crate_version};
use clap::{Arg, ArgAction, Command, crate_version};
#[cfg(target_os = "linux")]
use std::ffi::CString;
#[cfg(target_os = "linux")]
Expand Down Expand Up @@ -88,7 +88,10 @@ struct Lsns {

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let _matches = uu_app().try_get_matches_from(args)?;
let matches = uu_app().try_get_matches_from(args)?;

// Print no headings if this flag is set
let noheadings = matches.get_flag("noheadings");

let mut lsns = Lsns {
processes: Vec::new(),
Expand All @@ -99,7 +102,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {

read_namespaces(&mut lsns)?;

display_namespaces(&lsns)?;
display_namespaces(&lsns, noheadings)?;

Ok(())
}
Expand All @@ -110,6 +113,13 @@ pub fn uu_app() -> Command {
.about(ABOUT)
.override_usage(format_usage(USAGE))
.infer_long_args(true)
.arg(
Arg::new("noheadings")
.short('n')
.long("noheadings")
.action(ArgAction::SetTrue)
.help("don't print headings"),
)
}

/// Read information of all the processes from /proc
Expand Down Expand Up @@ -481,7 +491,7 @@ impl NamespaceType {

/// Display namespaces in default format using smartcols
#[cfg(target_os = "linux")]
fn display_namespaces(lsns: &Lsns) -> Result<(), LsnsError> {
fn display_namespaces(lsns: &Lsns, noheadings: bool) -> Result<(), LsnsError> {
use smartcols_sys::{SCOLS_FL_RIGHT, SCOLS_FL_TRUNC};

// Initialize smartcols
Expand All @@ -490,6 +500,11 @@ fn display_namespaces(lsns: &Lsns) -> Result<(), LsnsError> {
// Create table
let mut table = Table::new()?;

// Enable or disable headings based on flag
if noheadings {
table.enable_headings(false)?;
}

// NS: width_hint=10, right-aligned
table.new_column(c"NS", 10.0, SCOLS_FL_RIGHT)?;
// TYPE: width_hint=5, left-aligned
Expand Down Expand Up @@ -557,7 +572,7 @@ fn display_namespaces(lsns: &Lsns) -> Result<(), LsnsError> {
}

#[cfg(not(target_os = "linux"))]
fn display_namespaces(_lsns: &Lsns) -> Result<(), LsnsError> {
fn display_namespaces(_lsns: &Lsns, _noheadings: bool) -> Result<(), LsnsError> {
Err(LsnsError::UnsupportedPlatform)
}

Expand Down
10 changes: 8 additions & 2 deletions src/uu/lsns/src/smartcols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use std::{io, ptr};

use smartcols_sys::{
libscols_column, libscols_line, libscols_table, scols_init_debug, scols_line_set_data,
scols_new_table, scols_print_table, scols_table_new_column, scols_table_new_line,
scols_unref_table,
scols_new_table, scols_print_table, scols_table_enable_noheadings, scols_table_new_column,
scols_table_new_line, scols_unref_table,
};

use crate::errors::LsnsError;
Expand Down Expand Up @@ -45,6 +45,12 @@ impl Drop for Table {
pub(crate) trait TableOperations: Sized {
fn as_ptr(&self) -> *mut libscols_table;

fn enable_headings(&mut self, enable: bool) -> Result<(), LsnsError> {
let no_headings = c_int::from(!enable);
let r = unsafe { scols_table_enable_noheadings(self.as_ptr(), no_headings) };
LsnsError::io_from_neg_errno("scols_table_enable_noheadings", r).map(|_| ())
}

fn new_column(
&mut self,
name: &CStr,
Expand Down
14 changes: 14 additions & 0 deletions tests/by-util/test_lsns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ fn test_output_format() {
}
}

#[test]
#[cfg(target_os = "linux")]
fn test_noheadings() {
let res = new_ucmd!().arg("-n").succeeds();
let stdout = res.no_stderr().stdout_str();

let headers = ["NS", "TYPE", "NPROCS", "PID", "USER", "COMMAND"];

for header in headers {
let msg = format!("{} header should not be present when -n is used", header);
assert!(!stdout.contains(header), "{}", msg);
}
}

#[test]
#[cfg(target_os = "linux")]
fn test_namespace_ids_are_numeric() {
Expand Down
Loading