tokio: Cannot run any command with piped stdin with Nightly toolchain
Version
tokio v1.18.2
Toolchains
cargo 1.60.0 (d1fd9fe2c 2022-03-01)
cargo 1.62.0-nightly (a44758ac8 2022-05-04)
Platform
Windows 11
Description
I cannot spawn any tokio::process::Comand with a piped stdin in the Nightly toolchain.
I tried this code:
use tokio::process::Command;
use std::process::Stdio;
#[tokio::main]
async fn main() {
Command::new("cmd")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
}
I did not expect any output because it’s being spawned.
Running on the stable toolchain:

Instead, when running with the nightly toolchain, it throws this error:

If I make it inherit stdin (default behavior):
Command::new("cmd")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
It will run just fine in the nightly toolchain:

Am I missing something maybe ? 🤔
Thanks!
About this issue
- Original URL
- State: open
- Created 2 years ago
- Comments: 16 (7 by maintainers)
Commits related to this issue
- Rollup merge of #97149 - ChrisDenton:win_async_pipes, r=m-ou-se Windows: `CommandExt::async_pipes` Discussed in https://github.com/tokio-rs/tokio/issues/4670 was the need for third party crates to b... — committed to Dylan-DPC/rust by Dylan-DPC 2 years ago
- Rollup merge of #97149 - ChrisDenton:win_async_pipes, r=m-ou-se Windows: `CommandExt::async_pipes` Discussed in https://github.com/tokio-rs/tokio/issues/4670 was the need for third party crates to b... — committed to tcdi/postgrestd by Dylan-DPC 2 years ago
It’s unfortunate that libraries depend on the child process pipes being asynchronous ones, since that wasn’t a documented promise in
std. It seems we have two ways forward:.as_raw_handle()from astd::process::ChildStd{in,out,err}is always an asynchronous pipe on Windows. This meansstdhas to spawn a thread to copy over data from the async pipe into a new sync pipe when the pipe is given to anotherCommand. Or:For 2, we could add something like a
.async_pipes(true)tostd::os::windows::process::CommandExtso there’s a way to explicitly request async pipes.If you provide an
async_pipesconfig option, then it shouldn’t be a problem to add calls to it. We should be able to use a build script to detect the version of Rust and only call it on versions where it exists.Unfortunately, I don’t think it’s possible to change whether Tokio wraps the standard library
Commandstruct due to backwards compatibility.Filed a regression issue in https://github.com/rust-lang/rust/issues/97124. We’ll revert the PR on the upcoming 1.62 beta release, and most likely on nightly as well.