Skip to content

Commit 14232ad

Browse files
authored
new_last_{os,errno}_error (RustPython#6381)
* new_last_{os,errno}_error * Remove os::errno_err * enable ssl multithread test
1 parent f723974 commit 14232ad

File tree

21 files changed

+158
-139
lines changed

21 files changed

+158
-139
lines changed

Lib/test/test_os.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,12 +2428,10 @@ def test_ftruncate(self):
24282428
self.check(os.ftruncate, 0)
24292429
self.check_bool(os.truncate, 0)
24302430

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

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

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

2459-
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
24602456
@support.requires_subprocess()
24612457
def test_inheritable(self):
24622458
self.check(os.get_inheritable)

Lib/test/test_ssl.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2891,7 +2891,6 @@ def test_echo(self):
28912891
'Cannot create a client socket with a PROTOCOL_TLS_SERVER context',
28922892
str(e.exception))
28932893

2894-
@unittest.skip("TODO: RUSTPYTHON; Flaky on windows")
28952894
@unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled")
28962895
def test_ssl_in_multiple_threads(self):
28972896
# See GH-124984: OpenSSL is not thread safe.

Lib/test/test_support.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ def test_temp_cwd__name_none(self):
310310
def test_sortdict(self):
311311
self.assertEqual(support.sortdict({3:3, 2:2, 1:1}), "{1: 1, 2: 2, 3: 3}")
312312

313-
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; actual c fds on windows")
314313
def test_make_bad_fd(self):
315314
fd = os_helper.make_bad_fd()
316315
with self.assertRaises(OSError) as cm:

