mirror of
https://github.com/rust-lang/rust
synced 2024-10-18 22:43:56 +00:00
Make synchronous_write
safe to call
This commit is contained in:
parent
084b71a54f
commit
88c05edc9d
|
@ -986,13 +986,6 @@ pub fn ReadFileEx(
|
|||
lpOverlapped: LPOVERLAPPED,
|
||||
lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
|
||||
) -> BOOL;
|
||||
pub fn WriteFile(
|
||||
hFile: BorrowedHandle<'_>,
|
||||
lpBuffer: LPVOID,
|
||||
nNumberOfBytesToWrite: DWORD,
|
||||
lpNumberOfBytesWritten: LPDWORD,
|
||||
lpOverlapped: LPOVERLAPPED,
|
||||
) -> BOOL;
|
||||
pub fn WriteFileEx(
|
||||
hFile: BorrowedHandle<'_>,
|
||||
lpBuffer: LPVOID,
|
||||
|
|
|
@ -192,7 +192,7 @@ pub fn cancel_io(&self) -> io::Result<()> {
|
|||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
unsafe { self.synchronous_write(&buf, None) }
|
||||
self.synchronous_write(&buf, None)
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
|
@ -205,7 +205,7 @@ pub fn is_write_vectored(&self) -> bool {
|
|||
}
|
||||
|
||||
pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
unsafe { self.synchronous_write(&buf, Some(offset)) }
|
||||
self.synchronous_write(&buf, Some(offset))
|
||||
}
|
||||
|
||||
pub fn try_clone(&self) -> io::Result<Self> {
|
||||
|
@ -276,25 +276,27 @@ unsafe fn synchronous_read(
|
|||
/// See #81357.
|
||||
///
|
||||
/// If `offset` is `None` then the current file position is used.
|
||||
unsafe fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize> {
|
||||
fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize> {
|
||||
let mut io_status = c::IO_STATUS_BLOCK::default();
|
||||
|
||||
// The length is clamped at u32::MAX.
|
||||
let len = cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
|
||||
let status = c::NtWriteFile(
|
||||
self.as_handle(),
|
||||
ptr::null_mut(),
|
||||
None,
|
||||
ptr::null_mut(),
|
||||
&mut io_status,
|
||||
buf.as_ptr(),
|
||||
len,
|
||||
offset.map(|n| n as _).as_ref(),
|
||||
None,
|
||||
);
|
||||
let status = unsafe {
|
||||
c::NtWriteFile(
|
||||
self.as_handle(),
|
||||
ptr::null_mut(),
|
||||
None,
|
||||
ptr::null_mut(),
|
||||
&mut io_status,
|
||||
buf.as_ptr(),
|
||||
len,
|
||||
offset.map(|n| n as _).as_ref(),
|
||||
None,
|
||||
)
|
||||
};
|
||||
match status {
|
||||
// If the operation has not completed then abort the process.
|
||||
// Doing otherwise means that the buffer maybe read and the stack
|
||||
// Doing otherwise means that the buffer may be read and the stack
|
||||
// written to after this function returns.
|
||||
c::STATUS_PENDING => {
|
||||
eprintln!("I/O error: operation failed to complete synchronously");
|
||||
|
@ -305,7 +307,7 @@ unsafe fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Resul
|
|||
status if c::nt_success(status) => Ok(io_status.Information),
|
||||
|
||||
status => {
|
||||
let error = c::RtlNtStatusToDosError(status);
|
||||
let error = unsafe { c::RtlNtStatusToDosError(status) };
|
||||
Err(io::Error::from_raw_os_error(error as _))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue