Skip to content

Commit 301b4d6

Browse files
committed
Handle EINTR retry in os.write() (PEP 475)
Add EINTR retry loop to os.write(), matching the existing pattern in os.read() and os.readinto(). Remove the expectedFailure marker from test_write in _test_eintr.py.
1 parent 8c01615 commit 301b4d6

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

Lib/test/_test_eintr.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ def test_readinto(self):
163163
self.assertEqual(os.readinto(fd, buffer), len(expected))
164164
self.assertEqual(buffer, expected)
165165

166-
@unittest.expectedFailure # TODO: RUSTPYTHON; InterruptedError: [Errno 4] Interrupted system call
167166
def test_write(self):
168167
rd, wr = os.pipe()
169168
self.addCleanup(os.close, wr)

crates/vm/src/stdlib/os.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,17 @@ pub(super) mod _os {
325325
fd: crt_fd::Borrowed<'_>,
326326
data: ArgBytesLike,
327327
vm: &VirtualMachine,
328-
) -> io::Result<usize> {
329-
data.with_ref(|b| vm.allow_threads(|| crt_fd::write(fd, b)))
328+
) -> PyResult<usize> {
329+
data.with_ref(|b| loop {
330+
match vm.allow_threads(|| crt_fd::write(fd, b)) {
331+
Ok(n) => return Ok(n),
332+
Err(e) if e.raw_os_error() == Some(libc::EINTR) => {
333+
vm.check_signals()?;
334+
continue;
335+
}
336+
Err(e) => return Err(e.into_pyexception(vm)),
337+
}
338+
})
330339
}
331340

332341
#[cfg(not(windows))]

0 commit comments

Comments
 (0)