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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -2428,12 +2428,10 @@ def test_ftruncate(self):
self.check(os.ftruncate, 0)
self.check_bool(os.truncate, 0)

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)')
@unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()')
def test_lseek(self):
self.check(os.lseek, 0, 0)

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)')
@unittest.skipUnless(hasattr(os, 'read'), 'test needs os.read()')
def test_read(self):
self.check(os.read, 1)
Expand All @@ -2447,7 +2445,6 @@ def test_readv(self):
def test_tcsetpgrpt(self):
self.check(os.tcsetpgrp, 0)

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)')
@unittest.skipUnless(hasattr(os, 'write'), 'test needs os.write()')
def test_write(self):
self.check(os.write, b" ")
Expand All @@ -2456,7 +2453,6 @@ def test_write(self):
def test_writev(self):
self.check(os.writev, [b'abc'])

@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
@support.requires_subprocess()
def test_inheritable(self):
self.check(os.get_inheritable)
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2891,7 +2891,6 @@ def test_echo(self):
'Cannot create a client socket with a PROTOCOL_TLS_SERVER context',
str(e.exception))

@unittest.skip("TODO: RUSTPYTHON; Flaky on windows")
@unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled")
def test_ssl_in_multiple_threads(self):
# See GH-124984: OpenSSL is not thread safe.
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@ def test_temp_cwd__name_none(self):
def test_sortdict(self):
self.assertEqual(support.sortdict({3:3, 2:2, 1:1}), "{1: 1, 2: 2, 3: 3}")

