mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
Fix OSError.winerror and errno/winerror converions
This commit is contained in:
1 parent
79e7015a32
commit
d57287b89b
15 files changed
+234
-169
No files matched your search
Generated
+1
@@ -2063,6 +2063,7 @@ dependencies = [
|
||||
"siphasher",
|
||||
"volatile",
|
||||
"widestring",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
Vendored
-1
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -117,7 +117,7 @@ features = [
|
||||
]
|
||||
|
||||
[target.'cfg(windows)'.dependencies.windows-sys]
|
||||
version = "0.52.0"
|
||||
workspace = true
|
||||
features = [
|
||||
"Win32_Networking_WinSock",
|
||||
"Win32_NetworkManagement_IpHelper",
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)]
|
||||
|
||||
Reference in new issue
Block a user