Skip to content

Commit ecc13e6

Browse files
committed
use posix error messages under 127
1 parent 49522e7 commit ecc13e6

File tree

1 file changed

+25
-17
lines changed
  • crates/vm/src/stdlib

1 file changed

+25
-17
lines changed

crates/vm/src/stdlib/io.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,33 @@ pub use _io::{OpenArgs, io_open as open};
2020
impl ToPyException for std::io::Error {
2121
fn to_pyexception(&self, vm: &VirtualMachine) -> PyBaseExceptionRef {
2222
let errno = self.posix_errno();
23-
let msg = self.to_string();
24-
#[allow(clippy::let_and_return)]
25-
let exc = vm.new_errno_error(errno, msg);
2623

2724
#[cfg(windows)]
28-
{
29-
use crate::object::AsObject;
30-
let winerror = if let Some(winerror) = self.raw_os_error() {
31-
vm.new_pyobj(winerror)
32-
} else {
33-
vm.ctx.none()
34-
};
35-
36-
// FIXME: manual setup winerror due to lack of OSError.__init__ support
37-
exc.as_object()
38-
.set_attr("winerror", vm.new_pyobj(winerror), vm)
39-
.unwrap();
40-
}
41-
exc
25+
let msg = {
26+
// On Windows, use C runtime's strerror for POSIX errno values
27+
// For Windows-specific error codes, fall back to FormatMessage
28+
29+
// UCRT's strerror returns "Unknown error" for invalid errno values
30+
// Use strerror for POSIX errno range, fall back to FormatMessage otherwise
31+
// Windows UCRT defines errno values 1-42 plus some more up to ~127
32+
const MAX_POSIX_ERRNO: i32 = 127;
33+
if errno > 0 && errno <= MAX_POSIX_ERRNO {
34+
// Safety: strerror returns a valid C string
35+
let ptr = unsafe { libc::strerror(errno) };
36+
if !ptr.is_null() {
37+
let msg = unsafe { std::ffi::CStr::from_ptr(ptr) }.to_string_lossy();
38+
// Check if strerror returned a valid message (not "Unknown error")
39+
if !msg.starts_with("Unknown error") {
40+
return vm.new_errno_error(errno, msg.into_owned());
41+
}
42+
}
43+
}
44+
// For Windows-specific errors or unknown errno, use FormatMessage
45+
self.to_string()
46+
};
47+
#[cfg(not(windows))]
48+
let msg = self.to_string();
49+
vm.new_errno_error(errno, msg)
4250
}
4351
}
4452

0 commit comments

Comments
 (0)