Skip to content

fix: bail on --watch without a terminal - #983

Open
Mathjk wants to merge 1 commit into
dalance:masterfrom
Mathjk:fix/watch-non-tty-bail
Open

Mathjk wants to merge 1 commit into
dalance:masterfrom
Mathjk:fix/watch-non-tty-bail

Conversation

@Mathjk

@Mathjk Mathjk commented Sep 29, 2026

Copy link
Copy Markdown

Fixes #982.

Bug

procs -w with non-terminal stdout enters the TUI watch loop and emits ANSI frames into the pipe/file forever. A related case: procs -w </dev/null makes the getch keyboard thread spin at ~100% CPU (stdin.read returns Ok(0) instantly in a tight loop) and q can't quit.

Plain procs | cat is correct and unchanged — only watch mode is broken on non-tty.

Fix (+14/-1, src/main.rs)

In run_watch — before any frame write or Watcher::start:

if !stdout().is_terminal() {
    return Err(Error::msg("--watch requires a terminal, but stdout is not a TTY"));
}
if !std::io::stdin().is_terminal() {
    return Err(Error::msg("--watch requires a terminal, but stdin is not a TTY"));
}

IsTerminal is std (≥1.70; crate MSRV 1.88) — no dependency churn. Covers -w, --watch, and -W/--watch-interval (all funnel here). Bails through the existing error: stderr printer → exit 1.

Verified

Case Before After
procs -w | cat / > file ANSI frames forever error: --watch requires a terminal…, rc=1
procs -w </dev/null (tty out) getch ~100% CPU spin error: … stdin is not a TTY, rc=1
procs -w | head late "Broken pipe" immediate clean bail
procs | cat table output unchanged
procs -w real tty renders, q quits unchanged (verified Linux PTY + Windows ConPTY)

cargo test 24/24; fmt/clippy clean; x86_64-pc-windows-gnu build green.

Watch mode (-w/--watch/--watch-interval) is an interactive TUI like top.
With piped or redirected stdout it wrote ANSI screen frames into the
pipe/file forever, and with a non-terminal stdin the getch thread spun
at ~100% CPU. Bail out with a clear error instead.

Fixes dalance#982
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.

procs -w with piped stdout runs the interactive watch TUI (ANSI frames forever, CPU spin on non-tty stdin)

1 participant