Skip to content

wall initial implementation - #578

Open
cmoibssld wants to merge 3 commits into
uutils:mainfrom
cmoibssld:main
Open

cmoibssld wants to merge 3 commits into
uutils:mainfrom
cmoibssld:main

Conversation

@cmoibssld

Copy link
Copy Markdown

This pull request introduces an implementation of the 'wall' utility. It aims to be a first-draft binary crate since the flags of the wall command are not implemented yet.

New utility implementation:

  • adds a new binary crate uu_wall on src/uu/wall with Cargo.toml specifying dependencies (uucore, clap, nix...)
  • implements the core logic inside wall.rs. supports message input from stdin or command-line arguments
  • a simple entrypoint in main.rs to call the utility with the uucore macro

CLI and mechanics:

  • uses clap for parsing arguments. CLI flags are parsed but not yet implemented (placeholder for future extension)
  • after retreiving the messages, scan all logged-in users via the utmpx utility and then proceed to write into their terminal the message.

@sylvestre

Copy link
Copy Markdown
Contributor

nice
could you please add unit tests in tests/ ?
thanks

@cakebaker cakebaker changed the title wall initial implentation wall initial implementation Jun 24, 2026
@sylvestre

Copy link
Copy Markdown
Contributor

a few jobs are failing
(i was going to review it)

@cmoibssld

Copy link
Copy Markdown
Author

Yes sorry I updated the pr by error, I still need to work on this

Copilot AI lite review requested due to automatic review settings August 13, 2026 06:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Introduces an initial implementation of the wall utility as a new optional workspace crate, along with basic CLI parsing and a small set of utility-specific tests.

Changes:

  • Adds new uu_wall crate (library + binary) and wires it into workspace features/dependencies
  • Implements Unix-only wall logic: message sourcing (stdin/args/file), scanning logged-in users via utmpx, and writing to ttys
  • Adds initial tests and minor formatting/import cleanups in existing test files

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/tests.rs Registers the wall test module behind the wall feature flag
tests/by-util/test_wall.rs Adds initial cross-platform tests for wall behavior
tests/by-util/test_setsid.rs Adjusts import ordering (no functional change)
tests/by-util/test_lslocks.rs Reflows an array literal for formatting (no functional change)
src/uu/wall/wall.md Adds minimal help/about text for wall
src/uu/wall/src/wall.rs Implements the core wall command logic and CLI definition
src/uu/wall/src/main.rs Adds binary entrypoint using uucore::bin!
src/uu/wall/Cargo.toml Adds new crate manifest and dependencies for uu_wall
Cargo.toml Enables wall as an optional workspace feature/dependency

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/Cargo.toml Resolved
Comment thread tests/by-util/test_wall.rs Resolved
Copilot AI review requested due to automatic review settings September 1, 2026 09:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 7 comments.

Suppressed comments (8)

src/uu/wall/Cargo.toml:19

  • The nix dependency enables a feature named "feature", which doesn’t appear to be used elsewhere in this workspace and is likely not a valid nix crate feature; this can cause Cargo feature resolution failures.
chrono = { workspace = true }
clap.workspace = true
nix = { workspace = true, features = ["feature", "fs", "hostname", "term"] }
thiserror.workspace = true

src/uu/wall/src/wall.rs:40

  • WallError::Stdin is used via #[from] io::Error, so file-open/read errors also get reported as "cannot read stdin". Consider using a more general message so file input failures aren’t mislabeled.
enum WallError {
    #[error("wall: cannot read stdin")]
    Stdin(#[from] io::Error),
    #[error("wall: encoding error")]

src/uu/wall/src/wall.rs:58

  • handle_clap_result(...).map_err(|e| USimpleError::new(1, ...)) forces exit code 1 for clap’s help/version output and other parsing errors. Other utilities in this repo rely on try_get_matches_from(args)? so clap/help uses the expected exit codes.
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)
        .map_err(|e| USimpleError::new(1, e.to_string()))?; // Clap would have return 101
    // Might be considered wrong for --help and --version
    let message = get_message(matches.get_many(STRING).unwrap_or_default())?;

src/uu/wall/src/wall.rs:122

