Skip to content

Commit 85f1de2

Browse files
authored
Rollup merge of rust-lang#97149 - ChrisDenton:win_async_pipes, r=m-ou-se
Windows: `CommandExt::async_pipes` Discussed in tokio-rs/tokio#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(); ```
2 parents 625c929 + 740a54c commit 85f1de2

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

library/std/src/os/windows/process.rs

+40
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,37 @@ pub trait CommandExt: Sealed {
161161
/// `CommandLineToArgvW` escaping rules.
162162
#[stable(feature = "windows_process_extensions_raw_arg", since = "1.62.0")]
163163
fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut process::Command;
164+
165+
/// When [`process::Command`] creates pipes, request that our side is always async.
166+
///
167+
/// By default [`process::Command`] may choose to use pipes where both ends
168+
/// are opened for synchronous read or write operations. By using
169+
/// `async_pipes(true)`, this behavior is overridden so that our side is
170+
/// always async.
171+
///
172+
/// This is important because if doing async I/O a pipe or a file has to be
173+
/// opened for async access.
174+
///
175+
/// The end of the pipe sent to the child process will always be synchronous
176+
/// regardless of this option.
177+
///
178+
/// # Example
179+
///
180+
/// ```
181+
/// #![feature(windows_process_extensions_async_pipes)]
182+
/// use std::os::windows::process::CommandExt;
183+
/// use std::process::{Command, Stdio};
184+
///
185+
/// # let program = "";
186+
///
187+
/// Command::new(program)
188+
/// .async_pipes(true)
189+
/// .stdin(Stdio::piped())
190+
/// .stdout(Stdio::piped())
191+
/// .stderr(Stdio::piped());
192+
/// ```
193+
#[unstable(feature = "windows_process_extensions_async_pipes", issue = "98289")]
194+
fn async_pipes(&mut self, always_async: bool) -> &mut process::Command;
164195
}
165196

166197
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
@@ -179,6 +210,15 @@ impl CommandExt for process::Command {
179210
self.as_inner_mut().raw_arg(raw_text.as_ref());
180211
self
181212
}
213+
214+
fn async_pipes(&mut self, always_async: bool) -> &mut process::Command {
215+
// FIXME: This currently has an intentional no-op implementation.
216+
// For the time being our side of the pipes will always be async.
217+
// Once the ecosystem has adjusted, we may then be able to start making
218+
// use of synchronous pipes within the standard library.
219+
let _ = always_async;
220+
self
221+
}
182222
}
183223

184224
#[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]

0 commit comments

Comments
 (0)