@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; actual c fds on windows")
def test_make_bad_fd(self):
fd = os_helper.make_bad_fd()
with self.assertRaises(OSError) as cm:
Expand Down
6 changes: 4 additions & 2 deletions crates/common/src/crt_fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ pub type Raw = i32;
#[inline]
fn cvt<I: num_traits::PrimInt>(ret: I) -> io::Result<I> {
if ret < I::zero() {
Err(crate::os::last_os_error())
// CRT functions set errno, not GetLastError(), so use errno_io_error
Err(crate::os::errno_io_error())
} else {
Ok(ret)
}
Expand Down Expand Up @@ -345,7 +346,8 @@ pub fn as_handle(fd: Borrowed<'_>) -> io::Result<BorrowedHandle<'_>> {
}
let handle = unsafe { suppress_iph!(_get_osfhandle(fd)) };
if handle as HANDLE == INVALID_HANDLE_VALUE {
Err(crate::os::last_os_error())
// _get_osfhandle is a CRT function that sets errno, not GetLastError()
Err(crate::os::errno_io_error())
} else {
Ok(unsafe { BorrowedHandle::borrow_raw(handle as _) })
}
Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/fileutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn fstat(fd: crate::crt_fd::Borrowed<'_>) -> std::io::Result<StatStruct> {
unsafe {
let ret = libc::fstat(fd.as_raw(), stat.as_mut_ptr());
if ret == -1 {
Err(crate::os::last_os_error())
Err(crate::os::errno_io_error())
} else {
Ok(stat.assume_init())
}
Expand Down
30 changes: 11 additions & 19 deletions crates/common/src/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,22 @@ impl ErrorExt for io::Error {
}
}

/// Get the last error from C runtime library functions (like _dup, _dup2, _fstat, etc.)
/// CRT functions set errno, not GetLastError(), so we need to read errno directly.
#[cfg(windows)]
pub fn last_os_error() -> io::Error {
let err = io::Error::last_os_error();
// FIXME: probably not ideal, we need a bigger dichotomy between GetLastError and errno
if err.raw_os_error() == Some(0) {
unsafe extern "C" {
fn _get_errno(pValue: *mut i32) -> i32;
}
let mut errno = 0;
unsafe { suppress_iph!(_get_errno(&mut errno)) };
let errno = errno_to_winerror(errno);
io::Error::from_raw_os_error(errno)
} else {
err
}
pub fn errno_io_error() -> io::Error {
let errno: i32 = get_errno();
let winerror = errno_to_winerror(errno);
io::Error::from_raw_os_error(winerror)
}

#[cfg(not(windows))]
pub fn last_os_error() -> io::Error {
io::Error::last_os_error()
pub fn errno_io_error() -> io::Error {
std::io::Error::last_os_error()
}

#[cfg(windows)]
pub fn last_posix_errno() -> i32 {
pub fn get_errno() -> i32 {
unsafe extern "C" {
fn _get_errno(pValue: *mut i32) -> i32;
}
Expand All @@ -52,8 +44,8 @@ pub fn last_posix_errno() -> i32 {
}

#[cfg(not(windows))]
pub fn last_posix_errno() -> i32 {
last_os_error().posix_errno()
pub fn get_errno() -> i32 {
std::io::Error::last_os_error().posix_errno()
}

#[cfg(unix)]
Expand Down
16 changes: 8 additions & 8 deletions crates/stdlib/src/fcntl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod fcntl {
PyResult, VirtualMachine,
builtins::PyIntRef,
function::{ArgMemoryBuffer, ArgStrOrBytesLike, Either, OptionalArg},
stdlib::{io, os},
stdlib::io,
};

// TODO: supply these from <asm-generic/fnctl.h> (please file an issue/PR upstream):
Expand Down Expand Up @@ -75,7 +75,7 @@ mod fcntl {
}
let ret = unsafe { libc::fcntl(fd, cmd, buf.as_mut_ptr()) };
if ret < 0 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
return Ok(vm.ctx.new_bytes(buf[..arg_len].to_vec()).into());
}
Expand All @@ -84,7 +84,7 @@ mod fcntl {
};
let ret = unsafe { libc::fcntl(fd, cmd, int as i32) };
if ret < 0 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
Ok(vm.new_pyobj(ret))
}
Expand Down Expand Up @@ -117,7 +117,7 @@ mod fcntl {
let ret =
unsafe { libc::ioctl(fd, request as _, arg_buf.as_mut_ptr()) };
if ret < 0 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
return Ok(vm.ctx.new_int(ret).into());
}
Expand All @@ -128,14 +128,14 @@ mod fcntl {
};
let ret = unsafe { libc::ioctl(fd, request as _, buf.as_mut_ptr()) };
if ret < 0 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
Ok(vm.ctx.new_bytes(buf[..buf_len].to_vec()).into())
}
Either::B(i) => {
let ret = unsafe { libc::ioctl(fd, request as _, i) };
if ret < 0 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
Ok(vm.ctx.new_int(ret).into())
}
Expand All @@ -149,7 +149,7 @@ mod fcntl {
let ret = unsafe { libc::flock(fd, operation) };
// TODO: add support for platforms that don't have a builtin `flock` syscall
if ret < 0 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
Ok(vm.ctx.new_int(ret).into())
}
Expand Down Expand Up @@ -209,7 +209,7 @@ mod fcntl {
)
};
if ret < 0 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
Ok(vm.ctx.new_int(ret).into())
}
Expand Down
8 changes: 4 additions & 4 deletions crates/stdlib/src/multiprocessing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ pub(crate) use _multiprocessing::make_module;
#[cfg(windows)]
#[pymodule]
mod _multiprocessing {
use crate::vm::{PyResult, VirtualMachine, function::ArgBytesLike, stdlib::os};
use crate::vm::{PyResult, VirtualMachine, function::ArgBytesLike};
use windows_sys::Win32::Networking::WinSock::{self, SOCKET};

#[pyfunction]
fn closesocket(socket: usize, vm: &VirtualMachine) -> PyResult<()> {
let res = unsafe { WinSock::closesocket(socket as SOCKET) };
if res == 0 {
Err(os::errno_err(vm))
Err(vm.new_last_os_error())
} else {
Ok(())
}
Expand All @@ -22,7 +22,7 @@ mod _multiprocessing {
let n_read =
unsafe { WinSock::recv(socket as SOCKET, buf.as_mut_ptr() as *mut _, size as i32, 0) };
if n_read < 0 {
Err(os::errno_err(vm))
Err(vm.new_last_os_error())
} else {
Ok(n_read)
}
Expand All @@ -34,7 +34,7 @@ mod _multiprocessing {
WinSock::send(socket as SOCKET, b.as_ptr() as *const _, b.len() as i32, 0)
});
if ret < 0 {
Err(os::errno_err(vm))
Err(vm.new_last_os_error())
} else {
Ok(ret)
}
Expand Down
15 changes: 7 additions & 8 deletions crates/stdlib/src/overlapped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ mod _overlapped {
common::lock::PyMutex,
convert::{ToPyException, ToPyObject},
protocol::PyBuffer,
stdlib::os::errno_err,
types::Constructor,
};
use windows_sys::Win32::{
Expand Down Expand Up @@ -256,7 +255,7 @@ mod _overlapped {
};
// CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between
if ret == 0 && unsafe { GetLastError() } != Foundation::ERROR_NOT_FOUND {
return Err(errno_err(vm));
return Err(vm.new_last_os_error());
}
Ok(())
}
Expand All @@ -276,7 +275,7 @@ mod _overlapped {
) as isize
};
if event == NULL {
return Err(errno_err(vm));
return Err(vm.new_last_os_error());
}
}

Expand Down Expand Up @@ -318,7 +317,7 @@ mod _overlapped {
) as isize
};
if r as usize == 0 {
return Err(errno_err(vm));
return Err(vm.new_last_os_error());
}
Ok(r)
}
Expand Down Expand Up @@ -346,7 +345,7 @@ mod _overlapped {
if err == Foundation::WAIT_TIMEOUT {
return Ok(vm.ctx.none());
} else {
return Err(errno_err(vm));
return Err(vm.new_last_os_error());
}
}

Expand Down Expand Up @@ -387,7 +386,7 @@ mod _overlapped {
) as isize
};
if event == NULL {
return Err(errno_err(vm));
return Err(vm.new_last_os_error());
}
Ok(event)
}
Expand All @@ -396,7 +395,7 @@ mod _overlapped {
fn SetEvent(handle: u64, vm: &VirtualMachine) -> PyResult<()> {
let ret = unsafe { windows_sys::Win32::System::Threading::SetEvent(u64_to_handle(handle)) };
if ret == 0 {
return Err(errno_err(vm));
return Err(vm.new_last_os_error());
}
Ok(())
}
Expand All @@ -406,7 +405,7 @@ mod _overlapped {
let ret =
unsafe { windows_sys::Win32::System::Threading::ResetEvent(u64_to_handle(handle)) };
if ret == 0 {
return Err(errno_err(vm));
return Err(vm.new_last_os_error());
}
Ok(())
}
Expand Down
3 changes: 1 addition & 2 deletions crates/stdlib/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ mod resource {
use crate::vm::{
PyObject, PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine,
convert::{ToPyException, ToPyObject},
stdlib::os,
types::PyStructSequence,
};
use std::{io, mem};
Expand Down Expand Up @@ -161,7 +160,7 @@ mod resource {
let rlimit = unsafe {
let mut rlimit = mem::MaybeUninit::<libc::rlimit>::uninit();
if libc::getrlimit(resource as _, rlimit.as_mut_ptr()) == -1 {
return Err(os::errno_err(vm));
return Err(vm.new_last_errno_error());
}
rlimit.assume_init()
};
Expand Down
10 changes: 5 additions & 5 deletions crates/stdlib/src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1547,7 +1547,7 @@ mod _socket {
)
};
if ret < 0 {
return Err(crate::common::os::last_os_error().into());
return Err(crate::common::os::errno_io_error().into());
}
Ok(vm.ctx.new_int(flag).into())
} else {
Expand All @@ -1568,7 +1568,7 @@ mod _socket {
)
};
if ret < 0 {
return Err(crate::common::os::last_os_error().into());
return Err(crate::common::os::errno_io_error().into());
}
buf.truncate(buflen as usize);
Ok(vm.ctx.new_bytes(buf).into())
Expand Down Expand Up @@ -1609,7 +1609,7 @@ mod _socket {
}
};
if ret < 0 {
Err(crate::common::os::last_os_error().into())
Err(crate::common::os::errno_io_error().into())
} else {
Ok(())
}
Expand Down Expand Up @@ -2158,7 +2158,7 @@ mod _socket {
let mut buf = [0; c::IF_NAMESIZE + 1];
let ret = unsafe { c::if_indextoname(index, buf.as_mut_ptr()) };
if ret.is_null() {
Err(crate::vm::stdlib::os::errno_err(vm))
Err(vm.new_last_errno_error())
} else {
let buf = unsafe { ffi::CStr::from_ptr(buf.as_ptr() as _) };
Ok(buf.to_string_lossy().into_owned())
Expand Down Expand Up @@ -2488,7 +2488,7 @@ mod _socket {
use windows_sys::Win32::Networking::WinSock::closesocket as close;
let ret = unsafe { close(x as _) };
if ret < 0 {
let err = crate::common::os::last_os_error();
let err = std::io::Error::last_os_error();
if err.raw_os_error() != Some(errcode!(ECONNRESET)) {
return Err(err);
}
Expand Down
3 changes: 1 addition & 2 deletions crates/vm/src/stdlib/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3991,8 +3991,7 @@ mod _io {
// check file descriptor validity
#[cfg(unix)]
if let Ok(crate::ospath::OsPathOrFd::Fd(fd)) = file.clone().try_into_value(vm) {
nix::fcntl::fcntl(fd, nix::fcntl::F_GETFD)
.map_err(|_| crate::stdlib::os::errno_err(vm))?;
nix::fcntl::fcntl(fd, nix::fcntl::F_GETFD).map_err(|_| vm.new_last_errno_error())?;
}

// Construct a FileIO (subclass of RawIOBase)
Expand Down
5 changes: 2 additions & 3 deletions crates/vm/src/stdlib/msvcrt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ mod msvcrt {
builtins::{PyBytes, PyStrRef},
common::{crt_fd, suppress_iph},
convert::IntoPyException,
stdlib::os::errno_err,
};
use itertools::Itertools;
use std::os::windows::io::AsRawHandle;
Expand Down Expand Up @@ -82,7 +81,7 @@ mod msvcrt {
fn setmode(fd: crt_fd::Borrowed<'_>, flags: i32, vm: &VirtualMachine) -> PyResult<i32> {
let flags = unsafe { suppress_iph!(_setmode(fd, flags)) };
if flags == -1 {
Err(errno_err(vm))
Err(vm.new_last_errno_error())
} else {
Ok(flags)
}
Expand All @@ -92,7 +91,7 @@ mod msvcrt {
fn open_osfhandle(handle: isize, flags: i32, vm: &VirtualMachine) -> PyResult<i32> {
let ret = unsafe { suppress_iph!(libc::open_osfhandle(handle, flags)) };
if ret == -1 {
Err(errno_err(vm))
Err(vm.new_last_errno_error())
} else {
Ok(ret)
}
Expand Down
Loading
Loading