diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-06-20 14:56:38 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-20 14:56:38 +0200 |
| commit | 85f1de20e76001db54d64ee0c3f9fec797075938 (patch) | |
| tree | a3a48b7d1e82a50ff787ec06c0e055becfd09981 | |
| parent | 625c929a9fecc7fbaf7142faaab787ba8125a62f (diff) | |
| parent | 740a54c69b1c426c2b08329ea278140eb0059d42 (diff) | |
| download | rust-85f1de20e76001db54d64ee0c3f9fec797075938.tar.gz rust-85f1de20e76001db54d64ee0c3f9fec797075938.zip | |
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 be able to force `process::Command::spawn` to create pipes as async.
This implements the suggestion for a `async_pipes` method that gives third party crates that option.
# Example:
```rust
use std::process::{Command, Stdio};
Command::new("cmd")
.async_pipes(true)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
```
| -rw-r--r-- | library/std/src/os/windows/process.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 24b0888b112..a6b75493e6e 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -161,6 +161,37 @@ pub trait CommandExt: Sealed { /// `CommandLineToArgvW` escaping rules. #[stable(feature = "windows_process_extensions_raw_arg", since = "1.62.0")] fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut process::Command; + + /// When [`process::Command`] creates pipes, request that our side is always async. + /// + /// By default [`process::Command`] may choose to use pipes where both ends + /// are opened for synchronous read or write operations. By using + /// `async_pipes(true)`, this behavior is overridden so that our side is + /// always async. + /// + /// This is important because if doing async I/O a pipe or a file has to be + /// opened for async access. + /// + /// The end of the pipe sent to the child process will always be synchronous + /// regardless of this option. + /// + /// # Example + /// + /// ``` + /// #![feature(windows_process_extensions_async_pipes)] + /// use std::os::windows::process::CommandExt; + /// use std::process::{Command, Stdio}; + /// + /// # let program = ""; + /// + /// Command::new(program) + /// .async_pipes(true) + /// .stdin(Stdio::piped()) + /// .stdout(Stdio::piped()) + /// .stderr(Stdio::piped()); + /// ``` + #[unstable(feature = "windows_process_extensions_async_pipes", issue = "98289")] + fn async_pipes(&mut self, always_async: bool) -> &mut process::Command; } #[stable(feature = "windows_process_extensions", since = "1.16.0")] @@ -179,6 +210,15 @@ impl CommandExt for process::Command { self.as_inner_mut().raw_arg(raw_text.as_ref()); self } + + fn async_pipes(&mut self, always_async: bool) -> &mut process::Command { + // FIXME: This currently has an intentional no-op implementation. + // For the time being our side of the pipes will always be async. + // Once the ecosystem has adjusted, we may then be able to start making + // use of synchronous pipes within the standard library. + let _ = always_async; + self + } } #[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")] |