crates/common/src/crt_fd.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ pub type Raw = i32;
3535
#[inline]
3636
fn cvt<I: num_traits::PrimInt>(ret: I) -> io::Result<I> {
3737
if ret < I::zero() {
38-
Err(crate::os::last_os_error())
38+
// CRT functions set errno, not GetLastError(), so use errno_io_error
39+
Err(crate::os::errno_io_error())
3940
} else {
4041
Ok(ret)
4142
}
@@ -345,7 +346,8 @@ pub fn as_handle(fd: Borrowed<'_>) -> io::Result<BorrowedHandle<'_>> {
345346
}
346347
let handle = unsafe { suppress_iph!(_get_osfhandle(fd)) };
347348
if handle as HANDLE == INVALID_HANDLE_VALUE {
348-
Err(crate::os::last_os_error())
349+
// _get_osfhandle is a CRT function that sets errno, not GetLastError()
350+
Err(crate::os::errno_io_error())
349351
} else {
350352
Ok(unsafe { BorrowedHandle::borrow_raw(handle as _) })
351353
}

crates/common/src/fileutils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn fstat(fd: crate::crt_fd::Borrowed<'_>) -> std::io::Result<StatStruct> {
1313
unsafe {
1414
let ret = libc::fstat(fd.as_raw(), stat.as_mut_ptr());
1515
if ret == -1 {
16-
Err(crate::os::last_os_error())
16+
Err(crate::os::errno_io_error())
1717
} else {
1818
Ok(stat.assume_init())
1919
}

crates/common/src/os.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,22 @@ impl ErrorExt for io::Error {
1919
}
2020
}
2121

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

3931
#[cfg(not(windows))]
40-
pub fn last_os_error() -> io::Error {
41-
io::Error::last_os_error()
32+
pub fn errno_io_error() -> io::Error {
33+
std::io::Error::last_os_error()
4234
}
4335

4436
#[cfg(windows)]
45-
pub fn last_posix_errno() -> i32 {
37+
pub fn get_errno() -> i32 {
4638
unsafe extern "C" {
4739
fn _get_errno(pValue: *mut i32) -> i32;
4840
}
@@ -52,8 +44,8 @@ pub fn last_posix_errno() -> i32 {
5244
}
5345

5446
#[cfg(not(windows))]
55-
pub fn last_posix_errno() -> i32 {
56-
last_os_error().posix_errno()
47+
pub fn get_errno() -> i32 {
48+
std::io::Error::last_os_error().posix_errno()
5749
}
5850

5951
#[cfg(unix)]

crates/stdlib/src/fcntl.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod fcntl {
88
PyResult, VirtualMachine,
99
builtins::PyIntRef,
1010
function::{ArgMemoryBuffer, ArgStrOrBytesLike, Either, OptionalArg},
11-
stdlib::{io, os},
11+
stdlib::io,
1212
};
1313

1414
// TODO: supply these from <asm-generic/fnctl.h> (please file an issue/PR upstream):
@@ -75,7 +75,7 @@ mod fcntl {
7575
}
7676
let ret = unsafe { libc::fcntl(fd, cmd, buf.as_mut_ptr()) };
7777
if ret < 0 {
78-
return Err(os::errno_err(vm));
78+
return Err(vm.new_last_errno_error());
7979
}
8080
return Ok(vm.ctx.new_bytes(buf[..arg_len].to_vec()).into());
8181
}
@@ -84,7 +84,7 @@ mod fcntl {
8484
};
8585
let ret = unsafe { libc::fcntl(fd, cmd, int as i32) };
8686
if ret < 0 {
87-
return Err(os::errno_err(vm));
87+
return Err(vm.new_last_errno_error());
8888
}
8989
Ok(vm.new_pyobj(ret))
9090
}
@@ -117,7 +117,7 @@ mod fcntl {
117117
let ret =
118118
unsafe { libc::ioctl(fd, request as _, arg_buf.as_mut_ptr()) };
119119
if ret < 0 {
120-
return Err(os::errno_err(vm));
120+
return Err(vm.new_last_errno_error());
121121
}
122122
return Ok(vm.ctx.new_int(ret).into());
123123
}
@@ -128,14 +128,14 @@ mod fcntl {
128128
};
129129
let ret = unsafe { libc::ioctl(fd, request as _, buf.as_mut_ptr()) };
130130
if ret < 0 {
131-
return Err(os::errno_err(vm));
131+
return Err(vm.new_last_errno_error());
132132
}
133133
Ok(vm.ctx.new_bytes(buf[..buf_len].to_vec()).into())
134134
}
135135
Either::B(i) => {
136136
let ret = unsafe { libc::ioctl(fd, request as _, i) };
137137
if ret < 0 {
138-
return Err(os::errno_err(vm));
138+
return Err(vm.new_last_errno_error());
139139
}
140140
Ok(vm.ctx.new_int(ret).into())
141141
}
@@ -149,7 +149,7 @@ mod fcntl {
149149
let ret = unsafe { libc::flock(fd, operation) };
150150
// TODO: add support for platforms that don't have a builtin `flock` syscall
151151
if ret < 0 {
152-
return Err(os::errno_err(vm));
152+
return Err(vm.new_last_errno_error());
153153
}
154154
Ok(vm.ctx.new_int(ret).into())
155155
}
@@ -209,7 +209,7 @@ mod fcntl {
209209
)
210210
};
211211
if ret < 0 {
212-
return Err(os::errno_err(vm));
212+
return Err(vm.new_last_errno_error());
213213
}
214214
Ok(vm.ctx.new_int(ret).into())
215215
}

crates/stdlib/src/multiprocessing.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ pub(crate) use _multiprocessing::make_module;
33
#[cfg(windows)]
44
#[pymodule]
55
mod _multiprocessing {
6-
use crate::vm::{PyResult, VirtualMachine, function::ArgBytesLike, stdlib::os};
6+
use crate::vm::{PyResult, VirtualMachine, function::ArgBytesLike};
77
use windows_sys::Win32::Networking::WinSock::{self, SOCKET};
88

99
#[pyfunction]
1010
fn closesocket(socket: usize, vm: &VirtualMachine) -> PyResult<()> {
1111
let res = unsafe { WinSock::closesocket(socket as SOCKET) };
1212
if res == 0 {
13-
Err(os::errno_err(vm))
13+
Err(vm.new_last_os_error())
1414
} else {
1515
Ok(())
1616
}
@@ -22,7 +22,7 @@ mod _multiprocessing {
2222
let n_read =
2323
unsafe { WinSock::recv(socket as SOCKET, buf.as_mut_ptr() as *mut _, size as i32, 0) };
2424
if n_read < 0 {
25-
Err(os::errno_err(vm))
25+
Err(vm.new_last_os_error())
2626
} else {
2727
Ok(n_read)
2828
}
@@ -34,7 +34,7 @@ mod _multiprocessing {
3434
WinSock::send(socket as SOCKET, b.as_ptr() as *const _, b.len() as i32, 0)
3535
});
3636
if ret < 0 {
37-
Err(os::errno_err(vm))
37+
Err(vm.new_last_os_error())
3838
} else {
3939
Ok(ret)
4040
}

crates/stdlib/src/overlapped.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ mod _overlapped {
1313
common::lock::PyMutex,
1414
convert::{ToPyException, ToPyObject},
1515
protocol::PyBuffer,
16-
stdlib::os::errno_err,
1716
types::Constructor,
1817
};
1918
use windows_sys::Win32::{
@@ -256,7 +255,7 @@ mod _overlapped {
256255
};
257256
// CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between
258257
if ret == 0 && unsafe { GetLastError() } != Foundation::ERROR_NOT_FOUND {
259-
return Err(errno_err(vm));
258+
return Err(vm.new_last_os_error());
260259
}
261260
Ok(())
262261
}
@@ -276,7 +275,7 @@ mod _overlapped {
276275
) as isize
277276
};
278277
if event == NULL {
279-
return Err(errno_err(vm));
278+
return Err(vm.new_last_os_error());
280279
}
281280
}
282281

@@ -318,7 +317,7 @@ mod _overlapped {
318317
) as isize
319318
};
320319
if r as usize == 0 {
321-
return Err(errno_err(vm));
320+
return Err(vm.new_last_os_error());
322321
}
323322
Ok(r)
324323
}
@@ -346,7 +345,7 @@ mod _overlapped {
346345
if err == Foundation::WAIT_TIMEOUT {
347346
return Ok(vm.ctx.none());
348347
} else {
349-
return Err(errno_err(vm));
348+
return Err(vm.new_last_os_error());
350349
}
351350
}
352351

@@ -387,7 +386,7 @@ mod _overlapped {
387386
) as isize
388387
};
389388
if event == NULL {
390-
return Err(errno_err(vm));
389+
return Err(vm.new_last_os_error());
391390
}
392391
Ok(event)
393392
}
@@ -396,7 +395,7 @@ mod _overlapped {
396395
fn SetEvent(handle: u64, vm: &VirtualMachine) -> PyResult<()> {
397396
let ret = unsafe { windows_sys::Win32::System::Threading::SetEvent(u64_to_handle(handle)) };
398397
if ret == 0 {
399-
return Err(errno_err(vm));
398+
return Err(vm.new_last_os_error());
400399
}
401400
Ok(())
402401
}
@@ -406,7 +405,7 @@ mod _overlapped {
406405
let ret =
407406
unsafe { windows_sys::Win32::System::Threading::ResetEvent(u64_to_handle(handle)) };
408407
if ret == 0 {
409-
return Err(errno_err(vm));
408+
return Err(vm.new_last_os_error());
410409
}
411410
Ok(())
412411
}

crates/stdlib/src/resource.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ mod resource {
77
use crate::vm::{
88
PyObject, PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine,
99
convert::{ToPyException, ToPyObject},
10-
stdlib::os,
1110
types::PyStructSequence,
1211
};
1312
use std::{io, mem};
@@ -161,7 +160,7 @@ mod resource {
161160
let rlimit = unsafe {
162161
let mut rlimit = mem::MaybeUninit::<libc::rlimit>::uninit();
163162
if libc::getrlimit(resource as _, rlimit.as_mut_ptr()) == -1 {
164-
return Err(os::errno_err(vm));
163+
return Err(vm.new_last_errno_error());
165164
}
166165
rlimit.assume_init()
167166
};

0 commit comments

Comments
 (0)