Skip to content

fix: suppress xlings subprocess noise on Windows during bootstrap#57

Merged
Sunrisepeak merged 1 commit into
mainfrom
fix/windows-bootstrap-noise-v2
May 20, 2026
Merged

fix: suppress xlings subprocess noise on Windows during bootstrap#57
Sunrisepeak merged 1 commit into
mainfrom
fix/windows-bootstrap-noise-v2

Conversation

@Sunrisepeak
Copy link
Copy Markdown
Member

Summary

  • Fix ensure_init() missing output redirect on Windows — xlings self init internal messages no longer leak to terminal
  • Fix install_with_progress() fallback missing stderr redirect on Windows — NDJSON interface stderr suppressed

Problem

Windows first-run printed excessive xlings internal output (debug messages, extraction logs) while Linux/macOS were clean and silent. Two subprocess calls were missing platform-appropriate output redirection on Windows.

Test plan

  • Verify Windows first-run only shows mcpp status messages + progress bars
  • Verify Linux/macOS first-run behavior unchanged
  • CI passes on all three platforms

Two places in the first-run bootstrap path were missing output
redirection on Windows, causing xlings internal messages to leak
to the terminal:

1. ensure_init(): `xlings self init` ran without any output redirect
   on Windows (Linux/macOS already had >/dev/null 2>&1). Now appends
   platform::shell::silent_redirect (">/dev/null 2>&1" on Windows).

2. install_with_progress() fallback: the NDJSON interface command
   had no stderr redirect on Windows (Linux/macOS had 2>/dev/null).
   Now appends platform::null_redirect ("2>nul" on Windows).

After this fix, the first-run experience is consistent across all
three platforms — only mcpp's own status messages and progress bars
are shown; xlings internal output is fully suppressed.
@Sunrisepeak Sunrisepeak merged commit ffdc2d2 into main May 20, 2026
3 checks passed
Sunrisepeak added a commit that referenced this pull request May 23, 2026
* fix: seal child-process stdin on Windows (first-run hang)

mcpp's first-run flow on Windows was hanging at xlings / xim / curl / git
grandchildren that block on terminal stdin, forcing users to press Enter
repeatedly to advance bootstrap and toolchain install.

Root cause: process::seal_stdin was a no-op on Windows, and
install_with_progress's direct-install path deliberately bypassed it.
The POSIX side has had </dev/null sealing since PR #55 (macOS xcrun hang
fix); Windows never received the equivalent fix. PR #57 only suppressed
stdout/stderr noise (>/dev/null 2>&1) and did not touch stdin.

Changes:
  - process.cppm: seal_stdin now appends "<NUL" on Windows (matches POSIX
    behavior). All capture / run_silent / run_streaming / run_passthrough
    callers gain the protection automatically.
  - xlings.cppm: install_with_progress's direct path explicitly appends
    "<NUL" on Windows. POSIX keeps the original behavior conservatively.
  - shell.cppm: silent_redirect docstring corrected — it never touched
    stdin, that's seal_stdin's job. Implementation unchanged.

Regression coverage:
  - tests/unit/test_process_seal_stdin.cpp — deterministic reproduction
    test. Rebinds the test process's own stdin to an open, empty,
    never-closing pipe, then calls run_silent / capture / run_streaming
    with a child that reads stdin (more on Windows, cat on POSIX).
    Without the fix the child would block forever waiting on our pipe;
    with the fix it reads NUL / /dev/null and exits immediately. 5-second
    upper bound (real runs complete in <100ms).
  - ci-windows.yml — adds a step that launches mcpp via
    System.Diagnostics.Process with RedirectStandardInput=$true (parent
    holds the child's stdin open but never writes). Runs mcpp --version,
    mcpp build, mcpp run. Without the fix, any grandchild reading stdin
    blocks → step times out → CI fails. With the fix → all complete.

* ci(windows): convert MCPP_SELF MSYS path → Windows path; rename pwsh $Args

Two issues with the regression step from the previous commit (both showed
up only on the actual Windows runner, not in local validation):

1. MCPP_SELF was set in an earlier bash step via `pwd` (git-bash) so the
   value is MSYS-style (e.g. /d/a/mcpp/...). Bash steps tolerate it but
   pwsh's `&` operator can't exec it ("not recognized as a name of a
   cmdlet, function, script file, or executable program"). Convert via
   cygpath -w before use.

2. `$Args` is a PowerShell automatic variable inside function scope; a
   `param([string]$Args)` does not bind cleanly. Renamed to $McppArgs
   to avoid the collision (also updated call sites).
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.

1 participant