diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/miow/src/handle.rs | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/miow/src/handle.rs')
-rw-r--r-- | third_party/rust/miow/src/handle.rs | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/third_party/rust/miow/src/handle.rs b/third_party/rust/miow/src/handle.rs new file mode 100644 index 0000000000..a749fb3269 --- /dev/null +++ b/third_party/rust/miow/src/handle.rs @@ -0,0 +1,177 @@ +use std::cmp; +use std::io; +use std::ptr; + +use winapi::shared::minwindef::*; +use winapi::shared::ntdef::{BOOLEAN, FALSE, HANDLE, TRUE}; +use winapi::shared::winerror::*; +use winapi::um::fileapi::*; +use winapi::um::handleapi::*; +use winapi::um::ioapiset::*; +use winapi::um::minwinbase::*; + +#[derive(Debug)] +pub struct Handle(HANDLE); + +unsafe impl Send for Handle {} +unsafe impl Sync for Handle {} + +impl Handle { + pub fn new(handle: HANDLE) -> Handle { + Handle(handle) + } + + pub fn raw(&self) -> HANDLE { + self.0 + } + + pub fn into_raw(self) -> HANDLE { + use std::mem; + + let ret = self.0; + mem::forget(self); + ret + } + + pub fn write(&self, buf: &[u8]) -> io::Result<usize> { + let mut bytes = 0; + let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD; + crate::cvt(unsafe { + WriteFile( + self.0, + buf.as_ptr() as *const _, + len, + &mut bytes, + 0 as *mut _, + ) + })?; + Ok(bytes as usize) + } + + pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { + let mut bytes = 0; + let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD; + crate::cvt(unsafe { + ReadFile( + self.0, + buf.as_mut_ptr() as *mut _, + len, + &mut bytes, + 0 as *mut _, + ) + })?; + Ok(bytes as usize) + } + + pub unsafe fn read_overlapped( + &self, + buf: &mut [u8], + overlapped: *mut OVERLAPPED, + ) -> io::Result<Option<usize>> { + self.read_overlapped_helper(buf, overlapped, FALSE) + } + + pub unsafe fn read_overlapped_wait( + &self, + buf: &mut [u8], + overlapped: *mut OVERLAPPED, + ) -> io::Result<usize> { + match self.read_overlapped_helper(buf, overlapped, TRUE) { + Ok(Some(bytes)) => Ok(bytes), + Ok(None) => panic!("logic error"), + Err(e) => Err(e), + } + } + + pub unsafe fn read_overlapped_helper( + &self, + buf: &mut [u8], + overlapped: *mut OVERLAPPED, + wait: BOOLEAN, + ) -> io::Result<Option<usize>> { + let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD; + let res = crate::cvt({ + ReadFile( + self.0, + buf.as_mut_ptr() as *mut _, + len, + ptr::null_mut(), + overlapped, + ) + }); + match res { + Ok(_) => (), + Err(ref e) if e.raw_os_error() == Some(ERROR_IO_PENDING as i32) => (), + Err(e) => return Err(e), + } + + let mut bytes = 0; + let res = crate::cvt({ GetOverlappedResult(self.0, overlapped, &mut bytes, wait as BOOL) }); + match res { + Ok(_) => Ok(Some(bytes as usize)), + Err(ref e) if e.raw_os_error() == Some(ERROR_IO_INCOMPLETE as i32) && wait == FALSE => { + Ok(None) + } + Err(e) => Err(e), + } + } + + pub unsafe fn write_overlapped( + &self, + buf: &[u8], + overlapped: *mut OVERLAPPED, + ) -> io::Result<Option<usize>> { + self.write_overlapped_helper(buf, overlapped, FALSE) + } + + pub unsafe fn write_overlapped_wait( + &self, + buf: &[u8], + overlapped: *mut OVERLAPPED, + ) -> io::Result<usize> { + match self.write_overlapped_helper(buf, overlapped, TRUE) { + Ok(Some(bytes)) => Ok(bytes), + Ok(None) => panic!("logic error"), + Err(e) => Err(e), + } + } + + unsafe fn write_overlapped_helper( + &self, + buf: &[u8], + overlapped: *mut OVERLAPPED, + wait: BOOLEAN, + ) -> io::Result<Option<usize>> { + let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD; + let res = crate::cvt({ + WriteFile( + self.0, + buf.as_ptr() as *const _, + len, + ptr::null_mut(), + overlapped, + ) + }); + match res { + Ok(_) => (), + Err(ref e) if e.raw_os_error() == Some(ERROR_IO_PENDING as i32) => (), + Err(e) => return Err(e), + } + + let mut bytes = 0; + let res = crate::cvt({ GetOverlappedResult(self.0, overlapped, &mut bytes, wait as BOOL) }); + match res { + Ok(_) => Ok(Some(bytes as usize)), + Err(ref e) if e.raw_os_error() == Some(ERROR_IO_INCOMPLETE as i32) && wait == FALSE => { + Ok(None) + } + Err(e) => Err(e), + } + } +} + +impl Drop for Handle { + fn drop(&mut self) { + unsafe { CloseHandle(self.0) }; + } +} |