Skip to content

Commit

Permalink
Take generic value type
Browse files Browse the repository at this point in the history
  • Loading branch information
TyPR124 committed Mar 7, 2022
1 parent 0475e2f commit d20fc4e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 29 deletions.
22 changes: 9 additions & 13 deletions library/std/src/os/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#![stable(feature = "process_extensions", since = "1.2.0")]

use crate::ffi::{c_void, OsStr};
use crate::ffi::OsStr;
use crate::os::windows::io::{
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
};
Expand Down Expand Up @@ -166,17 +166,14 @@ pub trait CommandExt: Sealed {
///
/// # Safety
///
/// - The data pointed to by `value` pointer must not be moved or aliased for the entire lifetime of
/// the `Command`.
/// - The data pointed to by `value` pointer must be initialized.
/// - `size` must not exceed the size of the object pointed to by the `value` pointer.
/// - It must be safe to read the data pointed to by `value` from another thread.
/// - The attribute and value pair must be supplied in accordance with [Win32 API usage][1].
///
/// [1]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute
#[unstable(feature = "windows_process_extensions_proc_thread_attributes", issue = "none")]
unsafe fn process_thread_attribute(
unsafe fn process_thread_attribute<T: Copy + Send + Sync + 'static>(
&mut self,
attribute: usize,
value: *mut c_void,
size: usize,
value: T,
) -> &mut process::Command;
}

Expand All @@ -196,13 +193,12 @@ impl CommandExt for process::Command {
self.as_inner_mut().raw_arg(raw_text.as_ref());
self
}
unsafe fn process_thread_attribute(
unsafe fn process_thread_attribute<T: Copy + Send + Sync + 'static>(
&mut self,
attribute: usize,
value: *mut c_void,
size: usize,
value: T,
) -> &mut process::Command {
self.as_inner_mut().process_thread_attribute(attribute, value, size);
self.as_inner_mut().process_thread_attribute(attribute, value);
self
}
}
8 changes: 3 additions & 5 deletions library/std/src/process/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,17 +412,15 @@ fn test_creation_flags() {
fn test_proc_thread_attributes() {
use crate::os::windows::io::AsRawHandle;
use crate::os::windows::process::CommandExt;
use crate::sys::c::{DWORD_PTR, HANDLE};
use crate::sys::c::DWORD_PTR;
const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: DWORD_PTR = 0x00020000;
let mut parent = Command::new("cmd.exe").spawn().unwrap();
let mut parent_handle: HANDLE = parent.as_raw_handle();

let mut parent = Command::new("cmd.exe").spawn().unwrap();
let mut child_cmd = Command::new("cmd.exe");
unsafe {
child_cmd.process_thread_attribute(
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&mut parent_handle as *mut _ as *mut _,
crate::mem::size_of::<HANDLE>(),
parent.as_raw_handle() as isize,
);
}
let mut child = child_cmd.spawn().unwrap();
Expand Down
27 changes: 16 additions & 11 deletions library/std/src/sys/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,15 @@ impl Command {
pub fn get_current_dir(&self) -> Option<&Path> {
self.cwd.as_ref().map(|cwd| Path::new(cwd))
}
pub fn process_thread_attribute(&mut self, attribute: usize, ptr: *mut c_void, size: usize) {
self.proc_thread_attributes.insert(attribute, ProcThreadAttributeValue { ptr, size });
pub unsafe fn process_thread_attribute<T: Copy + Send + Sync + 'static>(
&mut self,
attribute: usize,
value: T,
) {
self.proc_thread_attributes.insert(
attribute,
ProcThreadAttributeValue { size: mem::size_of::<T>(), data: Box::new(value) },
);
}

pub fn spawn(
Expand Down Expand Up @@ -876,16 +883,10 @@ impl Drop for ProcThreadAttributeList {
}
}
/// Wrapper around the value data to be used as a Process Thread Attribute.
/// This exists primarily to force the raw pointer type to be `Send` and `Sync`
/// without needing to `unsafe impl` them for `Command`.
#[derive(Copy, Clone)]
struct ProcThreadAttributeValue {
ptr: *mut c_void,
data: Box<dyn Send + Sync>,
size: usize,
}
unsafe impl Send for ProcThreadAttributeValue {}
unsafe impl Sync for ProcThreadAttributeValue {}

fn make_proc_thread_attributes(
attributes: &BTreeMap<usize, ProcThreadAttributeValue>,
) -> io::Result<ProcThreadAttributeList> {
Expand All @@ -902,13 +903,17 @@ fn make_proc_thread_attributes(
// Add our attributes to the buffer.
// It's theoretically possible for the count to overflow a u32. Therefore, make
// sure we don't add more attributes than we actually initialized the buffer for.
for (&attribute, &value) in attributes.iter().take(count as usize) {
for (&attribute, value) in attributes.iter().take(count as usize) {
let value_ptr: *const (dyn Send + Sync) = &*value.data as *const _;
// let value_ptr = value_ptr as *const _;
let value_ptr = value_ptr as *const c_void;
let value_ptr = value_ptr as *mut c_void;
cvt(unsafe {
c::UpdateProcThreadAttribute(
attribute_list.0.as_mut_ptr().cast(),
0,
attribute,
value.ptr,
value_ptr,
value.size,
ptr::null_mut(),
ptr::null_mut(),
Expand Down

0 comments on commit d20fc4e

Please sign in to comment.