]> git.proxmox.com Git - rustc.git/blame - library/std/src/os/windows/process.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / library / std / src / os / windows / process.rs
CommitLineData
c295e0f8
XL
1//! Windows-specific extensions to primitives in the [`std::process`] module.
2//!
3//! [`std::process`]: crate::process
62682a34
SL
4
5#![stable(feature = "process_extensions", since = "1.2.0")]
6
136023e0 7use crate::ffi::OsStr;
94222f64
XL
8use crate::os::windows::io::{
9 AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
10};
532ac7d7 11use crate::process;
6a06907d 12use crate::sealed::Sealed;
532ac7d7 13use crate::sys;
60c5eb7d 14use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
62682a34
SL
15
16#[stable(feature = "process_extensions", since = "1.2.0")]
17impl FromRawHandle for process::Stdio {
18 unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio {
94222f64
XL
19 let handle = sys::handle::Handle::from_raw_handle(handle as *mut _);
20 let io = sys::process::Stdio::Handle(handle);
21 process::Stdio::from_inner(io)
22 }
23}
24
923072b8 25#[stable(feature = "io_safety", since = "1.63.0")]
94222f64
XL
26impl From<OwnedHandle> for process::Stdio {
27 fn from(handle: OwnedHandle) -> process::Stdio {
28 let handle = sys::handle::Handle::from_inner(handle);
7453a54e
SL
29 let io = sys::process::Stdio::Handle(handle);
30 process::Stdio::from_inner(io)
62682a34
SL
31 }
32}
33
34#[stable(feature = "process_extensions", since = "1.2.0")]
35impl AsRawHandle for process::Child {
cdc7bbd5 36 #[inline]
62682a34 37 fn as_raw_handle(&self) -> RawHandle {
94222f64
XL
38 self.as_inner().handle().as_raw_handle() as *mut _
39 }
40}
41
923072b8 42#[stable(feature = "io_safety", since = "1.63.0")]
94222f64
XL
43impl AsHandle for process::Child {
44 #[inline]
45 fn as_handle(&self) -> BorrowedHandle<'_> {
46 self.as_inner().handle().as_handle()
62682a34
SL
47 }
48}
49
c30ab7b3 50#[stable(feature = "into_raw_os", since = "1.4.0")]
c1a9b12d
SL
51impl IntoRawHandle for process::Child {
52 fn into_raw_handle(self) -> RawHandle {
94222f64
XL
53 self.into_inner().into_handle().into_raw_handle() as *mut _
54 }
55}
56
923072b8 57#[stable(feature = "io_safety", since = "1.63.0")]
94222f64
XL
58impl From<process::Child> for OwnedHandle {
59 fn from(child: process::Child) -> OwnedHandle {
60 child.into_inner().into_handle().into_inner()
c1a9b12d
SL
61 }
62}
63
62682a34
SL
64#[stable(feature = "process_extensions", since = "1.2.0")]
65impl AsRawHandle for process::ChildStdin {
cdc7bbd5 66 #[inline]
62682a34 67 fn as_raw_handle(&self) -> RawHandle {
94222f64 68 self.as_inner().handle().as_raw_handle() as *mut _
62682a34
SL
69 }
70}
71
72#[stable(feature = "process_extensions", since = "1.2.0")]
73impl AsRawHandle for process::ChildStdout {
cdc7bbd5 74 #[inline]
62682a34 75 fn as_raw_handle(&self) -> RawHandle {
94222f64 76 self.as_inner().handle().as_raw_handle() as *mut _
62682a34
SL
77 }
78}
79
80#[stable(feature = "process_extensions", since = "1.2.0")]
81impl AsRawHandle for process::ChildStderr {
cdc7bbd5 82 #[inline]
62682a34 83 fn as_raw_handle(&self) -> RawHandle {
94222f64 84 self.as_inner().handle().as_raw_handle() as *mut _
62682a34
SL
85 }
86}
c1a9b12d 87
c30ab7b3 88#[stable(feature = "into_raw_os", since = "1.4.0")]
c1a9b12d
SL
89impl IntoRawHandle for process::ChildStdin {
90 fn into_raw_handle(self) -> RawHandle {
94222f64 91 self.into_inner().into_handle().into_raw_handle() as *mut _
c1a9b12d
SL
92 }
93}
94
c30ab7b3 95#[stable(feature = "into_raw_os", since = "1.4.0")]
c1a9b12d
SL
96impl IntoRawHandle for process::ChildStdout {
97 fn into_raw_handle(self) -> RawHandle {
94222f64 98 self.into_inner().into_handle().into_raw_handle() as *mut _
c1a9b12d
SL
99 }
100}
101
c30ab7b3 102#[stable(feature = "into_raw_os", since = "1.4.0")]
c1a9b12d
SL
103impl IntoRawHandle for process::ChildStderr {
104 fn into_raw_handle(self) -> RawHandle {
94222f64 105 self.into_inner().into_handle().into_raw_handle() as *mut _
c1a9b12d
SL
106 }
107}
a7813a04 108
83c7162d 109/// Windows-specific extensions to [`process::ExitStatus`].
5869c6ff
XL
110///
111/// This trait is sealed: it cannot be implemented outside the standard library.
112/// This is so that future additional methods are not breaking changes.
5bcae85e 113#[stable(feature = "exit_status_from", since = "1.12.0")]
6a06907d 114pub trait ExitStatusExt: Sealed {
a7813a04
XL
115 /// Creates a new `ExitStatus` from the raw underlying `u32` return value of
116 /// a process.
5bcae85e 117 #[stable(feature = "exit_status_from", since = "1.12.0")]
a7813a04
XL
118 fn from_raw(raw: u32) -> Self;
119}
120
c30ab7b3 121#[stable(feature = "exit_status_from", since = "1.12.0")]
a7813a04
XL
122impl ExitStatusExt for process::ExitStatus {
123 fn from_raw(raw: u32) -> Self {
124 process::ExitStatus::from_inner(From::from(raw))
125 }
126}
476ff2be 127
83c7162d 128/// Windows-specific extensions to the [`process::Command`] builder.
6a06907d
XL
129///
130/// This trait is sealed: it cannot be implemented outside the standard library.
131/// This is so that future additional methods are not breaking changes.
32a655c1 132#[stable(feature = "windows_process_extensions", since = "1.16.0")]
6a06907d 133pub trait CommandExt: Sealed {
476ff2be
SL
134 /// Sets the [process creation flags][1] to be passed to `CreateProcess`.
135 ///
136 /// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
cc61c64b 137 ///
dfeec247 138 /// [1]: https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
32a655c1 139 #[stable(feature = "windows_process_extensions", since = "1.16.0")]
476ff2be 140 fn creation_flags(&mut self, flags: u32) -> &mut process::Command;
6a06907d
XL
141
142 /// Forces all arguments to be wrapped in quote (`"`) characters.
143 ///
144 /// This is useful for passing arguments to [MSYS2/Cygwin][1] based
145 /// executables: these programs will expand unquoted arguments containing
146 /// wildcard characters (`?` and `*`) by searching for any file paths
147 /// matching the wildcard pattern.
148 ///
149 /// Adding quotes has no effect when passing arguments to programs
150 /// that use [msvcrt][2]. This includes programs built with both
151 /// MinGW and MSVC.
152 ///
153 /// [1]: <https://github.com/msys2/MSYS2-packages/issues/2176>
154 /// [2]: <https://msdn.microsoft.com/en-us/library/17w5ykft.aspx>
155 #[unstable(feature = "windows_process_extensions_force_quotes", issue = "82227")]
156 fn force_quotes(&mut self, enabled: bool) -> &mut process::Command;
136023e0
XL
157
158 /// Append literal text to the command line without any quoting or escaping.
159 ///
160 /// This is useful for passing arguments to `cmd.exe /c`, which doesn't follow
161 /// `CommandLineToArgvW` escaping rules.
04454e1e 162 #[stable(feature = "windows_process_extensions_raw_arg", since = "1.62.0")]
136023e0 163 fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut process::Command;
923072b8
FG
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;
476ff2be
SL
195}
196
32a655c1 197#[stable(feature = "windows_process_extensions", since = "1.16.0")]
476ff2be
SL
198impl CommandExt for process::Command {
199 fn creation_flags(&mut self, flags: u32) -> &mut process::Command {
200 self.as_inner_mut().creation_flags(flags);
201 self
202 }
6a06907d
XL
203
204 fn force_quotes(&mut self, enabled: bool) -> &mut process::Command {
205 self.as_inner_mut().force_quotes(enabled);
206 self
207 }
136023e0
XL
208
209 fn raw_arg<S: AsRef<OsStr>>(&mut self, raw_text: S) -> &mut process::Command {
210 self.as_inner_mut().raw_arg(raw_text.as_ref());
211 self
212 }
923072b8
FG
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 }
476ff2be 222}
04454e1e
FG
223
224#[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]
225pub trait ChildExt: Sealed {
226 /// Extracts the main thread raw handle, without taking ownership
227 #[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]
228 fn main_thread_handle(&self) -> BorrowedHandle<'_>;
229}
230
231#[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]
232impl ChildExt for process::Child {
233 fn main_thread_handle(&self) -> BorrowedHandle<'_> {
234 self.handle.main_thread_handle()
235 }
236}