FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix _overlapped segfault and missing _winapi constants by youknowone · Pull Request #6907 · RustPython/RustPython · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .rs  (2) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
116 changes: 76 additions & 40 deletions crates/stdlib/src/overlapped.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod _overlapped {
convert::{ToPyException, ToPyObject},
function::OptionalArg,
protocol::PyBuffer,
types::Constructor,
types::{Constructor, Destructor},
};
use windows_sys::Win32::{
Foundation::{self, GetLastError, HANDLE},
Expand Down Expand Up @@ -235,14 +235,8 @@ mod _overlapped {
}

fn from_windows_err(err: u32, vm: &VirtualMachine) -> PyBaseExceptionRef {
use Foundation::{ERROR_CONNECTION_ABORTED, ERROR_CONNECTION_REFUSED};
debug_assert_ne!(err, 0, "call errno_err instead");
let exc = match err {
ERROR_CONNECTION_REFUSED => vm.ctx.exceptions.connection_refused_error,
ERROR_CONNECTION_ABORTED => vm.ctx.exceptions.connection_aborted_error,
err => return std::io::Error::from_raw_os_error(err as i32).to_pyexception(vm),
};
vm.new_exception_empty(exc.to_owned())
std::io::Error::from_raw_os_error(err as i32).to_pyexception(vm)
}

fn HasOverlappedIoCompleted(overlapped: &OVERLAPPED) -> bool {
Expand Down Expand Up @@ -383,7 +377,7 @@ mod _overlapped {
}
}

#[pyclass(with(Constructor))]
#[pyclass(with(Constructor, Destructor))]
impl Overlapped {
#[pygetset]
fn address(&self, _vm: &VirtualMachine) -> usize {
Expand Down Expand Up @@ -438,7 +432,6 @@ mod _overlapped {
use windows_sys::Win32::Foundation::{
ERROR_BROKEN_PIPE, ERROR_IO_PENDING, ERROR_MORE_DATA, ERROR_SUCCESS,
};
use windows_sys::Win32::System::IO::GetOverlappedResult;

let mut inner = zelf.inner.lock();
let wait = wait.unwrap_or(false);
Expand All @@ -454,7 +447,7 @@ mod _overlapped {
// Get the result
let mut transferred: u32 = 0;
let ret = unsafe {
GetOverlappedResult(
windows_sys::Win32::System::IO::GetOverlappedResult(
inner.handle,
&inner.overlapped,
&mut transferred,
Expand Down Expand Up @@ -1190,35 +1183,6 @@ mod _overlapped {
}
}

// ConnectPipe - this is a static method that returns a handle
#[pymethod]
fn ConnectPipe(address: String, vm: &VirtualMachine) -> PyResult<isize> {
use windows_sys::Win32::Storage::FileSystem::{
CreateFileW, FILE_FLAG_OVERLAPPED, FILE_GENERIC_READ, FILE_GENERIC_WRITE,
OPEN_EXISTING,
};

let address_wide: Vec<u16> = address.encode_utf16().chain(std::iter::once(0)).collect();

let handle = unsafe {
CreateFileW(
address_wide.as_ptr(),
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
0,
std::ptr::null(),
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
std::ptr::null_mut(),
)
};

if handle == windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE {
return Err(vm.new_last_os_error());
}

Ok(handle as isize)
}

// WSASendTo
#[pymethod]
fn WSASendTo(
Expand Down Expand Up @@ -1508,6 +1472,78 @@ mod _overlapped {
}
}

impl Destructor for Overlapped {
fn del(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<()> {
use windows_sys::Win32::System::IO::{CancelIoEx, GetOverlappedResult};

let mut inner = zelf.inner.lock();
let olderr = unsafe { GetLastError() };

// Cancel pending I/O and wait for completion
if !HasOverlappedIoCompleted(&inner.overlapped)
&& !matches!(
inner.data,
OverlappedData::None | OverlappedData::NotStarted
)
{
let cancelled = unsafe { CancelIoEx(inner.handle, &inner.overlapped) } != 0;

if cancelled {
// Wait for the cancellation to complete
let mut transferred: u32 = 0;
unsafe {
GetOverlappedResult(
inner.handle,
&inner.overlapped,
&mut transferred,
1, // bWait = TRUE
)
};
}
}

// Close the event handle
if !inner.overlapped.hEvent.is_null() {
unsafe {
Foundation::CloseHandle(inner.overlapped.hEvent);
}
inner.overlapped.hEvent = std::ptr::null_mut();
}

// Restore last error
unsafe { Foundation::SetLastError(olderr) };

Ok(())
}
}

#[pyfunction]
fn ConnectPipe(address: String, vm: &VirtualMachine) -> PyResult<isize> {
use windows_sys::Win32::Storage::FileSystem::{
CreateFileW, FILE_FLAG_OVERLAPPED, FILE_GENERIC_READ, FILE_GENERIC_WRITE, OPEN_EXISTING,
};

let address_wide: Vec<u16> = address.encode_utf16().chain(std::iter::once(0)).collect();

let handle = unsafe {
CreateFileW(
address_wide.as_ptr(),
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
0,
std::ptr::null(),
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
std::ptr::null_mut(),
)
};

if handle == windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE {
return Err(vm.new_last_os_error());
}

Ok(handle as isize)
}

#[pyfunction]
fn CreateIoCompletionPort(
handle: isize,
Expand Down
1 change: 1 addition & 0 deletions crates/vm/src/stdlib/winapi.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ mod _winapi {
SEC_LARGE_PAGES, SEC_NOCACHE, SEC_RESERVE, SEC_WRITECOMBINE,
},
Pipes::{
NMPWAIT_NOWAIT, NMPWAIT_USE_DEFAULT_WAIT, NMPWAIT_WAIT_FOREVER,
PIPE_READMODE_MESSAGE, PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES, PIPE_WAIT,
},
SystemServices::LOCALE_NAME_MAX_LENGTH,
Expand Down
Loading

Back | FazBrowse Home | New Git URL