-
Notifications
You must be signed in to change notification settings - Fork 14k
Description
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