Fix OSError.winerror and errno/winerror converions

This commit is contained in:
Jeong, YunWon authored and Jeong, YunWon committed 2024-04-19 04:56:25 +09:00
1 parent 79e7015a32
commit d57287b89b
15 files changed
+234 -169

No files matched your search

Generated
+1
View File
@@ -2063,6 +2063,7 @@ dependencies = [
"siphasher",
"volatile",
"widestring",
"windows-sys 0.52.0",
]
[[package]]
+1
View File
@@ -81,6 +81,7 @@ thiserror = "1.0"
thread_local = "1.1.4"
unicode_names2 = "1.1.0"
widestring = "1.1.0"
windows-sys = "0.52.0"
[features]
default = ["threading", "stdlib", "zlib", "importlib"]
-1
View File
@@ -1418,7 +1418,6 @@ class TestTemporaryDirectory(BaseTestCase):
with open(os.path.join(path, "test%d.txt" % i), "wb") as f:
f.write(b"Hello world!")
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def test_mkdtemp_failure(self):
# Check no additional exception if mkdtemp fails
# Previously would raise AttributeError instead
+4
View File
@@ -35,3 +35,7 @@ volatile = "0.3"
[target.'cfg(windows)'.dependencies]
widestring = { workspace = true }
windows-sys = { workspace = true, features = [
"Win32_Foundation",
"Win32_Networking_WinSock",
] }
+3 -22
View File
@@ -23,7 +23,7 @@ pub type Offset = libc::c_longlong;
#[inline]
fn cvt<T, I: num_traits::PrimInt>(ret: I, f: impl FnOnce(I) -> T) -> io::Result<T> {
if ret < I::zero() {
Err(crate::os::errno())
Err(crate::os::last_os_error())
} else {
Ok(f(ret))
}
@@ -86,7 +86,7 @@ impl Fd {
}
}
impl io::Write for &Fd {
impl io::Write for Fd {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let count = cmp::min(buf.len(), MAX_RW);
cvt(
@@ -101,19 +101,7 @@ impl io::Write for &Fd {
}
}
impl io::Write for Fd {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
(&*self).write(buf)
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
(&*self).flush()
}
}
impl io::Read for &Fd {
impl io::Read for Fd {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let count = cmp::min(buf.len(), MAX_RW);
cvt(
@@ -122,10 +110,3 @@ impl io::Read for &Fd {
)
}
}
impl io::Read for Fd {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
(&*self).read(buf)
}
}
+173 -5
View File
@@ -2,26 +2,64 @@
use std::{io, str::Utf8Error};
pub trait ErrorExt {
fn posix_errno(&self) -> i32;
}
impl ErrorExt for io::Error {
#[cfg(not(windows))]
fn posix_errno(&self) -> i32 {
self.raw_os_error().unwrap_or(0)
}
#[cfg(windows)]
fn posix_errno(&self) -> i32 {
let winerror = self.raw_os_error().unwrap_or(0);
winerror_to_errno(winerror)
}
}
#[cfg(windows)]
pub fn errno() -> io::Error {
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) {
extern "C" {
fn _get_errno(pValue: *mut i32) -> i32;
}
let mut e = 0;
unsafe { suppress_iph!(_get_errno(&mut e)) };
io::Error::from_raw_os_error(e)
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
}
}
#[cfg(not(windows))]
pub fn errno() -> io::Error {
pub fn last_os_error() -> io::Error {
io::Error::last_os_error()
}
#[cfg(windows)]
pub fn last_posix_errno() -> i32 {
let err = io::Error::last_os_error();
if err.raw_os_error() == Some(0) {
extern "C" {
fn _get_errno(pValue: *mut i32) -> i32;
}
let mut errno = 0;
unsafe { suppress_iph!(_get_errno(&mut errno)) };
errno
} else {
err.posix_errno()
}
}
#[cfg(not(windows))]
pub fn last_posix_errno() -> i32 {
last_os_error().posix_errno()
}
#[cfg(unix)]
pub fn bytes_as_osstr(b: &[u8]) -> Result<&std::ffi::OsStr, Utf8Error> {
use std::os::unix::ffi::OsStrExt;
@@ -37,3 +75,133 @@ pub fn bytes_as_osstr(b: &[u8]) -> Result<&std::ffi::OsStr, Utf8Error> {
pub use std::os::unix::ffi;
#[cfg(target_os = "wasi")]
pub use std::os::wasi::ffi;
#[cfg(windows)]
pub fn errno_to_winerror(errno: i32) -> i32 {
use libc::*;
use windows_sys::Win32::Foundation::*;
let winerror = match errno {
ENOENT => ERROR_FILE_NOT_FOUND,
E2BIG => ERROR_BAD_ENVIRONMENT,
ENOEXEC => ERROR_BAD_FORMAT,
EBADF => ERROR_INVALID_HANDLE,
ECHILD => ERROR_WAIT_NO_CHILDREN,
EAGAIN => ERROR_NO_PROC_SLOTS,
ENOMEM => ERROR_NOT_ENOUGH_MEMORY,
EACCES => ERROR_ACCESS_DENIED,
EEXIST => ERROR_FILE_EXISTS,
EXDEV => ERROR_NOT_SAME_DEVICE,
ENOTDIR => ERROR_DIRECTORY,
EMFILE => ERROR_TOO_MANY_OPEN_FILES,
ENOSPC => ERROR_DISK_FULL,
EPIPE => ERROR_BROKEN_PIPE,
ENOTEMPTY => ERROR_DIR_NOT_EMPTY,
EILSEQ => ERROR_NO_UNICODE_TRANSLATION,
EINVAL => ERROR_INVALID_FUNCTION,
_ => ERROR_INVALID_FUNCTION,
};
winerror as _
}
// winerror: https://learn.microsoft.com/windows/win32/debug/system-error-codes--0-499-
// errno: https://learn.microsoft.com/cpp/c-runtime-library/errno-constants?view=msvc-170
#[cfg(windows)]
pub fn winerror_to_errno(winerror: i32) -> i32 {
use libc::*;
use windows_sys::Win32::{
Foundation::*,
Networking::WinSock::{WSAEACCES, WSAEBADF, WSAEFAULT, WSAEINTR, WSAEINVAL, WSAEMFILE},
};
// Unwrap FACILITY_WIN32 HRESULT errors.
// if ((winerror & 0xFFFF0000) == 0x80070000) {
// winerror &= 0x0000FFFF;
// }
// Winsock error codes (10000-11999) are errno values.
if (10000..12000).contains(&winerror) {
match winerror {
WSAEINTR | WSAEBADF | WSAEACCES | WSAEFAULT | WSAEINVAL | WSAEMFILE => {
// Winsock definitions of errno values. See WinSock2.h
return winerror - 10000;
}
_ => return winerror as _,
}
}
#[allow(non_upper_case_globals)]
match winerror as u32 {
ERROR_FILE_NOT_FOUND
| ERROR_PATH_NOT_FOUND
| ERROR_INVALID_DRIVE
| ERROR_NO_MORE_FILES
| ERROR_BAD_NETPATH
| ERROR_BAD_NET_NAME
| ERROR_BAD_PATHNAME
| ERROR_FILENAME_EXCED_RANGE => ENOENT,
ERROR_BAD_ENVIRONMENT => E2BIG,
ERROR_BAD_FORMAT
| ERROR_INVALID_STARTING_CODESEG
| ERROR_INVALID_STACKSEG
| ERROR_INVALID_MODULETYPE
| ERROR_INVALID_EXE_SIGNATURE
| ERROR_EXE_MARKED_INVALID
| ERROR_BAD_EXE_FORMAT
| ERROR_ITERATED_DATA_EXCEEDS_64k
| ERROR_INVALID_MINALLOCSIZE
| ERROR_DYNLINK_FROM_INVALID_RING
| ERROR_IOPL_NOT_ENABLED
| ERROR_INVALID_SEGDPL
| ERROR_AUTODATASEG_EXCEEDS_64k
| ERROR_RING2SEG_MUST_BE_MOVABLE
| ERROR_RELOC_CHAIN_XEEDS_SEGLIM
| ERROR_INFLOOP_IN_RELOC_CHAIN => ENOEXEC,
ERROR_INVALID_HANDLE | ERROR_INVALID_TARGET_HANDLE | ERROR_DIRECT_ACCESS_HANDLE => EBADF,
ERROR_WAIT_NO_CHILDREN | ERROR_CHILD_NOT_COMPLETE => ECHILD,
ERROR_NO_PROC_SLOTS | ERROR_MAX_THRDS_REACHED | ERROR_NESTING_NOT_ALLOWED => EAGAIN,
ERROR_ARENA_TRASHED
| ERROR_NOT_ENOUGH_MEMORY
| ERROR_INVALID_BLOCK
| ERROR_NOT_ENOUGH_QUOTA => ENOMEM,
ERROR_ACCESS_DENIED
| ERROR_CURRENT_DIRECTORY
| ERROR_WRITE_PROTECT
| ERROR_BAD_UNIT
| ERROR_NOT_READY
| ERROR_BAD_COMMAND
| ERROR_CRC
| ERROR_BAD_LENGTH
| ERROR_SEEK
| ERROR_NOT_DOS_DISK
| ERROR_SECTOR_NOT_FOUND
| ERROR_OUT_OF_PAPER
| ERROR_WRITE_FAULT
| ERROR_READ_FAULT
| ERROR_GEN_FAILURE
| ERROR_SHARING_VIOLATION
| ERROR_LOCK_VIOLATION
| ERROR_WRONG_DISK
| ERROR_SHARING_BUFFER_EXCEEDED
| ERROR_NETWORK_ACCESS_DENIED
| ERROR_CANNOT_MAKE
| ERROR_FAIL_I24
| ERROR_DRIVE_LOCKED
| ERROR_SEEK_ON_DEVICE
| ERROR_NOT_LOCKED
| ERROR_LOCK_FAILED
| 35 => EACCES,
ERROR_FILE_EXISTS | ERROR_ALREADY_EXISTS => EEXIST,
ERROR_NOT_SAME_DEVICE => EXDEV,
ERROR_DIRECTORY => ENOTDIR,
ERROR_TOO_MANY_OPEN_FILES => EMFILE,
ERROR_DISK_FULL => ENOSPC,
ERROR_BROKEN_PIPE | ERROR_NO_DATA => EPIPE,
ERROR_DIR_NOT_EMPTY => ENOTEMPTY,
ERROR_NO_UNICODE_TRANSLATION => EILSEQ,
ERROR_INVALID_FUNCTION
| ERROR_INVALID_ACCESS
| ERROR_INVALID_DATA
| ERROR_INVALID_PARAMETER
| ERROR_NEGATIVE_SEEK => EINVAL,
_ => EINVAL,
}
}
+1 -1
View File
@@ -117,7 +117,7 @@ features = [
]
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.52.0"
workspace = true
features = [
"Win32_Networking_WinSock",
"Win32_NetworkManagement_IpHelper",
+7 -9
View File
@@ -13,6 +13,7 @@ mod _socket {
use crate::common::lock::{PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard};
use crate::vm::{
builtins::{PyBaseExceptionRef, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
common::os::ErrorExt,
convert::{IntoPyException, ToPyObject, TryFromBorrowedObject, TryFromObject},
function::{ArgBytesLike, ArgMemoryBuffer, Either, FsPath, OptionalArg, OptionalOption},
types::{DefaultConstructor, Initializer, Representable},
@@ -1018,7 +1019,7 @@ mod _socket {
let sock = self.sock()?;
let err = sock.take_error()?;
match err {
Some(e) if e.raw_os_error() == Some(libc::EISCONN) => Ok(()),
Some(e) if e.posix_errno() == libc::EISCONN => Ok(()),
Some(e) => Err(e),
// TODO: is this accurate?
None => Ok(()),
@@ -1408,7 +1409,7 @@ mod _socket {
)
};
if ret < 0 {
return Err(crate::common::os::errno().into());
return Err(crate::common::os::last_os_error().into());
}
Ok(vm.ctx.new_int(flag).into())
} else {
@@ -1429,7 +1430,7 @@ mod _socket {
)
};
if ret < 0 {
return Err(crate::common::os::errno().into());
return Err(crate::common::os::last_os_error().into());
}
buf.truncate(buflen as usize);
Ok(vm.ctx.new_bytes(buf).into())
@@ -1470,7 +1471,7 @@ mod _socket {
}
};
if ret < 0 {
Err(crate::common::os::errno().into())
Err(crate::common::os::last_os_error().into())
} else {
Ok(())
}
@@ -1694,10 +1695,7 @@ mod _socket {
fn errno(self) -> PyResult<i32> {
match self {
Self::Timeout => Ok(errcode!(EWOULDBLOCK)),
Self::Io(err) => {
// TODO: just unwrap()?
Ok(err.raw_os_error().unwrap_or(1))
}
Self::Io(err) => Ok(err.posix_errno()),
Self::Py(exc) => Err(exc),
}
}
@@ -2354,7 +2352,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::errno();
let err = crate::common::os::last_os_error();
if err.raw_os_error() != Some(errcode!(ECONNRESET)) {
return Err(err);
}
+1 -1
View File
@@ -680,7 +680,7 @@ mod _ssl {
)
};
if ret != 1 {
let errno = std::io::Error::last_os_error().raw_os_error().unwrap();
let errno = crate::common::os::last_posix_errno();
let err = if errno != 0 {
crate::vm::stdlib::os::errno_err(vm)
} else {
+2 -1
View File
@@ -4,6 +4,7 @@ pub(crate) use self::termios::make_module;
mod termios {
use crate::vm::{
builtins::{PyBaseExceptionRef, PyBytes, PyInt, PyListRef, PyTypeRef},
common::os::ErrorExt,
convert::ToPyObject,
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
};
@@ -259,7 +260,7 @@ mod termios {
vm.new_exception(
error_type(vm),
vec![
err.raw_os_error().to_pyobject(vm),
err.posix_errno().to_pyobject(vm),
vm.ctx.new_str(err.to_string()).into(),
],
)
+1 -1
View File
@@ -119,7 +119,7 @@ features = [
]
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.52.0"
workspace = true
features = [
"Win32_Foundation",
"Win32_Networking_WinSock",
+10 -116
View File
@@ -800,10 +800,8 @@ impl ExceptionZoo {
// second exception filename
"filename2" => ctx.none(),
});
// TODO: this isn't really accurate
#[cfg(windows)]
excs.os_error
.set_str_attr("winerror", errno_getter.clone(), ctx);
excs.os_error.set_str_attr("winerror", ctx.none(), ctx);
extend_exception!(PyBlockingIOError, ctx, excs.blocking_io_error);
extend_exception!(PyChildProcessError, ctx, excs.child_process_error);
@@ -1013,14 +1011,9 @@ impl<C> ToPyException for widestring::error::ContainsNul<C> {
}
#[cfg(any(unix, windows, target_os = "wasi"))]
pub(crate) fn raw_os_error_to_exc_type(
errno: i32,
vm: &VirtualMachine,
) -> Option<&'static Py<PyType>> {
pub(crate) fn errno_to_exc_type(errno: i32, vm: &VirtualMachine) -> Option<&'static Py<PyType>> {
use crate::stdlib::errno::errors;
let excs = &vm.ctx.exceptions;
#[cfg(windows)]
let errno = win_error_to_errno(errno as u32);
match errno {
errors::EWOULDBLOCK => Some(excs.blocking_io_error),
errors::EALREADY => Some(excs.blocking_io_error),
@@ -1045,111 +1038,8 @@ pub(crate) fn raw_os_error_to_exc_type(
}
}
#[cfg(windows)]
pub(crate) fn win_error_to_errno(winerror: u32) -> i32 {
use crate::stdlib::errno::errors;
use windows_sys::Win32::Foundation::*;
// Unwrap FACILITY_WIN32 HRESULT errors.
// if ((winerror & 0xFFFF0000) == 0x80070000) {
// winerror &= 0x0000FFFF;
// }
// Winsock error codes (10000-11999) are errno values.
// if winerror >= 10000 && winerror < 12000 {
// match winerror {
// WSAEINTR | WSAEBADF | WSAEACCES | WSAEFAULT | WSAEINVAL | WSAEMFILE => {
// // Winsock definitions of errno values. See WinSock2.h
// return winerror - 10000;
// },
// _ => return winerror,
// }
// }
#[allow(non_upper_case_globals)]
match winerror {
ERROR_FILE_NOT_FOUND
| ERROR_PATH_NOT_FOUND
| ERROR_INVALID_DRIVE
| ERROR_NO_MORE_FILES
| ERROR_BAD_NETPATH
| ERROR_BAD_NET_NAME
| ERROR_BAD_PATHNAME
| ERROR_FILENAME_EXCED_RANGE => errors::ENOENT,
ERROR_BAD_ENVIRONMENT => errors::E2BIG,
ERROR_BAD_FORMAT
| ERROR_INVALID_STARTING_CODESEG
| ERROR_INVALID_STACKSEG
| ERROR_INVALID_MODULETYPE
| ERROR_INVALID_EXE_SIGNATURE
| ERROR_EXE_MARKED_INVALID
| ERROR_BAD_EXE_FORMAT
| ERROR_ITERATED_DATA_EXCEEDS_64k
| ERROR_INVALID_MINALLOCSIZE
| ERROR_DYNLINK_FROM_INVALID_RING
| ERROR_IOPL_NOT_ENABLED
| ERROR_INVALID_SEGDPL
| ERROR_AUTODATASEG_EXCEEDS_64k
| ERROR_RING2SEG_MUST_BE_MOVABLE
| ERROR_RELOC_CHAIN_XEEDS_SEGLIM
| ERROR_INFLOOP_IN_RELOC_CHAIN => errors::ENOEXEC,
ERROR_INVALID_HANDLE | ERROR_INVALID_TARGET_HANDLE | ERROR_DIRECT_ACCESS_HANDLE => {
errors::EBADF
}
ERROR_WAIT_NO_CHILDREN | ERROR_CHILD_NOT_COMPLETE => errors::ECHILD,
ERROR_NO_PROC_SLOTS | ERROR_MAX_THRDS_REACHED | ERROR_NESTING_NOT_ALLOWED => errors::EAGAIN,
ERROR_ARENA_TRASHED
| ERROR_NOT_ENOUGH_MEMORY
| ERROR_INVALID_BLOCK
| ERROR_NOT_ENOUGH_QUOTA => errors::ENOMEM,
ERROR_ACCESS_DENIED
| ERROR_CURRENT_DIRECTORY
| ERROR_WRITE_PROTECT
| ERROR_BAD_UNIT
| ERROR_NOT_READY
| ERROR_BAD_COMMAND
| ERROR_CRC
| ERROR_BAD_LENGTH
| ERROR_SEEK
| ERROR_NOT_DOS_DISK
| ERROR_SECTOR_NOT_FOUND
| ERROR_OUT_OF_PAPER
| ERROR_WRITE_FAULT
| ERROR_READ_FAULT
| ERROR_GEN_FAILURE
| ERROR_SHARING_VIOLATION
| ERROR_LOCK_VIOLATION
| ERROR_WRONG_DISK
| ERROR_SHARING_BUFFER_EXCEEDED
| ERROR_NETWORK_ACCESS_DENIED
| ERROR_CANNOT_MAKE
| ERROR_FAIL_I24
| ERROR_DRIVE_LOCKED
| ERROR_SEEK_ON_DEVICE
| ERROR_NOT_LOCKED
| ERROR_LOCK_FAILED
| 35 => errors::EACCES,
ERROR_FILE_EXISTS | ERROR_ALREADY_EXISTS => errors::EEXIST,
ERROR_NOT_SAME_DEVICE => errors::EXDEV,
ERROR_DIRECTORY => errors::ENOTDIR,
ERROR_TOO_MANY_OPEN_FILES => errors::EMFILE,
ERROR_DISK_FULL => errors::ENOSPC,
ERROR_BROKEN_PIPE | ERROR_NO_DATA => errors::EPIPE,
ERROR_DIR_NOT_EMPTY => errors::ENOTEMPTY,
ERROR_NO_UNICODE_TRANSLATION => errors::EILSEQ,
ERROR_INVALID_FUNCTION
| ERROR_INVALID_ACCESS
| ERROR_INVALID_DATA
| ERROR_INVALID_PARAMETER
| ERROR_NEGATIVE_SEEK => errors::EINVAL,
_ => errors::EINVAL,
}
}
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
pub(crate) fn raw_os_error_to_exc_type(
_errno: i32,
_vm: &VirtualMachine,
) -> Option<&'static Py<PyType>> {
pub(crate) fn errno_to_exc_type(_errno: i32, _vm: &VirtualMachine) -> Option<&'static Py<PyType>> {
None
}
@@ -1359,7 +1249,7 @@ pub(super) mod types {
errno
.payload_if_subclass::<PyInt>(vm)
.and_then(|errno| errno.try_to_primitive::<i32>(vm).ok())
.and_then(|errno| super::raw_os_error_to_exc_type(errno, vm))
.and_then(|errno| super::errno_to_exc_type(errno, vm))
.and_then(|typ| vm.invoke_exception(typ.to_owned(), args.to_vec()).ok())
} else {
None
@@ -1392,8 +1282,12 @@ pub(super) mod types {
let mut new_args = args;
if (3..=5).contains(&len) {
zelf.set_attr("filename", new_args.args[2].clone(), vm)?;
if len == 5 {
zelf.set_attr("filename2", new_args.args[4].clone(), vm)?;
#[cfg(windows)]
if let Some(winerror) = new_args.args.get(3) {
zelf.set_attr("winerror", winerror.clone(), vm)?;
}
if let Some(filename2) = new_args.args.get(4) {
zelf.set_attr("filename2", filename2.clone(), vm)?;
}
new_args.args.truncate(2);
+26 -8
View File
@@ -10,9 +10,9 @@ cfg_if::cfg_if! {
}
use crate::{
builtins::PyBaseExceptionRef,
builtins::PyModule,
convert::{IntoPyException, ToPyException, ToPyObject},
builtins::{PyBaseExceptionRef, PyModule},
common::os::ErrorExt,
convert::{IntoPyException, ToPyException},
PyObjectRef, PyRef, PyResult, TryFromObject, VirtualMachine,
};
pub use _io::io_open as open;
@@ -28,14 +28,32 @@ impl ToPyException for std::io::Error {
ErrorKind::PermissionDenied => excs.permission_error,
ErrorKind::AlreadyExists => excs.file_exists_error,
ErrorKind::WouldBlock => excs.blocking_io_error,
_ => self
.raw_os_error()
.and_then(|errno| crate::exceptions::raw_os_error_to_exc_type(errno, vm))
_ => crate::exceptions::errno_to_exc_type(self.posix_errno(), vm)
.unwrap_or(excs.os_error),
};
let errno = self.raw_os_error().to_pyobject(vm);
let errno = self.raw_os_error().unwrap_or(0);
let errno_obj = vm.new_pyobj(errno);
#[cfg(windows)]
let (winerror_obj, errno_obj) = {
let winerror = errno;
let winerror_obj = errno_obj.clone();
let errno = crate::common::os::winerror_to_errno(winerror);
(winerror_obj, vm.new_pyobj(errno))
};
let msg = vm.ctx.new_str(self.to_string()).into();
vm.new_exception(exc_type.to_owned(), vec![errno, msg])
#[allow(clippy::let_and_return)]
let exc = vm.new_exception(exc_type.to_owned(), vec![errno_obj, msg]);
#[cfg(windows)]
{
// FIXME: manual setup winerror due to lack of OSError.__init__ support
use crate::object::AsObject;
exc.as_object()
.set_attr("winerror", vm.new_pyobj(winerror_obj), vm)
.unwrap();
}
exc
}
}
+2 -2
View File
@@ -14,7 +14,7 @@ pub(crate) mod module {
use crate::builtins::PyListRef;
use crate::{
builtins::{PyDictRef, PyStrRef, PyTupleRef},
common::{crt_fd::Fd, os::errno, suppress_iph},
common::{crt_fd::Fd, os::last_os_error, suppress_iph},
convert::ToPyException,
function::Either,
function::OptionalArg,
@@ -385,7 +385,7 @@ pub(crate) mod module {
Foundation::SetHandleInformation(handle as _, Foundation::HANDLE_FLAG_INHERIT, flags)
};
if res == 0 {
Err(errno())
Err(last_os_error())
} else {
Ok(())
}
+2 -2
View File
@@ -1,7 +1,7 @@
use crate::{
builtins::{PyBaseExceptionRef, PyModule, PySet},
common::crt_fd::Fd,
convert::IntoPyException,
convert::{IntoPyException, ToPyException},
function::{ArgumentError, FromArgs, FsPath, FuncArgs},
AsObject, Py, PyObjectRef, PyPayload, PyResult, TryFromObject, VirtualMachine,
};
@@ -205,7 +205,7 @@ impl IntoPyException for IOErrorBuilder {
/// Convert the error stored in the `errno` variable into an Exception
#[inline]
pub fn errno_err(vm: &VirtualMachine) -> PyBaseExceptionRef {
crate::common::os::errno().into_pyexception(vm)
crate::common::os::last_os_error().to_pyexception(vm)
}
#[allow(dead_code)]