2021-09-17 23:23:21 +05:30
//! Windows-specific extensions to primitives in the [`std::process`] module.
//!
//! [`std::process`]: crate::process
2015-05-12 11:03:49 -07:00
2015-06-09 16:41:14 -07:00
#![ stable(feature = " process_extensions " , since = " 1.2.0 " ) ]
2015-05-12 11:03:49 -07:00
2021-05-30 17:01:02 +01:00
use crate ::ffi ::OsStr ;
2021-08-19 12:24:25 -07:00
use crate ::os ::windows ::io ::{
AsHandle , AsRawHandle , BorrowedHandle , FromRawHandle , IntoRawHandle , OwnedHandle , RawHandle ,
} ;
2019-02-11 04:23:21 +09:00
use crate ::process ;
2021-02-10 21:30:30 +00:00
use crate ::sealed ::Sealed ;
2019-02-11 04:23:21 +09:00
use crate ::sys ;
2019-11-27 10:28:39 -08:00
use crate ::sys_common ::{ AsInner , AsInnerMut , FromInner , IntoInner } ;
2015-05-12 11:03:49 -07:00
2015-06-09 16:41:14 -07:00
#[ stable(feature = " process_extensions " , since = " 1.2.0 " ) ]
2015-05-12 11:03:49 -07:00
impl FromRawHandle for process ::Stdio {
unsafe fn from_raw_handle ( handle : RawHandle ) -> process ::Stdio {
2021-06-30 21:44:30 -07:00
let handle = sys ::handle ::Handle ::from_raw_handle ( handle as * mut _ ) ;
2016-02-04 11:10:37 -08:00
let io = sys ::process ::Stdio ::Handle ( handle ) ;
process ::Stdio ::from_inner ( io )
2015-05-12 11:03:49 -07:00
}
}
2022-03-08 15:38:08 -08:00
#[ stable(feature = " io_safety " , since = " 1.63.0 " ) ]
2021-08-17 16:28:00 -07:00
impl From < OwnedHandle > for process ::Stdio {
fn from ( handle : OwnedHandle ) -> process ::Stdio {
2021-08-19 12:24:25 -07:00
let handle = sys ::handle ::Handle ::from_inner ( handle ) ;
2021-08-17 16:28:00 -07:00
let io = sys ::process ::Stdio ::Handle ( handle ) ;
process ::Stdio ::from_inner ( io )
}
}
2015-06-09 16:41:14 -07:00
#[ stable(feature = " process_extensions " , since = " 1.2.0 " ) ]
2015-05-12 11:03:49 -07:00
impl AsRawHandle for process ::Child {
2021-04-25 07:39:09 +01:00
#[ inline ]
2015-05-12 11:03:49 -07:00
fn as_raw_handle ( & self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . as_inner ( ) . handle ( ) . as_raw_handle ( ) as * mut _
2015-05-12 11:03:49 -07:00
}
}
2022-03-08 15:38:08 -08:00
#[ stable(feature = " io_safety " , since = " 1.63.0 " ) ]
2021-08-17 16:28:00 -07:00
impl AsHandle for process ::Child {
#[ inline ]
fn as_handle ( & self ) -> BorrowedHandle < '_ > {
self . as_inner ( ) . handle ( ) . as_handle ( )
}
}
2016-09-28 11:28:42 +01:00
#[ stable(feature = " into_raw_os " , since = " 1.4.0 " ) ]
2015-07-15 23:31:24 -07:00
impl IntoRawHandle for process ::Child {
fn into_raw_handle ( self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . into_inner ( ) . into_handle ( ) . into_raw_handle ( ) as * mut _
2015-07-15 23:31:24 -07:00
}
}
2022-03-08 15:38:08 -08:00
#[ stable(feature = " io_safety " , since = " 1.63.0 " ) ]
2021-08-19 12:24:25 -07:00
impl From < process ::Child > for OwnedHandle {
fn from ( child : process ::Child ) -> OwnedHandle {
child . into_inner ( ) . into_handle ( ) . into_inner ( )
2021-08-17 16:28:00 -07:00
}
}
2015-06-09 16:41:14 -07:00
#[ stable(feature = " process_extensions " , since = " 1.2.0 " ) ]
2015-05-12 11:03:49 -07:00
impl AsRawHandle for process ::ChildStdin {
2021-04-25 07:39:09 +01:00
#[ inline ]
2015-05-12 11:03:49 -07:00
fn as_raw_handle ( & self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . as_inner ( ) . handle ( ) . as_raw_handle ( ) as * mut _
2015-05-12 11:03:49 -07:00
}
}
2015-06-09 16:41:14 -07:00
#[ stable(feature = " process_extensions " , since = " 1.2.0 " ) ]
2015-05-12 11:03:49 -07:00
impl AsRawHandle for process ::ChildStdout {
2021-04-25 07:39:09 +01:00
#[ inline ]
2015-05-12 11:03:49 -07:00
fn as_raw_handle ( & self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . as_inner ( ) . handle ( ) . as_raw_handle ( ) as * mut _
2015-05-12 11:03:49 -07:00
}
}
2015-06-09 16:41:14 -07:00
#[ stable(feature = " process_extensions " , since = " 1.2.0 " ) ]
2015-05-12 11:03:49 -07:00
impl AsRawHandle for process ::ChildStderr {
2021-04-25 07:39:09 +01:00
#[ inline ]
2015-05-12 11:03:49 -07:00
fn as_raw_handle ( & self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . as_inner ( ) . handle ( ) . as_raw_handle ( ) as * mut _
2015-05-12 11:03:49 -07:00
}
}
2015-07-15 23:31:24 -07:00
2016-09-28 11:28:42 +01:00
#[ stable(feature = " into_raw_os " , since = " 1.4.0 " ) ]
2015-07-15 23:31:24 -07:00
impl IntoRawHandle for process ::ChildStdin {
fn into_raw_handle ( self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . into_inner ( ) . into_handle ( ) . into_raw_handle ( ) as * mut _
2015-07-15 23:31:24 -07:00
}
}
2016-09-28 11:28:42 +01:00
#[ stable(feature = " into_raw_os " , since = " 1.4.0 " ) ]
2015-07-15 23:31:24 -07:00
impl IntoRawHandle for process ::ChildStdout {
fn into_raw_handle ( self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . into_inner ( ) . into_handle ( ) . into_raw_handle ( ) as * mut _
2015-07-15 23:31:24 -07:00
}
}
2016-09-28 11:28:42 +01:00
#[ stable(feature = " into_raw_os " , since = " 1.4.0 " ) ]
2015-07-15 23:31:24 -07:00
impl IntoRawHandle for process ::ChildStderr {
fn into_raw_handle ( self ) -> RawHandle {
2021-06-30 21:44:30 -07:00
self . into_inner ( ) . into_handle ( ) . into_raw_handle ( ) as * mut _
2015-07-15 23:31:24 -07:00
}
}
2016-04-26 15:23:46 -07:00
2023-03-09 10:46:38 +01:00
/// Create a `ChildStdin` from the provided `OwnedHandle`.
///
/// The provided handle must be asynchronous, as reading and
/// writing from and to it is implemented using asynchronous APIs.
2023-10-02 19:12:46 -04:00
#[ stable(feature = " child_stream_from_fd " , since = " 1.74.0 " ) ]
2022-07-06 15:29:17 +02:00
impl From < OwnedHandle > for process ::ChildStdin {
fn from ( handle : OwnedHandle ) -> process ::ChildStdin {
let handle = sys ::handle ::Handle ::from_inner ( handle ) ;
let pipe = sys ::pipe ::AnonPipe ::from_inner ( handle ) ;
process ::ChildStdin ::from_inner ( pipe )
}
}
2023-03-09 10:46:38 +01:00
/// Create a `ChildStdout` from the provided `OwnedHandle`.
///
/// The provided handle must be asynchronous, as reading and
/// writing from and to it is implemented using asynchronous APIs.
2023-10-02 19:12:46 -04:00
#[ stable(feature = " child_stream_from_fd " , since = " 1.74.0 " ) ]
2022-07-06 15:29:17 +02:00
impl From < OwnedHandle > for process ::ChildStdout {
fn from ( handle : OwnedHandle ) -> process ::ChildStdout {
let handle = sys ::handle ::Handle ::from_inner ( handle ) ;
let pipe = sys ::pipe ::AnonPipe ::from_inner ( handle ) ;
process ::ChildStdout ::from_inner ( pipe )
}
}
2023-03-09 10:46:38 +01:00
/// Create a `ChildStderr` from the provided `OwnedHandle`.
///
/// The provided handle must be asynchronous, as reading and
/// writing from and to it is implemented using asynchronous APIs.
2023-10-02 19:12:46 -04:00
#[ stable(feature = " child_stream_from_fd " , since = " 1.74.0 " ) ]
2022-07-06 15:29:17 +02:00
impl From < OwnedHandle > for process ::ChildStderr {
fn from ( handle : OwnedHandle ) -> process ::ChildStderr {
let handle = sys ::handle ::Handle ::from_inner ( handle ) ;
let pipe = sys ::pipe ::AnonPipe ::from_inner ( handle ) ;
process ::ChildStderr ::from_inner ( pipe )
}
}
2018-04-09 17:44:28 -07:00
/// Windows-specific extensions to [`process::ExitStatus`].
2021-01-04 17:45:23 +00:00
///
2021-01-10 18:11:00 -08:00
/// This trait is sealed: it cannot be implemented outside the standard library.
2021-01-04 17:45:23 +00:00
/// This is so that future additional methods are not breaking changes.
2016-08-11 14:08:24 -07:00
#[ stable(feature = " exit_status_from " , since = " 1.12.0 " ) ]
2021-02-10 21:30:30 +00:00
pub trait ExitStatusExt : Sealed {
2016-04-26 15:23:46 -07:00
/// Creates a new `ExitStatus` from the raw underlying `u32` return value of
/// a process.
2016-08-11 14:08:24 -07:00
#[ stable(feature = " exit_status_from " , since = " 1.12.0 " ) ]
2016-04-26 15:23:46 -07:00
fn from_raw ( raw : u32 ) -> Self ;
}
2016-09-28 11:28:42 +01:00
#[ stable(feature = " exit_status_from " , since = " 1.12.0 " ) ]
2016-04-26 15:23:46 -07:00
impl ExitStatusExt for process ::ExitStatus {
fn from_raw ( raw : u32 ) -> Self {
process ::ExitStatus ::from_inner ( From ::from ( raw ) )
}
}
2016-11-30 19:44:07 -05:00
2018-04-09 17:44:28 -07:00
/// Windows-specific extensions to the [`process::Command`] builder.
2021-02-10 21:30:30 +00:00
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
2017-01-25 15:37:20 -08:00
#[ stable(feature = " windows_process_extensions " , since = " 1.16.0 " ) ]
2021-02-10 21:30:30 +00:00
pub trait CommandExt : Sealed {
2016-11-30 19:44:07 -05:00
/// Sets the [process creation flags][1] to be passed to `CreateProcess`.
///
/// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
2017-04-06 12:57:40 +01:00
///
2019-12-25 15:35:54 +00:00
/// [1]: https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
2017-01-25 15:37:20 -08:00
#[ stable(feature = " windows_process_extensions " , since = " 1.16.0 " ) ]
2016-11-30 21:31:47 -05:00
fn creation_flags ( & mut self , flags : u32 ) -> & mut process ::Command ;
2020-10-08 22:26:31 +00:00
/// Forces all arguments to be wrapped in quote (`"`) characters.
///
/// This is useful for passing arguments to [MSYS2/Cygwin][1] based
/// executables: these programs will expand unquoted arguments containing
/// wildcard characters (`?` and `*`) by searching for any file paths
/// matching the wildcard pattern.
///
/// Adding quotes has no effect when passing arguments to programs
/// that use [msvcrt][2]. This includes programs built with both
/// MinGW and MSVC.
///
/// [1]: <https://github.com/msys2/MSYS2-packages/issues/2176>
/// [2]: <https://msdn.microsoft.com/en-us/library/17w5ykft.aspx>
#[ unstable(feature = " windows_process_extensions_force_quotes " , issue = " 82227 " ) ]
fn force_quotes ( & mut self , enabled : bool ) -> & mut process ::Command ;
2021-05-30 17:01:02 +01:00
/// Append literal text to the command line without any quoting or escaping.
///
/// This is useful for passing arguments to `cmd.exe /c`, which doesn't follow
/// `CommandLineToArgvW` escaping rules.
2022-04-04 10:15:28 -07:00
#[ stable(feature = " windows_process_extensions_raw_arg " , since = " 1.62.0 " ) ]
2021-07-05 00:05:46 +01:00
fn raw_arg < S : AsRef < OsStr > > ( & mut self , text_to_append_as_is : S ) -> & mut process ::Command ;
2022-05-18 19:52:10 +01:00
/// 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 ;
2023-08-25 16:19:16 +02:00
/// Sets a raw attribute on the command, providing extended configuration options for Windows processes.
///
/// This method allows you to specify custom attributes for a child process on Windows systems using raw attribute values.
/// Raw attributes provide extended configurability for process creation, but their usage can be complex and potentially unsafe.
///
/// The `attribute` parameter specifies the raw attribute to be set, while the `value` parameter holds the value associated with that attribute.
/// Please refer to the [`windows-rs`](https://microsoft.github.io/windows-docs-rs/doc/windows/) documentation or the [`Win32 API documentation`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute) for detailed information about available attributes and their meanings.
///
/// # Note
///
/// The maximum number of raw attributes is the value of [`u32::MAX`].
/// If this limit is exceeded, the call to [`process::Command::spawn`] will return an `Error` indicating that the maximum number of attributes has been exceeded.
/// # Safety
///
/// The usage of raw attributes is potentially unsafe and should be done with caution. Incorrect attribute values or improper configuration can lead to unexpected behavior or errors.
///
/// # Example
///
/// The following example demonstrates how to create a child process with a specific parent process ID using a raw attribute.
///
/// ```rust
/// #![feature(windows_process_extensions_raw_attribute)]
/// use std::os::windows::{process::CommandExt, io::AsRawHandle};
/// use std::process::Command;
///
/// # struct ProcessDropGuard(std::process::Child);
/// # impl Drop for ProcessDropGuard {
/// # fn drop(&mut self) {
/// # let _ = self.0.kill();
/// # }
/// # }
///
/// let parent = Command::new("cmd").spawn()?;
///
/// let mut child_cmd = Command::new("cmd");
///
/// const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: usize = 0x00020000;
///
/// unsafe {
/// child_cmd.raw_attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, parent.as_raw_handle() as isize);
/// }
/// #
/// # let parent = ProcessDropGuard(parent);
///
/// let mut child = child_cmd.spawn()?;
///
/// # child.kill()?;
/// # Ok::<(), std::io::Error>(())
/// ```
///
/// # Safety Note
///
/// Remember that improper use of raw attributes can lead to undefined behavior or security vulnerabilities. Always consult the documentation and ensure proper attribute values are used.
#[ unstable(feature = " windows_process_extensions_raw_attribute " , issue = " 114854 " ) ]
unsafe fn raw_attribute < T : Copy + Send + Sync + 'static > (
& mut self ,
attribute : usize ,
value : T ,
) -> & mut process ::Command ;
2016-11-30 19:44:07 -05:00
}
2017-01-25 15:37:20 -08:00
#[ stable(feature = " windows_process_extensions " , since = " 1.16.0 " ) ]
2016-11-30 19:44:07 -05:00
impl CommandExt for process ::Command {
2016-11-30 21:31:47 -05:00
fn creation_flags ( & mut self , flags : u32 ) -> & mut process ::Command {
self . as_inner_mut ( ) . creation_flags ( flags ) ;
2016-11-30 19:44:07 -05:00
self
}
2020-10-08 22:26:31 +00:00
fn force_quotes ( & mut self , enabled : bool ) -> & mut process ::Command {
self . as_inner_mut ( ) . force_quotes ( enabled ) ;
self
}
2021-05-30 17:01:02 +01:00
2021-07-05 00:05:46 +01:00
fn raw_arg < S : AsRef < OsStr > > ( & mut self , raw_text : S ) -> & mut process ::Command {
self . as_inner_mut ( ) . raw_arg ( raw_text . as_ref ( ) ) ;
2021-05-30 17:01:02 +01:00
self
}
2022-05-18 19:52:10 +01:00
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
}
2023-08-25 16:19:16 +02:00
unsafe fn raw_attribute < T : Copy + Send + Sync + 'static > (
& mut self ,
attribute : usize ,
value : T ,
) -> & mut process ::Command {
self . as_inner_mut ( ) . raw_attribute ( attribute , value ) ;
self
}
2016-11-30 19:44:07 -05:00
}
2022-05-10 02:41:19 -03:00
#[ unstable(feature = " windows_process_extensions_main_thread_handle " , issue = " 96723 " ) ]
pub trait ChildExt : Sealed {
/// Extracts the main thread raw handle, without taking ownership
#[ unstable(feature = " windows_process_extensions_main_thread_handle " , issue = " 96723 " ) ]
fn main_thread_handle ( & self ) -> BorrowedHandle < '_ > ;
}
#[ unstable(feature = " windows_process_extensions_main_thread_handle " , issue = " 96723 " ) ]
impl ChildExt for process ::Child {
fn main_thread_handle ( & self ) -> BorrowedHandle < '_ > {
self . handle . main_thread_handle ( )
}
}
2022-06-09 15:29:58 +02:00
/// Windows-specific extensions to [`process::ExitCode`].
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
2023-11-23 11:16:10 -08:00
#[ unstable(feature = " windows_process_exit_code_from " , issue = " 111688 " ) ]
2022-06-09 15:29:58 +02:00
pub trait ExitCodeExt : Sealed {
2022-06-10 14:21:49 +02:00
/// Creates a new `ExitCode` from the raw underlying `u32` return value of
2022-06-09 15:29:58 +02:00
/// a process.
2022-06-10 14:33:19 +02:00
///
/// The exit code should not be 259, as this conflicts with the `STILL_ACTIVE`
/// macro returned from the `GetExitCodeProcess` function to signal that the
/// process has yet to run to completion.
2023-11-23 11:16:10 -08:00
#[ unstable(feature = " windows_process_exit_code_from " , issue = " 111688 " ) ]
2022-06-09 15:29:58 +02:00
fn from_raw ( raw : u32 ) -> Self ;
}
2023-11-23 11:16:10 -08:00
#[ unstable(feature = " windows_process_exit_code_from " , issue = " 111688 " ) ]
2022-06-09 15:29:58 +02:00
impl ExitCodeExt for process ::ExitCode {
fn from_raw ( raw : u32 ) -> Self {
process ::ExitCode ::from_inner ( From ::from ( raw ) )
}
}