From cef23cbc46446136bedfa9817cf7a3395c276deb Mon Sep 17 00:00:00 2001 From: Christopher Berner Date: Fri, 27 Sep 2024 20:11:24 -0700 Subject: [PATCH] WIP: Windows --- .../std/src/sys/pal/windows/c/windows_sys.rs | 2 + library/std/src/sys/pal/windows/fs.rs | 62 +++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index ab5f8919d7af6..4cfa747983666 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -65,6 +65,7 @@ windows_targets::link!("kernel32.dll" "system" fn InitOnceBeginInitialize(lpinit windows_targets::link!("kernel32.dll" "system" fn InitOnceComplete(lpinitonce : *mut INIT_ONCE, dwflags : u32, lpcontext : *const core::ffi::c_void) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwattributecount : u32, dwflags : u32, lpsize : *mut usize) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL); +windows_targets::link!("kernel32.dll" "system" fn LockFileEx(hfile : HANDLE, dwflags : u32, dwreserved : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32, lpoverlapped : *mut OVERLAPPED) -> bool); windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : PCSTR, cbmultibyte : i32, lpwidecharstr : PWSTR, cchwidechar : i32) -> i32); windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceCounter(lpperformancecount : *mut i64) -> BOOL); @@ -96,6 +97,7 @@ windows_targets::link!("kernel32.dll" "system" fn TlsGetValue(dwtlsindex : u32) windows_targets::link!("kernel32.dll" "system" fn TlsSetValue(dwtlsindex : u32, lptlsvalue : *const core::ffi::c_void) -> BOOL); windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockExclusive(srwlock : *mut SRWLOCK) -> BOOLEAN); windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockShared(srwlock : *mut SRWLOCK) -> BOOLEAN); +windows_targets::link!("kernel32.dll" "system" fn UnlockFile(hfile : HANDLE, dwfileoffsetlow: u32, dwfileoffsethigh : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32) -> bool); windows_targets::link!("kernel32.dll" "system" 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); windows_targets::link!("kernel32.dll" "system" fn WaitForMultipleObjects(ncount : u32, lphandles : *const HANDLE, bwaitall : BOOL, dwmilliseconds : u32) -> WAIT_EVENT); windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT); diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index 2e41071ada005..3633ad6c3fbd2 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -349,23 +349,75 @@ impl File { } pub fn lock(&self) -> io::Result<()> { - unsupported() + cvt(unsafe { + let overlapped = mem::zeroed(); + c::LockFileEx( + self.handle.as_raw_handle(), + c::LOCKFILE_EXCLUSIVE_LOCK, + 0, + u32::MAX, + u32::MAX, + &mut overlapped, + ) + })?; + Ok(()) } pub fn lock_shared(&self) -> io::Result<()> { - unsupported() + cvt(unsafe { + let overlapped = mem::zeroed(); + c::LockFileEx(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX, &mut overlapped) + })?; + Ok(()) } pub fn try_lock(&self) -> io::Result { - unsupported() + let result = cvt(unsafe { + let overlapped = mem::zeroed(); + c::LockFileEx( + self.handle.as_raw_handle(), + c::LOCKFILE_EXCLUSIVE_LOCK | c::LOCKFILE_FAIL_IMMEDIATELY, + 0, + u32::MAX, + u32::MAX, + &mut overlapped, + ) + }); + + if let Err(ref err) = result { + if err.raw_os_error() == Some(c::ERROR_IO_PENDING) { + return Ok(false); + } + } + result?; + Ok(true) } pub fn try_lock_shared(&self) -> io::Result { - unsupported() + let result = cvt(unsafe { + let overlapped = mem::zeroed(); + c::LockFileEx( + self.handle.as_raw_handle(), + c::LOCKFILE_FAIL_IMMEDIATELY, + 0, + u32::MAX, + u32::MAX, + &mut overlapped, + ) + }); + + if let Err(ref err) = result { + if err.raw_os_error() == Some(c::ERROR_IO_PENDING) { + return Ok(false); + } + } + result?; + Ok(true) } pub fn unlock(&self) -> io::Result<()> { - unsupported() + cvt(unsafe { c::UnlockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) })?; + Ok(()) } pub fn truncate(&self, size: u64) -> io::Result<()> {