summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys/windows
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /library/std/src/sys/windows
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/std/src/sys/windows')
-rw-r--r--library/std/src/sys/windows/args.rs4
-rw-r--r--library/std/src/sys/windows/c.rs6
-rw-r--r--library/std/src/sys/windows/c/windows_sys.lst21
-rw-r--r--library/std/src/sys/windows/c/windows_sys.rs201
-rw-r--r--library/std/src/sys/windows/handle.rs9
-rw-r--r--library/std/src/sys/windows/mod.rs5
-rw-r--r--library/std/src/sys/windows/net.rs38
-rw-r--r--library/std/src/sys/windows/os_str.rs8
-rw-r--r--library/std/src/sys/windows/path.rs28
-rw-r--r--library/std/src/sys/windows/pipe.rs8
-rw-r--r--library/std/src/sys/windows/process.rs151
11 files changed, 323 insertions, 156 deletions
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index 6b597f499..ee7dba6e5 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -226,7 +226,7 @@ pub(crate) fn append_arg(cmd: &mut Vec<u16>, arg: &Arg, force_quotes: bool) -> i
// that it actually gets passed through on the command line or otherwise
// it will be dropped entirely when parsed on the other end.
ensure_no_nuls(arg)?;
- let arg_bytes = arg.as_os_str_bytes();
+ let arg_bytes = arg.as_encoded_bytes();
let (quote, escape) = match quote {
Quote::Always => (true, true),
Quote::Auto => {
@@ -298,7 +298,7 @@ pub(crate) fn make_bat_command_line(
const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
let force_quotes = match arg {
Arg::Regular(arg) if !force_quotes => {
- arg.as_os_str_bytes().iter().any(|c| SPECIAL.contains(c))
+ arg.as_encoded_bytes().iter().any(|c| SPECIAL.contains(c))
}
_ => force_quotes,
};
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index d9ccba0e9..f3637cbb9 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -46,10 +46,6 @@ pub use FD_SET as fd_set;
pub use LINGER as linger;
pub use TIMEVAL as timeval;
-pub type CONDITION_VARIABLE = RTL_CONDITION_VARIABLE;
-pub type SRWLOCK = RTL_SRWLOCK;
-pub type INIT_ONCE = RTL_RUN_ONCE;
-
pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() };
pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() };
pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() };
@@ -224,7 +220,7 @@ pub unsafe extern "system" fn ReadFileEx(
) -> BOOL {
windows_sys::ReadFileEx(
hFile.as_raw_handle(),
- lpBuffer,
+ lpBuffer.cast::<u8>(),
nNumberOfBytesToRead,
lpOverlapped,
lpCompletionRoutine,
diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst
index 631aedd26..0aca37e2d 100644
--- a/library/std/src/sys/windows/c/windows_sys.lst
+++ b/library/std/src/sys/windows/c/windows_sys.lst
@@ -1,3 +1,6 @@
+--out windows_sys.rs
+--config flatten std
+--filter
// tidy-alphabetical-start
Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION
@@ -2108,7 +2111,6 @@ Windows.Win32.Networking.WinSock.WSABASEERR
Windows.Win32.Networking.WinSock.WSABUF
Windows.Win32.Networking.WinSock.WSACleanup
Windows.Win32.Networking.WinSock.WSADATA
-Windows.Win32.Networking.WinSock.WSADATA
Windows.Win32.Networking.WinSock.WSADuplicateSocketW
Windows.Win32.Networking.WinSock.WSAEACCES
Windows.Win32.Networking.WinSock.WSAEADDRINUSE
@@ -2328,7 +2330,6 @@ Windows.Win32.Storage.FileSystem.FileStandardInfo
Windows.Win32.Storage.FileSystem.FileStorageInfo
Windows.Win32.Storage.FileSystem.FileStreamInfo
Windows.Win32.Storage.FileSystem.FindClose
-Windows.Win32.Storage.FileSystem.FindFileHandle
Windows.Win32.Storage.FileSystem.FindFirstFileW
Windows.Win32.Storage.FileSystem.FindNextFileW
Windows.Win32.Storage.FileSystem.FlushFileBuffers
@@ -2420,8 +2421,6 @@ Windows.Win32.System.Console.STD_OUTPUT_HANDLE
Windows.Win32.System.Console.WriteConsoleW
Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128
Windows.Win32.System.Diagnostics.Debug.CONTEXT
-Windows.Win32.System.Diagnostics.Debug.CONTEXT
-Windows.Win32.System.Diagnostics.Debug.CONTEXT
Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD
Windows.Win32.System.Diagnostics.Debug.FACILITY_CODE
Windows.Win32.System.Diagnostics.Debug.FACILITY_NT_BIT
@@ -2435,7 +2434,6 @@ Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_OPTIONS
Windows.Win32.System.Diagnostics.Debug.FormatMessageW
Windows.Win32.System.Diagnostics.Debug.M128A
Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT
-Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT
Windows.Win32.System.Environment.FreeEnvironmentStringsW
Windows.Win32.System.Environment.GetCommandLineW
Windows.Win32.System.Environment.GetCurrentDirectoryW
@@ -2456,7 +2454,6 @@ Windows.Win32.System.Kernel.ExceptionContinueExecution
Windows.Win32.System.Kernel.ExceptionContinueSearch
Windows.Win32.System.Kernel.ExceptionNestedException
Windows.Win32.System.Kernel.FLOATING_SAVE_AREA
-Windows.Win32.System.Kernel.FLOATING_SAVE_AREA
Windows.Win32.System.Kernel.OBJ_DONT_REPARSE
Windows.Win32.System.LibraryLoader.GetModuleFileNameW
Windows.Win32.System.LibraryLoader.GetModuleHandleA
@@ -2482,6 +2479,7 @@ Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime
Windows.Win32.System.SystemInformation.GetWindowsDirectoryW
Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE
Windows.Win32.System.SystemInformation.SYSTEM_INFO
+Windows.Win32.System.SystemServices.ALL_PROCESSOR_GROUPS
Windows.Win32.System.SystemServices.DLL_PROCESS_DETACH
Windows.Win32.System.SystemServices.DLL_THREAD_DETACH
Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS
@@ -2510,9 +2508,11 @@ Windows.Win32.System.Threading.CreateProcessW
Windows.Win32.System.Threading.CreateThread
Windows.Win32.System.Threading.DEBUG_ONLY_THIS_PROCESS
Windows.Win32.System.Threading.DEBUG_PROCESS
+Windows.Win32.System.Threading.DeleteProcThreadAttributeList
Windows.Win32.System.Threading.DETACHED_PROCESS
Windows.Win32.System.Threading.ExitProcess
Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT
+Windows.Win32.System.Threading.GetActiveProcessorCount
Windows.Win32.System.Threading.GetCurrentProcess
Windows.Win32.System.Threading.GetCurrentProcessId
Windows.Win32.System.Threading.GetCurrentThread
@@ -2524,8 +2524,10 @@ Windows.Win32.System.Threading.INFINITE
Windows.Win32.System.Threading.INHERIT_CALLER_PRIORITY
Windows.Win32.System.Threading.INHERIT_PARENT_AFFINITY
Windows.Win32.System.Threading.INIT_ONCE_INIT_FAILED
+Windows.Win32.System.Threading.InitializeProcThreadAttributeList
Windows.Win32.System.Threading.InitOnceBeginInitialize
Windows.Win32.System.Threading.InitOnceComplete
+Windows.Win32.System.Threading.LPPROC_THREAD_ATTRIBUTE_LIST
Windows.Win32.System.Threading.LPTHREAD_START_ROUTINE
Windows.Win32.System.Threading.NORMAL_PRIORITY_CLASS
Windows.Win32.System.Threading.OpenProcessToken
@@ -2539,9 +2541,6 @@ Windows.Win32.System.Threading.PROFILE_USER
Windows.Win32.System.Threading.REALTIME_PRIORITY_CLASS
Windows.Win32.System.Threading.ReleaseSRWLockExclusive
Windows.Win32.System.Threading.ReleaseSRWLockShared
-Windows.Win32.System.Threading.RTL_CONDITION_VARIABLE
-Windows.Win32.System.Threading.RTL_RUN_ONCE
-Windows.Win32.System.Threading.RTL_SRWLOCK
Windows.Win32.System.Threading.SetThreadStackGuarantee
Windows.Win32.System.Threading.Sleep
Windows.Win32.System.Threading.SleepConditionVariableSRW
@@ -2561,6 +2560,7 @@ Windows.Win32.System.Threading.STARTF_USEPOSITION
Windows.Win32.System.Threading.STARTF_USESHOWWINDOW
Windows.Win32.System.Threading.STARTF_USESIZE
Windows.Win32.System.Threading.STARTF_USESTDHANDLES
+Windows.Win32.System.Threading.STARTUPINFOEXW
Windows.Win32.System.Threading.STARTUPINFOW
Windows.Win32.System.Threading.STARTUPINFOW_FLAGS
Windows.Win32.System.Threading.SwitchToThread
@@ -2575,12 +2575,11 @@ Windows.Win32.System.Threading.TlsGetValue
Windows.Win32.System.Threading.TlsSetValue
Windows.Win32.System.Threading.TryAcquireSRWLockExclusive
Windows.Win32.System.Threading.TryAcquireSRWLockShared
+Windows.Win32.System.Threading.UpdateProcThreadAttribute
Windows.Win32.System.Threading.WaitForMultipleObjects
Windows.Win32.System.Threading.WaitForSingleObject
Windows.Win32.System.Threading.WakeAllConditionVariable
Windows.Win32.System.Threading.WakeConditionVariable
-Windows.Win32.System.WindowsProgramming.IO_STATUS_BLOCK
-Windows.Win32.System.WindowsProgramming.OBJECT_ATTRIBUTES
Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE
Windows.Win32.UI.Shell.GetUserProfileDirectoryW
// tidy-alphabetical-end
diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs
index 023770871..851d15915 100644
--- a/library/std/src/sys/windows/c/windows_sys.rs
+++ b/library/std/src/sys/windows/c/windows_sys.rs
@@ -4,7 +4,7 @@
// regenerate the bindings.
//
// ignore-tidy-filelength
-// Bindings generated by `windows-bindgen` 0.49.0
+// Bindings generated by `windows-bindgen` 0.51.1
#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
#[link(name = "advapi32")]
@@ -32,11 +32,11 @@ extern "system" {
}
#[link(name = "kernel32")]
extern "system" {
- pub fn AcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
+ pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> ();
}
#[link(name = "kernel32")]
extern "system" {
- pub fn AcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
+ pub fn AcquireSRWLockShared(srwlock: *mut SRWLOCK) -> ();
}
#[link(name = "kernel32")]
extern "system" {
@@ -156,6 +156,10 @@ extern "system" {
}
#[link(name = "kernel32")]
extern "system" {
+ pub fn DeleteProcThreadAttributeList(lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
pub fn DeviceIoControl(
hdevice: HANDLE,
dwiocontrolcode: u32,
@@ -185,18 +189,15 @@ extern "system" {
}
#[link(name = "kernel32")]
extern "system" {
- pub fn FindClose(hfindfile: FindFileHandle) -> BOOL;
+ pub fn FindClose(hfindfile: HANDLE) -> BOOL;
}
#[link(name = "kernel32")]
extern "system" {
- pub fn FindFirstFileW(
- lpfilename: PCWSTR,
- lpfindfiledata: *mut WIN32_FIND_DATAW,
- ) -> FindFileHandle;
+ pub fn FindFirstFileW(lpfilename: PCWSTR, lpfindfiledata: *mut WIN32_FIND_DATAW) -> HANDLE;
}
#[link(name = "kernel32")]
extern "system" {
- pub fn FindNextFileW(hfindfile: FindFileHandle, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL;
+ pub fn FindNextFileW(hfindfile: HANDLE, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL;
}
#[link(name = "kernel32")]
extern "system" {
@@ -220,6 +221,10 @@ extern "system" {
}
#[link(name = "kernel32")]
extern "system" {
+ pub fn GetActiveProcessorCount(groupnumber: u16) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
pub fn GetCommandLineW() -> PCWSTR;
}
#[link(name = "kernel32")]
@@ -356,7 +361,7 @@ extern "system" {
#[link(name = "kernel32")]
extern "system" {
pub fn InitOnceBeginInitialize(
- lpinitonce: *mut RTL_RUN_ONCE,
+ lpinitonce: *mut INIT_ONCE,
dwflags: u32,
fpending: *mut BOOL,
lpcontext: *mut *mut ::core::ffi::c_void,
@@ -365,13 +370,22 @@ extern "system" {
#[link(name = "kernel32")]
extern "system" {
pub fn InitOnceComplete(
- lpinitonce: *mut RTL_RUN_ONCE,
+ lpinitonce: *mut INIT_ONCE,
dwflags: u32,
lpcontext: *const ::core::ffi::c_void,
) -> BOOL;
}
#[link(name = "kernel32")]
extern "system" {
+ pub fn InitializeProcThreadAttributeList(
+ lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
+ dwattributecount: u32,
+ dwflags: u32,
+ lpsize: *mut usize,
+ ) -> BOOL;
+}
+#[link(name = "kernel32")]
+extern "system" {
pub fn MoveFileExW(
lpexistingfilename: PCWSTR,
lpnewfilename: PCWSTR,
@@ -411,7 +425,7 @@ extern "system" {
extern "system" {
pub fn ReadFile(
hfile: HANDLE,
- lpbuffer: *mut ::core::ffi::c_void,
+ lpbuffer: *mut u8,
nnumberofbytestoread: u32,
lpnumberofbytesread: *mut u32,
lpoverlapped: *mut OVERLAPPED,
@@ -421,7 +435,7 @@ extern "system" {
extern "system" {
pub fn ReadFileEx(
hfile: HANDLE,
- lpbuffer: *mut ::core::ffi::c_void,
+ lpbuffer: *mut u8,
nnumberofbytestoread: u32,
lpoverlapped: *mut OVERLAPPED,
lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
@@ -429,11 +443,11 @@ extern "system" {
}
#[link(name = "kernel32")]
extern "system" {
- pub fn ReleaseSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
+ pub fn ReleaseSRWLockExclusive(srwlock: *mut SRWLOCK) -> ();
}
#[link(name = "kernel32")]
extern "system" {
- pub fn ReleaseSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
+ pub fn ReleaseSRWLockShared(srwlock: *mut SRWLOCK) -> ();
}
#[link(name = "kernel32")]
extern "system" {
@@ -500,8 +514,8 @@ extern "system" {
#[link(name = "kernel32")]
extern "system" {
pub fn SleepConditionVariableSRW(
- conditionvariable: *mut RTL_CONDITION_VARIABLE,
- srwlock: *mut RTL_SRWLOCK,
+ conditionvariable: *mut CONDITION_VARIABLE,
+ srwlock: *mut SRWLOCK,
dwmilliseconds: u32,
flags: u32,
) -> BOOL;
@@ -536,11 +550,23 @@ extern "system" {
}
#[link(name = "kernel32")]
extern "system" {
- pub fn TryAcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
+ pub fn TryAcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> BOOLEAN;
+}
+#[link(name = "kernel32")]
+extern "system" {
+ pub fn TryAcquireSRWLockShared(srwlock: *mut SRWLOCK) -> BOOLEAN;
}
#[link(name = "kernel32")]
extern "system" {
- pub fn TryAcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
+ pub fn UpdateProcThreadAttribute(
+ lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
+ dwflags: u32,
+ attribute: usize,
+ lpvalue: *const ::core::ffi::c_void,
+ cbsize: usize,
+ lppreviousvalue: *mut ::core::ffi::c_void,
+ lpreturnsize: *const usize,
+ ) -> BOOL;
}
#[link(name = "kernel32")]
extern "system" {
@@ -549,19 +575,19 @@ extern "system" {
lphandles: *const HANDLE,
bwaitall: BOOL,
dwmilliseconds: u32,
- ) -> WIN32_ERROR;
+ ) -> WAIT_EVENT;
}
#[link(name = "kernel32")]
extern "system" {
- pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR;
+ pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WAIT_EVENT;
}
#[link(name = "kernel32")]
extern "system" {
- pub fn WakeAllConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
+ pub fn WakeAllConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> ();
}
#[link(name = "kernel32")]
extern "system" {
- pub fn WakeConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
+ pub fn WakeConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> ();
}
#[link(name = "kernel32")]
extern "system" {
@@ -822,6 +848,7 @@ impl ::core::clone::Clone for ADDRINFOA {
pub const AF_INET: ADDRESS_FAMILY = 2u16;
pub const AF_INET6: ADDRESS_FAMILY = 23u16;
pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16;
+pub const ALL_PROCESSOR_GROUPS: u32 = 65535u32;
#[repr(C)]
pub union ARM64_NT_NEON128 {
pub Anonymous: ARM64_NT_NEON128_0,
@@ -874,7 +901,17 @@ impl ::core::clone::Clone for BY_HANDLE_FILE_INFORMATION {
}
pub const CALLBACK_CHUNK_FINISHED: LPPROGRESS_ROUTINE_CALLBACK_REASON = 0u32;
pub const CALLBACK_STREAM_SWITCH: LPPROGRESS_ROUTINE_CALLBACK_REASON = 1u32;
-pub type COMPARESTRING_RESULT = u32;
+pub type COMPARESTRING_RESULT = i32;
+#[repr(C)]
+pub struct CONDITION_VARIABLE {
+ pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for CONDITION_VARIABLE {}
+impl ::core::clone::Clone for CONDITION_VARIABLE {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
pub type CONSOLE_MODE = u32;
#[repr(C)]
pub struct CONSOLE_READCONSOLE_CONTROL {
@@ -892,7 +929,7 @@ impl ::core::clone::Clone for CONSOLE_READCONSOLE_CONTROL {
#[repr(C)]
#[cfg(target_arch = "aarch64")]
pub struct CONTEXT {
- pub ContextFlags: u32,
+ pub ContextFlags: CONTEXT_FLAGS,
pub Cpsr: u32,
pub Anonymous: CONTEXT_0,
pub Sp: u64,
@@ -979,7 +1016,7 @@ pub struct CONTEXT {
pub P4Home: u64,
pub P5Home: u64,
pub P6Home: u64,
- pub ContextFlags: u32,
+ pub ContextFlags: CONTEXT_FLAGS,
pub MxCsr: u32,
pub SegCs: u16,
pub SegDs: u16,
@@ -1075,7 +1112,7 @@ impl ::core::clone::Clone for CONTEXT_0_0 {
#[repr(C)]
#[cfg(target_arch = "x86")]
pub struct CONTEXT {
- pub ContextFlags: u32,
+ pub ContextFlags: CONTEXT_FLAGS,
pub Dr0: u32,
pub Dr1: u32,
pub Dr2: u32,
@@ -1109,6 +1146,7 @@ impl ::core::clone::Clone for CONTEXT {
*self
}
}
+pub type CONTEXT_FLAGS = u32;
pub const CP_UTF8: u32 = 65001u32;
pub const CREATE_ALWAYS: FILE_CREATION_DISPOSITION = 2u32;
pub const CREATE_BREAKAWAY_FROM_JOB: PROCESS_CREATION_FLAGS = 16777216u32;
@@ -1126,9 +1164,9 @@ pub const CREATE_SEPARATE_WOW_VDM: PROCESS_CREATION_FLAGS = 2048u32;
pub const CREATE_SHARED_WOW_VDM: PROCESS_CREATION_FLAGS = 4096u32;
pub const CREATE_SUSPENDED: PROCESS_CREATION_FLAGS = 4u32;
pub const CREATE_UNICODE_ENVIRONMENT: PROCESS_CREATION_FLAGS = 1024u32;
-pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2u32;
-pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3u32;
-pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1u32;
+pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2i32;
+pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3i32;
+pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1i32;
pub const DEBUG_ONLY_THIS_PROCESS: PROCESS_CREATION_FLAGS = 2u32;
pub const DEBUG_PROCESS: PROCESS_CREATION_FLAGS = 1u32;
pub const DELETE: FILE_ACCESS_RIGHTS = 65536u32;
@@ -3344,7 +3382,6 @@ pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32;
pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32;
pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32;
pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32;
-pub type FindFileHandle = *mut ::core::ffi::c_void;
pub type GENERIC_ACCESS_RIGHTS = u32;
pub const GENERIC_ALL: GENERIC_ACCESS_RIGHTS = 268435456u32;
pub const GENERIC_EXECUTE: GENERIC_ACCESS_RIGHTS = 536870912u32;
@@ -3358,6 +3395,12 @@ pub struct GUID {
pub data3: u16,
pub data4: [u8; 8],
}
+impl ::core::marker::Copy for GUID {}
+impl ::core::clone::Clone for GUID {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
impl GUID {
pub const fn from_u128(uuid: u128) -> Self {
Self {
@@ -3368,12 +3411,6 @@ impl GUID {
}
}
}
-impl ::core::marker::Copy for GUID {}
-impl ::core::clone::Clone for GUID {
- fn clone(&self) -> Self {
- *self
- }
-}
pub type HANDLE = *mut ::core::ffi::c_void;
pub type HANDLE_FLAGS = u32;
pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32;
@@ -3406,6 +3443,16 @@ impl ::core::clone::Clone for IN6_ADDR_0 {
pub const INFINITE: u32 = 4294967295u32;
pub const INHERIT_CALLER_PRIORITY: PROCESS_CREATION_FLAGS = 131072u32;
pub const INHERIT_PARENT_AFFINITY: PROCESS_CREATION_FLAGS = 65536u32;
+#[repr(C)]
+pub union INIT_ONCE {
+ pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for INIT_ONCE {}
+impl ::core::clone::Clone for INIT_ONCE {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
pub const INIT_ONCE_INIT_FAILED: u32 = 4u32;
pub const INVALID_FILE_ATTRIBUTES: u32 = 4294967295u32;
pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::invalid_mut(-1i32 as _);
@@ -3567,6 +3614,7 @@ pub type LPOVERLAPPED_COMPLETION_ROUTINE = ::core::option::Option<
lpoverlapped: *mut OVERLAPPED,
) -> (),
>;
+pub type LPPROC_THREAD_ATTRIBUTE_LIST = *mut ::core::ffi::c_void;
pub type LPPROGRESS_ROUTINE = ::core::option::Option<
unsafe extern "system" fn(
totalfilesize: i64,
@@ -3633,10 +3681,10 @@ pub type NTSTATUS = i32;
pub struct OBJECT_ATTRIBUTES {
pub Length: u32,
pub RootDirectory: HANDLE,
- pub ObjectName: *mut UNICODE_STRING,
+ pub ObjectName: *const UNICODE_STRING,
pub Attributes: u32,
- pub SecurityDescriptor: *mut ::core::ffi::c_void,
- pub SecurityQualityOfService: *mut ::core::ffi::c_void,
+ pub SecurityDescriptor: *const ::core::ffi::c_void,
+ pub SecurityQualityOfService: *const ::core::ffi::c_void,
}
impl ::core::marker::Copy for OBJECT_ATTRIBUTES {}
impl ::core::clone::Clone for OBJECT_ATTRIBUTES {
@@ -3686,8 +3734,8 @@ pub type PCSTR = *const u8;
pub type PCWSTR = *const u16;
pub type PIO_APC_ROUTINE = ::core::option::Option<
unsafe extern "system" fn(
- apccontext: *const ::core::ffi::c_void,
- iostatusblock: *const IO_STATUS_BLOCK,
+ apccontext: *mut ::core::ffi::c_void,
+ iostatusblock: *mut IO_STATUS_BLOCK,
reserved: u32,
) -> (),
>;
@@ -3729,36 +3777,6 @@ pub type PSTR = *mut u8;
pub type PWSTR = *mut u16;
pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32;
pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32;
-#[repr(C)]
-pub struct RTL_CONDITION_VARIABLE {
- pub Ptr: *mut ::core::ffi::c_void,
-}
-impl ::core::marker::Copy for RTL_CONDITION_VARIABLE {}
-impl ::core::clone::Clone for RTL_CONDITION_VARIABLE {
- fn clone(&self) -> Self {
- *self
- }
-}
-#[repr(C)]
-pub union RTL_RUN_ONCE {
- pub Ptr: *mut ::core::ffi::c_void,
-}
-impl ::core::marker::Copy for RTL_RUN_ONCE {}
-impl ::core::clone::Clone for RTL_RUN_ONCE {
- fn clone(&self) -> Self {
- *self
- }
-}
-#[repr(C)]
-pub struct RTL_SRWLOCK {
- pub Ptr: *mut ::core::ffi::c_void,
-}
-impl ::core::marker::Copy for RTL_SRWLOCK {}
-impl ::core::clone::Clone for RTL_SRWLOCK {
- fn clone(&self) -> Self {
- *self
- }
-}
pub const SD_BOTH: WINSOCK_SHUTDOWN_HOW = 2i32;
pub const SD_RECEIVE: WINSOCK_SHUTDOWN_HOW = 0i32;
pub const SD_SEND: WINSOCK_SHUTDOWN_HOW = 1i32;
@@ -3795,10 +3813,7 @@ impl ::core::clone::Clone for SOCKADDR {
*self
}
}
-#[cfg(target_pointer_width = "32")]
-pub type SOCKET = u32;
-#[cfg(target_pointer_width = "64")]
-pub type SOCKET = u64;
+pub type SOCKET = usize;
pub const SOCKET_ERROR: i32 = -1i32;
pub const SOCK_DGRAM: WINSOCK_SOCKET_TYPE = 2i32;
pub const SOCK_RAW: WINSOCK_SOCKET_TYPE = 3i32;
@@ -3812,6 +3827,16 @@ pub const SO_LINGER: i32 = 128i32;
pub const SO_RCVTIMEO: i32 = 4102i32;
pub const SO_SNDTIMEO: i32 = 4101i32;
pub const SPECIFIC_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 65535u32;
+#[repr(C)]
+pub struct SRWLOCK {
+ pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for SRWLOCK {}
+impl ::core::clone::Clone for SRWLOCK {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
pub const STACK_SIZE_PARAM_IS_A_RESERVATION: THREAD_CREATION_FLAGS = 65536u32;
pub const STANDARD_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 2031616u32;
pub const STANDARD_RIGHTS_EXECUTE: FILE_ACCESS_RIGHTS = 131072u32;
@@ -3833,6 +3858,17 @@ pub const STARTF_USESHOWWINDOW: STARTUPINFOW_FLAGS = 1u32;
pub const STARTF_USESIZE: STARTUPINFOW_FLAGS = 2u32;
pub const STARTF_USESTDHANDLES: STARTUPINFOW_FLAGS = 256u32;
#[repr(C)]
+pub struct STARTUPINFOEXW {
+ pub StartupInfo: STARTUPINFOW,
+ pub lpAttributeList: LPPROC_THREAD_ATTRIBUTE_LIST,
+}
+impl ::core::marker::Copy for STARTUPINFOEXW {}
+impl ::core::clone::Clone for STARTUPINFOEXW {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[repr(C)]
pub struct STARTUPINFOW {
pub cb: u32,
pub lpReserved: PWSTR,
@@ -3971,12 +4007,13 @@ impl ::core::clone::Clone for UNICODE_STRING {
pub const VOLUME_NAME_DOS: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32;
pub const VOLUME_NAME_GUID: GETFINALPATHNAMEBYHANDLE_FLAGS = 1u32;
pub const VOLUME_NAME_NONE: GETFINALPATHNAMEBYHANDLE_FLAGS = 4u32;
-pub const WAIT_ABANDONED: WIN32_ERROR = 128u32;
-pub const WAIT_ABANDONED_0: WIN32_ERROR = 128u32;
-pub const WAIT_FAILED: WIN32_ERROR = 4294967295u32;
-pub const WAIT_IO_COMPLETION: WIN32_ERROR = 192u32;
-pub const WAIT_OBJECT_0: WIN32_ERROR = 0u32;
-pub const WAIT_TIMEOUT: WIN32_ERROR = 258u32;
+pub const WAIT_ABANDONED: WAIT_EVENT = 128u32;
+pub const WAIT_ABANDONED_0: WAIT_EVENT = 128u32;
+pub type WAIT_EVENT = u32;
+pub const WAIT_FAILED: WAIT_EVENT = 4294967295u32;
+pub const WAIT_IO_COMPLETION: WAIT_EVENT = 192u32;
+pub const WAIT_OBJECT_0: WAIT_EVENT = 0u32;
+pub const WAIT_TIMEOUT: WAIT_EVENT = 258u32;
pub const WC_ERR_INVALID_CHARS: u32 = 128u32;
pub type WIN32_ERROR = u32;
#[repr(C)]
diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs
index 84c1fbde3..56d0d6c08 100644
--- a/library/std/src/sys/windows/handle.rs
+++ b/library/std/src/sys/windows/handle.rs
@@ -143,13 +143,8 @@ impl Handle {
) -> io::Result<Option<usize>> {
let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
let mut amt = 0;
- let res = cvt(c::ReadFile(
- self.as_raw_handle(),
- buf.as_ptr() as c::LPVOID,
- len,
- &mut amt,
- overlapped,
- ));
+ let res =
+ cvt(c::ReadFile(self.as_raw_handle(), buf.as_mut_ptr(), len, &mut amt, overlapped));
match res {
Ok(_) => Ok(Some(amt as usize)),
Err(e) => {
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index bcc172b0f..b609ad247 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -60,6 +60,11 @@ pub unsafe fn cleanup() {
net::cleanup();
}
+#[inline]
+pub fn is_interrupted(_errno: i32) -> bool {
+ false
+}
+
pub fn decode_error_kind(errno: i32) -> ErrorKind {
use ErrorKind::*;
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index 1ae42cb7e..abdcab424 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -117,7 +117,7 @@ impl Socket {
};
if socket != c::INVALID_SOCKET {
- unsafe { Ok(Self::from_raw_socket(socket)) }
+ unsafe { Ok(Self::from_raw(socket)) }
} else {
let error = unsafe { c::WSAGetLastError() };
@@ -133,7 +133,7 @@ impl Socket {
}
unsafe {
- let socket = Self::from_raw_socket(socket);
+ let socket = Self::from_raw(socket);
socket.0.set_no_inherit()?;
Ok(socket)
}
@@ -144,7 +144,7 @@ impl Socket {
self.set_nonblocking(true)?;
let result = {
let (addr, len) = addr.into_inner();
- let result = unsafe { c::connect(self.as_raw_socket(), addr.as_ptr(), len) };
+ let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) };
cvt(result).map(drop)
};
self.set_nonblocking(false)?;
@@ -170,7 +170,7 @@ impl Socket {
let fds = {
let mut fds = unsafe { mem::zeroed::<c::fd_set>() };
fds.fd_count = 1;
- fds.fd_array[0] = self.as_raw_socket();
+ fds.fd_array[0] = self.as_raw();
fds
};
@@ -202,11 +202,11 @@ impl Socket {
}
pub fn accept(&self, storage: *mut c::SOCKADDR, len: *mut c_int) -> io::Result<Socket> {
- let socket = unsafe { c::accept(self.as_raw_socket(), storage, len) };
+ let socket = unsafe { c::accept(self.as_raw(), storage, len) };
match socket {
c::INVALID_SOCKET => Err(last_error()),
- _ => unsafe { Ok(Self::from_raw_socket(socket)) },
+ _ => unsafe { Ok(Self::from_raw(socket)) },
}
}
@@ -218,9 +218,8 @@ impl Socket {
// On unix when a socket is shut down all further reads return 0, so we
// do the same on windows to map a shut down socket to returning EOF.
let length = cmp::min(buf.capacity(), i32::MAX as usize) as i32;
- let result = unsafe {
- c::recv(self.as_raw_socket(), buf.as_mut().as_mut_ptr() as *mut _, length, flags)
- };
+ let result =
+ unsafe { c::recv(self.as_raw(), buf.as_mut().as_mut_ptr() as *mut _, length, flags) };
match result {
c::SOCKET_ERROR => {
@@ -257,7 +256,7 @@ impl Socket {
let mut flags = 0;
let result = unsafe {
c::WSARecv(
- self.as_raw_socket(),
+ self.as_raw(),
bufs.as_mut_ptr() as *mut c::WSABUF,
length,
&mut nread,
@@ -305,7 +304,7 @@ impl Socket {
// do the same on windows to map a shut down socket to returning EOF.
let result = unsafe {
c::recvfrom(
- self.as_raw_socket(),
+ self.as_raw(),
buf.as_mut_ptr() as *mut _,
length,
flags,
@@ -341,7 +340,7 @@ impl Socket {
let mut nwritten = 0;
let result = unsafe {
c::WSASend(
- self.as_raw_socket(),
+ self.as_raw(),
bufs.as_ptr() as *const c::WSABUF as *mut _,
length,
&mut nwritten,
@@ -392,14 +391,14 @@ impl Socket {
Shutdown::Read => c::SD_RECEIVE,
Shutdown::Both => c::SD_BOTH,
};
- let result = unsafe { c::shutdown(self.as_raw_socket(), how) };
+ let result = unsafe { c::shutdown(self.as_raw(), how) };
cvt(result).map(drop)
}
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
let mut nonblocking = nonblocking as c_ulong;
let result =
- unsafe { c::ioctlsocket(self.as_raw_socket(), c::FIONBIO as c_int, &mut nonblocking) };
+ unsafe { c::ioctlsocket(self.as_raw(), c::FIONBIO as c_int, &mut nonblocking) };
cvt(result).map(drop)
}
@@ -433,8 +432,15 @@ impl Socket {
}
// This is used by sys_common code to abstract over Windows and Unix.
- pub fn as_raw(&self) -> RawSocket {
- self.as_inner().as_raw_socket()
+ pub fn as_raw(&self) -> c::SOCKET {
+ debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>());
+ debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>());
+ self.as_inner().as_raw_socket() as c::SOCKET
+ }
+ pub unsafe fn from_raw(raw: c::SOCKET) -> Self {
+ debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>());
+ debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>());
+ Self::from_raw_socket(raw as RawSocket)
}
}
diff --git a/library/std/src/sys/windows/os_str.rs b/library/std/src/sys/windows/os_str.rs
index 4708657a9..237854fac 100644
--- a/library/std/src/sys/windows/os_str.rs
+++ b/library/std/src/sys/windows/os_str.rs
@@ -64,12 +64,12 @@ impl fmt::Display for Slice {
impl Buf {
#[inline]
- pub fn into_os_str_bytes(self) -> Vec<u8> {
+ pub fn into_encoded_bytes(self) -> Vec<u8> {
self.inner.into_bytes()
}
#[inline]
- pub unsafe fn from_os_str_bytes_unchecked(s: Vec<u8>) -> Self {
+ pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
Self { inner: Wtf8Buf::from_bytes_unchecked(s) }
}
@@ -162,12 +162,12 @@ impl Buf {
impl Slice {
#[inline]
- pub fn as_os_str_bytes(&self) -> &[u8] {
+ pub fn as_encoded_bytes(&self) -> &[u8] {
self.inner.as_bytes()
}
#[inline]
- pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice {
+ pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
mem::transmute(Wtf8::from_bytes_unchecked(s))
}
diff --git a/library/std/src/sys/windows/path.rs b/library/std/src/sys/windows/path.rs
index c9c2d10e6..8c0e07b35 100644
--- a/library/std/src/sys/windows/path.rs
+++ b/library/std/src/sys/windows/path.rs
@@ -22,12 +22,12 @@ pub fn is_verbatim_sep(b: u8) -> bool {
/// Returns true if `path` looks like a lone filename.
pub(crate) fn is_file_name(path: &OsStr) -> bool {
- !path.as_os_str_bytes().iter().copied().any(is_sep_byte)
+ !path.as_encoded_bytes().iter().copied().any(is_sep_byte)
}
pub(crate) fn has_trailing_slash(path: &OsStr) -> bool {
- let is_verbatim = path.as_os_str_bytes().starts_with(br"\\?\");
+ let is_verbatim = path.as_encoded_bytes().starts_with(br"\\?\");
let is_separator = if is_verbatim { is_verbatim_sep } else { is_sep_byte };
- if let Some(&c) = path.as_os_str_bytes().last() { is_separator(c) } else { false }
+ if let Some(&c) = path.as_encoded_bytes().last() { is_separator(c) } else { false }
}
/// Appends a suffix to a path.
@@ -49,7 +49,7 @@ impl<'a, const LEN: usize> PrefixParser<'a, LEN> {
fn get_prefix(path: &OsStr) -> [u8; LEN] {
let mut prefix = [0; LEN];
// SAFETY: Only ASCII characters are modified.
- for (i, &ch) in path.as_os_str_bytes().iter().take(LEN).enumerate() {
+ for (i, &ch) in path.as_encoded_bytes().iter().take(LEN).enumerate() {
prefix[i] = if ch == b'/' { b'\\' } else { ch };
}
prefix
@@ -82,7 +82,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
}
fn prefix_bytes(&self) -> &'a [u8] {
- &self.path.as_os_str_bytes()[..self.index]
+ &self.path.as_encoded_bytes()[..self.index]
}
fn finish(self) -> &'a OsStr {
@@ -90,7 +90,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
// &[u8] and back. This is safe to do because (1) we only look at ASCII
// contents of the encoding and (2) new &OsStr values are produced only
// from ASCII-bounded slices of existing &OsStr values.
- unsafe { OsStr::from_os_str_bytes_unchecked(&self.path.as_os_str_bytes()[self.index..]) }
+ unsafe { OsStr::from_encoded_bytes_unchecked(&self.path.as_encoded_bytes()[self.index..]) }
}
}
@@ -162,7 +162,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
drive.is_ascii_alphabetic()
}
- match path.as_os_str_bytes() {
+ match path.as_encoded_bytes() {
[drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()),
_ => None,
}
@@ -171,7 +171,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
// Parses a drive prefix exactly, e.g. "C:"
fn parse_drive_exact(path: &OsStr) -> Option<u8> {
// only parse two bytes: the drive letter and the drive separator
- if path.as_os_str_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
+ if path.as_encoded_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
parse_drive(path)
} else {
None
@@ -185,15 +185,15 @@ fn parse_drive_exact(path: &OsStr) -> Option<u8> {
fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
let separator = if verbatim { is_verbatim_sep } else { is_sep_byte };
- match path.as_os_str_bytes().iter().position(|&x| separator(x)) {
+ match path.as_encoded_bytes().iter().position(|&x| separator(x)) {
Some(separator_start) => {
let separator_end = separator_start + 1;
- let component = &path.as_os_str_bytes()[..separator_start];
+ let component = &path.as_encoded_bytes()[..separator_start];
// Panic safe
// The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
- let path = &path.as_os_str_bytes()[separator_end..];
+ let path = &path.as_encoded_bytes()[separator_end..];
// SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
// is encoded in a single byte, therefore `bytes[separator_start]` and
@@ -201,8 +201,8 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
// `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
unsafe {
(
- OsStr::from_os_str_bytes_unchecked(component),
- OsStr::from_os_str_bytes_unchecked(path),
+ OsStr::from_encoded_bytes_unchecked(component),
+ OsStr::from_encoded_bytes_unchecked(path),
)
}
}
@@ -323,7 +323,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
// Verbatim paths should not be modified.
if prefix.map(|x| x.is_verbatim()).unwrap_or(false) {
// NULs in verbatim paths are rejected for consistency.
- if path.as_os_str_bytes().contains(&0) {
+ if path.as_encoded_bytes().contains(&0) {
return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
"strings passed to WinAPI cannot contain NULs",
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index d07147ecc..7624e746f 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -12,7 +12,7 @@ use crate::sys::c;
use crate::sys::fs::{File, OpenOptions};
use crate::sys::handle::Handle;
use crate::sys::hashmap_random_keys;
-use crate::sys_common::IntoInner;
+use crate::sys_common::{FromInner, IntoInner};
////////////////////////////////////////////////////////////////////////////////
// Anonymous pipes
@@ -28,6 +28,12 @@ impl IntoInner<Handle> for AnonPipe {
}
}
+impl FromInner<Handle> for AnonPipe {
+ fn from_inner(inner: Handle) -> AnonPipe {
+ Self { inner }
+ }
+}
+
pub struct Pipes {
pub ours: AnonPipe,
pub theirs: AnonPipe,
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index 2dd0c67ac..cd5bf7f15 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -11,6 +11,7 @@ use crate::ffi::{OsStr, OsString};
use crate::fmt;
use crate::io::{self, Error, ErrorKind};
use crate::mem;
+use crate::mem::MaybeUninit;
use crate::num::NonZeroI32;
use crate::os::windows::ffi::{OsStrExt, OsStringExt};
use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle};
@@ -166,10 +167,12 @@ pub struct Command {
stdout: Option<Stdio>,
stderr: Option<Stdio>,
force_quotes_enabled: bool,
+ proc_thread_attributes: BTreeMap<usize, ProcThreadAttributeValue>,
}
pub enum Stdio {
Inherit,
+ InheritSpecific { from_stdio_id: c::DWORD },
Null,
MakePipe,
Pipe(AnonPipe),
@@ -195,6 +198,7 @@ impl Command {
stdout: None,
stderr: None,
force_quotes_enabled: false,
+ proc_thread_attributes: Default::default(),
}
}
@@ -245,6 +249,17 @@ impl Command {
self.cwd.as_ref().map(|cwd| Path::new(cwd))
}
+ pub unsafe fn raw_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(
&mut self,
default: Stdio,
@@ -308,7 +323,6 @@ impl Command {
let stderr = stderr.to_handle(c::STD_ERROR_HANDLE, &mut pipes.stderr)?;
let mut si = zeroed_startupinfo();
- si.cb = mem::size_of::<c::STARTUPINFOW>() as c::DWORD;
// If at least one of stdin, stdout or stderr are set (i.e. are non null)
// then set the `hStd` fields in `STARTUPINFO`.
@@ -322,6 +336,27 @@ impl Command {
si.hStdError = stderr.as_raw_handle();
}
+ let si_ptr: *mut c::STARTUPINFOW;
+
+ let mut proc_thread_attribute_list;
+ let mut si_ex;
+
+ if !self.proc_thread_attributes.is_empty() {
+ si.cb = mem::size_of::<c::STARTUPINFOEXW>() as u32;
+ flags |= c::EXTENDED_STARTUPINFO_PRESENT;
+
+ proc_thread_attribute_list =
+ make_proc_thread_attribute_list(&self.proc_thread_attributes)?;
+ si_ex = c::STARTUPINFOEXW {
+ StartupInfo: si,
+ lpAttributeList: proc_thread_attribute_list.0.as_mut_ptr() as _,
+ };
+ si_ptr = &mut si_ex as *mut _ as _;
+ } else {
+ si.cb = mem::size_of::<c::STARTUPINFOW>() as c::DWORD;
+ si_ptr = &mut si as *mut _ as _;
+ }
+
unsafe {
cvt(c::CreateProcessW(
program.as_ptr(),
@@ -332,7 +367,7 @@ impl Command {
flags,
envp,
dirp,
- &si,
+ si_ptr,
&mut pi,
))
}?;
@@ -395,7 +430,7 @@ fn resolve_exe<'a>(
// Test if the file name has the `exe` extension.
// This does a case-insensitive `ends_with`.
let has_exe_suffix = if exe_path.len() >= EXE_SUFFIX.len() {
- exe_path.as_os_str_bytes()[exe_path.len() - EXE_SUFFIX.len()..]
+ exe_path.as_encoded_bytes()[exe_path.len() - EXE_SUFFIX.len()..]
.eq_ignore_ascii_case(EXE_SUFFIX.as_bytes())
} else {
false
@@ -425,7 +460,7 @@ fn resolve_exe<'a>(
// From the `CreateProcessW` docs:
// > If the file name does not contain an extension, .exe is appended.
// Note that this rule only applies when searching paths.
- let has_extension = exe_path.as_os_str_bytes().contains(&b'.');
+ let has_extension = exe_path.as_encoded_bytes().contains(&b'.');
// Search the directories given by `search_paths`.
let result = search_paths(parent_paths, child_paths, |mut path| {
@@ -521,17 +556,19 @@ fn program_exists(path: &Path) -> Option<Vec<u16>> {
impl Stdio {
fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>) -> io::Result<Handle> {
- match *self {
- Stdio::Inherit => match stdio::get_handle(stdio_id) {
- Ok(io) => unsafe {
- let io = Handle::from_raw_handle(io);
- let ret = io.duplicate(0, true, c::DUPLICATE_SAME_ACCESS);
- io.into_raw_handle();
- ret
- },
- // If no stdio handle is available, then propagate the null value.
- Err(..) => unsafe { Ok(Handle::from_raw_handle(ptr::null_mut())) },
+ let use_stdio_id = |stdio_id| match stdio::get_handle(stdio_id) {
+ Ok(io) => unsafe {
+ let io = Handle::from_raw_handle(io);
+ let ret = io.duplicate(0, true, c::DUPLICATE_SAME_ACCESS);
+ io.into_raw_handle();
+ ret
},
+ // If no stdio handle is available, then propagate the null value.
+ Err(..) => unsafe { Ok(Handle::from_raw_handle(ptr::null_mut())) },
+ };
+ match *self {
+ Stdio::Inherit => use_stdio_id(stdio_id),
+ Stdio::InheritSpecific { from_stdio_id } => use_stdio_id(from_stdio_id),
Stdio::MakePipe => {
let ours_readable = stdio_id != c::STD_INPUT_HANDLE;
@@ -579,6 +616,18 @@ impl From<File> for Stdio {
}
}
+impl From<io::Stdout> for Stdio {
+ fn from(_: io::Stdout) -> Stdio {
+ Stdio::InheritSpecific { from_stdio_id: c::STD_OUTPUT_HANDLE }
+ }
+}
+
+impl From<io::Stderr> for Stdio {
+ fn from(_: io::Stderr) -> Stdio {
+ Stdio::InheritSpecific { from_stdio_id: c::STD_ERROR_HANDLE }
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// Processes
////////////////////////////////////////////////////////////////////////////////
@@ -831,6 +880,80 @@ fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> {
}
}
+struct ProcThreadAttributeList(Box<[MaybeUninit<u8>]>);
+
+impl Drop for ProcThreadAttributeList {
+ fn drop(&mut self) {
+ let lp_attribute_list = self.0.as_mut_ptr() as _;
+ unsafe { c::DeleteProcThreadAttributeList(lp_attribute_list) }
+ }
+}
+
+/// Wrapper around the value data to be used as a Process Thread Attribute.
+struct ProcThreadAttributeValue {
+ data: Box<dyn Send + Sync>,
+ size: usize,
+}
+
+fn make_proc_thread_attribute_list(
+ attributes: &BTreeMap<usize, ProcThreadAttributeValue>,
+) -> io::Result<ProcThreadAttributeList> {
+ // To initialize our ProcThreadAttributeList, we need to determine
+ // how many bytes to allocate for it. The Windows API simplifies this process
+ // by allowing us to call `InitializeProcThreadAttributeList` with
+ // a null pointer to retrieve the required size.
+ let mut required_size = 0;
+ let Ok(attribute_count) = attributes.len().try_into() else {
+ return Err(io::const_io_error!(
+ ErrorKind::InvalidInput,
+ "maximum number of ProcThreadAttributes exceeded",
+ ));
+ };
+ unsafe {
+ c::InitializeProcThreadAttributeList(
+ ptr::null_mut(),
+ attribute_count,
+ 0,
+ &mut required_size,
+ )
+ };
+
+ let mut proc_thread_attribute_list = ProcThreadAttributeList(
+ vec![MaybeUninit::uninit(); required_size as usize].into_boxed_slice(),
+ );
+
+ // Once we've allocated the necessary memory, it's safe to invoke
+ // `InitializeProcThreadAttributeList` to properly initialize the list.
+ cvt(unsafe {
+ c::InitializeProcThreadAttributeList(
+ proc_thread_attribute_list.0.as_mut_ptr() as *mut _,
+ attribute_count,
+ 0,
+ &mut required_size,
+ )
+ })?;
+
+ // # Add our attributes to the buffer.
+ // It's theoretically possible for the attribute count to exceed a u32 value.
+ // Therefore, we ensure that we don't add more attributes than the buffer was initialized for.
+ for (&attribute, value) in attributes.iter().take(attribute_count as usize) {
+ let value_ptr = &*value.data as *const (dyn Send + Sync) as _;
+ cvt(unsafe {
+ c::UpdateProcThreadAttribute(
+ proc_thread_attribute_list.0.as_mut_ptr() as _,
+ 0,
+ attribute,
+ value_ptr,
+ value.size,
+ ptr::null_mut(),
+ ptr::null_mut(),
+ )
+ })?;
+ }
+
+ Ok(proc_thread_attribute_list)
+}
+
pub struct CommandArgs<'a> {
iter: crate::slice::Iter<'a, Arg>,
}