Skip to content

Conversation

@npiesco
Copy link

@npiesco npiesco commented Feb 6, 2026

While Command itself is designed to be OS-agnostic, spawned programs behavior may differ by platform. Example, invoking program with no arguments may hang on Windows (if waits for stdin) but exit immediately on Unix.

This adds new section to Command documentation noting behavior and suggesting use of flags like --version to ensure consistent behavior when probing for program availability.

Context:
Discovered while debugging cross-platform build system (Servo) that hung on Windows ARM64 when detecting Python availability. Fix was use python --version instead of python with no args.

This addresses workingjubilee's suggestion in #152143 (comment):

While Command is intended to be OS-agnostic, spawning a process itself can still have enough OS-specific consequences, unavoidably, that it makes the same thing less useful. That may be something to document."

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Feb 6, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 6, 2026

r? @jhpratt

rustbot has assigned @jhpratt.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ChrisDenton, libs
  • @ChrisDenton, libs expanded to 8 candidates
  • Random selection from ChrisDenton, Mark-Simulacrum, jhpratt

@npiesco
Copy link
Author

npiesco commented Feb 6, 2026

r? @workingjubilee

@rustbot rustbot assigned workingjubilee and unassigned jhpratt Feb 6, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 6, 2026

workingjubilee is currently at their maximum review capacity.
They may take a while to respond.

@ChrisDenton
Copy link
Member

This just seems to be python specific behaviour, no? I'm not sure it's useful for rust documentation to include documentation on python's platform differences.

@npiesco
Copy link
Author

npiesco commented Feb 6, 2026

This just seems to be python specific behaviour, no? I'm not sure it's useful for rust documentation to include documentation on python's platform differences.

No. Issue is general. Applies to any program that:

  • Waits for stdin when given no arguments (REPLs, interpreters, cat, node, etc.)
  • Doesn't detect non-TTY stdin to exit early

Python is just an example. I updated the documentation to say:

"invoking it with no arguments may hang on Windows (if the program waits for stdin)"

Same principle applies to node/ruby/cat/bc.... any stdin-reading program. Python just happened to be the case that exposed this in Servo, so it's a concrete, relatable example. Using it to be illustrative, not exhaustive.

See: servo/servo#42340

EDIT: Will make slight tweak to comments to make this clearer.

While Command itself is OS-agnostic, spawned programs behavior may differ by platform. Example, invoking program with no arguments
may hang on Windows (waits for stdin) but exit immediately on Unix.

This documents issue and suggests using flags like --version to ensure consistent behavior when probing for program availability.

Discovered while debugging a cross-platform build system that hung on
Windows ARM64 when detecting Python availability.
@npiesco npiesco force-pushed the docs-process-platform-behavior branch from 288e65f to d55672f Compare February 6, 2026 15:57
@ChrisDenton
Copy link
Member

ChrisDenton commented Feb 6, 2026

Is node affected? That surprises me if so. I'm doubly surprised about cat tbh, Have you tested this?

Applies to any program that:

  • Waits for stdin when given no arguments (REPLs, interpreters, cat, node, etc.)
  • Doesn't detect non-TTY stdin to exit early

But that's just as true on Unix platforms as it is on Windows. There's no particular reason why a Windows application cannot detect non-TTY stdin and exit early. The fact that python doesn't seems like a quirk of python.

@npiesco
Copy link
Author

npiesco commented Feb 6, 2026

Is node affected? That surprises me if so. I'm doubly surprised about cat tbh, Have you tested this?

Applies to any program that:

  • Waits for stdin when given no arguments (REPLs, interpreters, cat, node, etc.)
  • Doesn't detect non-TTY stdin to exit early

But that's just as true on Unix platforms as it is on Windows. There's no particular reason why a Windows application cannot detect non-TTY stdin and exit early. The fact that python doesn't seems like a quirk of python.

Yes to node and yes to cat as well. All tested. Minimal Rust reproduction:

use std::process::Command;
use std::time::{Duration, Instant};

fn test_program(name: &str, timeout_secs: u64) {
    println!("Testing '{}'...", name);
    let start = Instant::now();
    let mut child = match Command::new(name).spawn() {
        Ok(c) => c,
        Err(e) => { println!("  '{}' failed: {}", name, e); return; }
    };
    loop {
        match child.try_wait() {
            Ok(Some(status)) => {
                println!("  '{}' exited in {:?}", name, start.elapsed());
                return;
            }
            Ok(None) => {
                if start.elapsed() > Duration::from_secs(timeout_secs) {
                    child.kill().ok();
                    println!("  '{}' HUNG (killed after {}s)", name, timeout_secs);
                    return;
                }
                std::thread::sleep(Duration::from_millis(100));
            }
            Err(e) => { println!("  '{}' error: {}", name, e); return; }
        }
    }
}

fn main() {
    test_program("python", 5);  // or python3 on Unix
    test_program("node", 5);
    test_program("cat", 5);     // GNU coreutils via Git for Windows
}

Results:

Program Windows (ARM64) Unix (WSL Ubuntu, stdin piped to /dev/null)
python HUNG (5s+) 0.03s
node HUNG (5s+) 0.18s
cat HUNG (5s+) 0.00s

You're right that programs could detect non-TTY stdin on Windows. But observed behavior is that common programs don't; they wait for console input. On Unix, (verified on WSL) same programs receive immediate EOF from pipe and exit.

TL;DR: Not Python quirk but rather a cross-platform footgun when using Command to probe for program availability.

NOTE: cat tested is GNU coreutils on both platforms (Windows build via Git for Windows, Linux build on WSL). Same source code, different platform behavior. Windows build waits for console input while Linux build detects EOF from pipe and exits immediately.

@ChrisDenton
Copy link
Member

You don't say how you're running this on Windows. If running directly from the console then by default a tty would be attached. The original servo code was using Command::output to capture the output (and thereby assured that it was using pipes).

@npiesco
Copy link
Author

npiesco commented Feb 6, 2026

You don't say how you're running this on Windows. If running directly from the console then by default a tty would be attached. The original servo code was using Command::output to capture the output (and thereby assured that it was using pipes).

Ooo! You're right. Apologies My original test was flawed. Used spawn() which inherited console TTY.

Reran with proper Stdio::null() to match what Command::output() does:

Command::new(name)
    .stdin(Stdio::null())
    .stdout(Stdio::piped())
    .stderr(Stdio::piped())
    .spawn()
Program Windows (stdin=null)
python HUNG (5s+)
node 0.64s
cat 0.11s

Only Python hangs! node + cat both detected EOF and exit on Windows. I stand corrected. This is indeed Python-specific behavior, not a general platform issue. Will close this PR as I agree, documentation change isn't warranted.

Also, thanks for pushing back and making me verify properly. Servo fix (using --version) is still correct, but it's working around the Python quirk, not platform behavior.

@npiesco npiesco closed this Feb 6, 2026
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants