Skip to content

fix: suppress stdout in library mode for silent embedding#917

Open
Functionhx wants to merge 11 commits into
bee-san:masterfrom
Functionhx:fix/rustscan-706-stdout
Open

fix: suppress stdout in library mode for silent embedding#917
Functionhx wants to merge 11 commits into
bee-san:masterfrom
Functionhx:fix/rustscan-706-stdout

Conversation

@Functionhx

Copy link
Copy Markdown

Default library output to silent. CLI explicitly enables output. Tests verify fresh-process default-silent behavior, toggle flag isolation, and cross-platform binary path resolution.

Fixes: #706

Signed-off-by: Functionhx 2994114386@qq.com

Add a global AtomicBool flag SUPPRESS_STDOUT (default false for CLI
compatibility) and a public suppress_output() function. Single-argument
forms of the warning!, detail!, output!, and funny_opening! macros now
check this flag before printing. Also fix a bare println! in the UDP
scanner error path that bypassed the greppable check.

Closes bee-san#706

Signed-off-by: Yuchen Fan <functionhx@gmail.com>
fmt_ports() in scanner/mod.rs now checks SUPPRESS_STDOUT before
printing open port lines. warning!/detail!/output! 3-argument macro
arms in tui.rs also gate on SUPPRESS_STDOUT so library callers using
suppress_output() get true silence.

Signed-off-by: Yuchen Fan <functionhx@gmail.com>
- src/input.rs: guard println! with SUPPRESS_STDOUT in Config::read()
  and replace std::process::exit(1) with panic! for library safety
- src/scanner/mod.rs: revert undocumented eprintln! to println! at
  sock binding error site

Signed-off-by: Functionhx <2994114386@qq.com>
Signed-off-by: Yuchen Fan <functionhx@gmail.com>
The prior change replaced a clean process exit with a panic, which:
- Unwinds the full stack (exit(1) terminates immediately)
- Prints a messy panic message + backtrace to stderr
- Leaks error output to stderr even when SUPPRESS_STDOUT is true

Restore the original exit(1) behavior, keeping only the conditional
println! guard for stdout suppression. The scope of issue bee-san#706 is
stdout noise, not error handling semantics.

Signed-off-by: Yuchen Fan <functionhx@gmail.com>
Verify suppress_output() flips SUPPRESS_STDOUT to true, defaults to
false, and is idempotent across repeated calls.

Signed-off-by: Yuchen Fan <functionhx@gmail.com>
…orks

Replace flawed unit tests (line 88 stored false before asserting, line 99
only checked AtomicBool) with a subprocess integration test that builds and
runs the stdout_check example, capturing real stdout. Asserts pre-suppression
markers appear and post-suppression markers do not.

Signed-off-by: Yuchen Fan <functionhx@gmail.com>
…licitly

Isolation review found that SUPPRESS_STDOUT defaulted to false,
requiring library consumers to manually call suppress_output().
This does not fully resolve issue bee-san#706 because existing library
usage remains noisy by default.

Change SUPPRESS_STDOUT default to true (silent by default).
Add enable_output() to allow library consumers and the CLI to
explicitly enable terminal output. The CLI calls enable_output()
at the start of main(). Integration tests updated accordingly.

Fixes: bee-san#706
Signed-off-by: Yuchen Fan <functionhx@gmail.com>
…cess default-silent test

R4 review identified two defects:

1. The four toggle tests in src/lib.rs (suppress_output_sets_flag,
   suppress_output_is_idempotent, enable_output_clears_flag,
   default_is_suppressed) shared the SUPPRESS_STDOUT AtomicBool static
   and raced under parallel test execution. Combined them into a single
   sequential test (toggle_flag_behavior) to eliminate races.

2. default_is_suppressed manually stored true before asserting, never
   tested the actual AtomicBool::new(true) initialiser. Added a
   fresh-process integration test via new example default_silent.rs
   that emits macros without calling enable_output() and verifies
   stdout is empty — proving the library is silent by default.

Also parameterised example_binary() and ensure_example_built() in
tests/stdout_suppression.rs to avoid duplication.

Fixes: bee-san#706
Signed-off-by: Yuchen Fan <functionhx@gmail.com>
The fallback binary path constructed in example_binary() omitted
std::env::consts::EXE_SUFFIX, causing bin.exists() to fail on
Windows where example binaries have a .exe extension.

Signed-off-by: Yuchen Fan <functionhx@gmail.com>
- Use cargo build --message-format=json to resolve release/debug profile
  mismatch: profile flag now matches cfg!(debug_assertions), and the
  returned path respects CARGO_TARGET_DIR / workspace layouts.
- Save and restore SUPPRESS_STDOUT in toggle_flag_behavior to avoid
  contaminating parallel unit tests sharing the process-global AtomicBool.

Signed-off-by: Yuchen Fan <functionhx@gmail.com>
…licing

Naive string slicing on JSON lines fails when CARGO_TARGET_DIR
contains escape-worthy characters (backslashes, quotes, control
chars). Replace with serde_json::Value deserialization which
correctly decodes escape sequences.

Signed-off-by: Functionhx <2994114386@qq.com>
Signed-off-by: Yuchen Fan <functionhx@gmail.com>
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.

Rustcan API Library is too noisy in stdout

1 participant