  • Same as the Linux cfg: prefer Command::new(uucore::util_name()) to follow the established pattern across utilities and keep the displayed name consistent.
pub fn uu_app() -> Command {
    Command::new("wall")
        .version(uucore::crate_version!())

src/uu/wall/src/wall.rs:101

  • Typo in user-facing help text: "branner" → "banner".
                .required(false)
                .action(ArgAction::SetTrue)
                .help("Suppress the intro branner of the broadcast"),
        )

src/uu/wall/src/wall.rs:133

  • Same user-facing help text issue here (ungrammatical).
                .value_name("GROUP")
                .help("Send restrict to only users in the group(s)")
                .num_args(1)

src/uu/wall/src/wall.rs:218

  • On macOS the broadcast header format string is missing the closing ")" after the datetime, which makes the output inconsistent with Linux and likely incorrect.
        "\r\nBroadcast message from {}@{} ({tty}) at ({datetime} \r\n\r\n",

tests/by-util/test_wall.rs:24

  • This test doesn’t assert anything, so it may not actually execute the command (unlike the other tests in this directory which call .succeeds()/.fails()). Add an explicit expectation so the test verifies behavior on Linux.
fn test_invalid_file() {
    new_ucmd!().arg("not_existing_file.not_existing_extension"); // Should print non-file name as broadcast
}

Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/main.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/wall.md Resolved
Copilot AI lite review requested due to automatic review settings October 26, 2026 10:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved build, option-handling, output-formatting, error-handling, and test issues remain.

16 open issues
1 resolved since last review

Review effort: Lite

Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Copilot AI lite review requested due to automatic review settings November 2, 2026 17:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Active critical, moderate, and test-coverage issues remain, including a dependency configuration that prevents compilation, unsupported-platform build failures, incorrect CLI behavior, and unimplemented options.

19 open issues

Review effort: Lite

Comment thread src/uu/wall/Cargo.toml Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Copilot AI lite review requested due to automatic review settings November 2, 2026 17:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Several critical platform-specific compilation failures remain in the Unix implementation, including invalid imports, undefined options and symbols, and an undefined error variable.

9 open issues
14 resolved since last review

Review effort: Lite

Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Copilot AI lite review requested due to automatic review settings November 3, 2026 12:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/wall.rs Resolved
Comment thread src/uu/wall/src/main.rs Resolved
Copilot AI lite review requested due to automatic review settings November 7, 2026 16:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/uu/wall/src/wall.rs
let binding = unistd::gethostname().unwrap_or_else(|_| "".into());
let hostname = binding.to_string_lossy();

let user: String = env::var_os(user)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyone can run USER=root wall hi and the banner says it is from root
please use getlogin() / the uid's passwd entry instead of $USER

Comment thread src/uu/wall/src/wall.rs
if args.len() == 0 {
read_from_stdin()
} else if args.len() == 1 {
match read_from_file(args.clone().next().unwrap()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if wall is installed setgid tty, this lets any user read a file only the tty group can read
util-linux refuses to read the file when uid != euid or gid != egid, could you please do the same?

Comment thread src/uu/wall/src/wall.rs
.collect();
// Same here, control characters could also be hidden in the message provided. We still want newline char of course...
#[cfg(not(target_os = "macos"))]
let formatted_message = formatted_message.replace('\n', "\r\n\n");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why \r\n\n? this adds an empty line after every line of the message

Comment thread src/uu/wall/src/wall.rs
while !ttys.is_empty() {
let remaining = deadline.saturating_duration_since(std::time::Instant::now());
if remaining.is_zero() {
return Err(WallError::TimeoutError.into());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one stuck terminal makes the whole wall fail with exit 1
is that wanted? i would expect it to just give up on that tty

Comment thread src/uu/wall/src/wall.rs

// #[cfg(all(unix, not(target_os = "linux"), not(target_os = "openbsd")))]
#[cfg(not(target_os = "linux"))]
pub fn uu_app() -> Command {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

almost the same uu_app twice, with the commented-out group block copied in both
could be dedup with cfg on the linux-only args, no? and please remove the commented code

fn test_invalid_file() {
new_ucmd!()
.arg("not_existing_file.not_existing_extension")
.succeeds(); // Should print non-file name as broadcast

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this sends a real broadcast to everyone logged in on the machine running the tests
please add tests that check something (--help, -t 0 rejected, invalid utf-8, ...) without hitting the real ttys

Comment thread Cargo.lock
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated lockfile format bump (and num-conv), please revert

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants