Skip to content

Parent process with "windows" subsystem can't properly create console child process #101645

Closed
@CrendKing

Description

@CrendKing

I tried this code:

App P:

#![windows_subsystem = "windows"]

fn main() {
    std::process::Command::new("<path_to_app_C>").spawn().unwrap();
    std::thread::sleep(std::time::Duration::from_secs(100));
}

App C:

fn main() {
    loop {
        println!("Hello World!");
        std::thread::sleep(std::time::Duration::from_secs(1));
    }
}

Build this in Windows.

I expected to see this happen:

Since P has "windows" subsystem, it will create no console window (i.e. no conhost.exe process). Since C is a console app, when the process is created, I expect to see one console window that prints "Hello World" infinitely.

Instead, this happened: explanation

App C creates its console window but no text is printed.

What I suspect the cause of the issue

In Windows, spawn() eventually calls to CreateProcessW with a STARTUPINFO, whose dwFlags is hard coded to STARTF_USESTDHANDLES. Additionally, it also get device handles of stdin, stdout and stderr with GetStdHandle, and set them to the STARTUPINFO. Since app P uses "windows" subsystem, it does not have console. stdout is always INVALID_HANDLE_VALUE. Combining STARTF_USESTDHANDLES with INVALID_HANDLE_VALUE in STARTUPINFO causes the unexpected behavior.

If I make a call to CreateProcessW with same parameters except a "zeroed" STARTUPINFO, it exhibits the correct behavior.

Suggestion

spawn() should only conditionally set the STARTF_USESTDHANDLES flag if it can obtain those device handles, and never set any of those handles INVALID_HANDLE_VALUE. Like this (pseudo code):

let mut si = zeroed_startupinfo();
si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;

si.hStdInput = stdin.to_handle().unwrap_or(0);
si.hStdOutput = stdout.to_handle().unwrap_or(0);
si.hStdError = stderr.to_handle().unwrap_or(0);

if si.hStdInput != 0 || si.hStdOutput != 0 || si.hStdError != 0 {
    si.dwFlags |= c::STARTF_USESTDHANDLES;
}

Meta

rustc --version --verbose:

rustc 1.63.0 (4b91a6ea7 2022-08-08)
binary: rustc
commit-hash: 4b91a6ea7258a947e59c6522cd5898e7c0a6a88f
commit-date: 2022-08-08
host: x86_64-pc-windows-msvc
release: 1.63.0
LLVM version: 14.0.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-windowsOperating system: WindowsT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions