about summary refs log tree commit diff
path: root/library/std/src/os
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-28 10:55:05 +0000
committerbors <bors@rust-lang.org>2023-08-28 10:55:05 +0000
commit9847c6406dc8182abb417b69000fcd0bc5f4a1b7 (patch)
tree4c2176c7b6001e7a76d7446f0987720c09b2b771 /library/std/src/os
parent1bd043098e05839afb557bd7a2858cb09a4054ca (diff)
parentedefa8b105cd4a35b689e85187689f4fb4085ede (diff)
downloadrust-9847c6406dc8182abb417b69000fcd0bc5f4a1b7.tar.gz
rust-9847c6406dc8182abb417b69000fcd0bc5f4a1b7.zip
Auto merge of #114848 - michaelvanstraten:spawn_with_attributes, r=ChrisDenton
Add ability to spawn Windows process with Proc Thread Attributes | Take 2

This is the second attempt to merge pull request #88193 into the standard library.

This PR implements the ability to add arbitrary attributes to a command on Windows targets using a new `raw_attribute` method on the [`CommandExt`](https://doc.rust-lang.org/stable/std/os/windows/process/trait.CommandExt.html) trait.

`@TyPR124` and my main motivation behind adding this feature is to enable the support of pseudo terminals in the std library, but there are many more applications. A good starting point to get into this topic is to head over to the [`Win32 API documentation`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute).
Diffstat (limited to 'library/std/src/os')
-rw-r--r--library/std/src/os/windows/process.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 073168cf2d2..5d87216ff1b 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -192,6 +192,66 @@ pub trait CommandExt: Sealed {
     /// ```
     #[unstable(feature = "windows_process_extensions_async_pipes", issue = "98289")]
     fn async_pipes(&mut self, always_async: bool) -> &mut process::Command;
+
+    /// 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;
 }
 
 #[stable(feature = "windows_process_extensions", since = "1.16.0")]
@@ -219,6 +279,15 @@ impl CommandExt for process::Command {
         let _ = always_async;
         self
     }
+
+    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
+    }
 }
 
 #[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]