Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Lib/test/_test_eintr.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,15 +452,13 @@ def wait_func(signum):
class SelectEINTRTest(EINTRBaseTest):
""" EINTR tests for the select module. """

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_select(self):
t0 = time.monotonic()
select.select([], [], [], self.sleep_time)
dt = time.monotonic() - t0
self.stop_alarm()
self.check_elapsed_time(dt)

@unittest.skip("TODO: RUSTPYTHON; timed out at the 10 minute mark")
@unittest.skipIf(sys.platform == "darwin",
"poll may fail on macOS; see issue #28087")
@unittest.skipUnless(hasattr(select, 'poll'), 'need select.poll')
Expand Down Expand Up @@ -544,12 +542,10 @@ def _lock(self, lock_func, lock_name):

# Issue 35633: See https://bugs.python.org/issue35633#msg333662
# skip test rather than accept PermissionError from all platforms
@unittest.expectedFailure # TODO: RUSTPYTHON; InterruptedError: [Errno 4] Interrupted system call
@unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError")
def test_lockf(self):
self._lock(fcntl.lockf, "lockf")

@unittest.expectedFailure # TODO: RUSTPYTHON; InterruptedError: [Errno 4] Interrupted system call
def test_flock(self):
self._lock(fcntl.flock, "flock")

Expand Down
3 changes: 0 additions & 3 deletions Lib/test/test_mmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def tearDown(self):
except OSError:
pass

@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'mmap' object has no attribute 'seekable'
def test_basic(self):
# Test mmap module on Unix systems and Windows

Expand Down Expand Up @@ -272,7 +271,6 @@ def test_access_parameter(self):
self.assertRaises(TypeError, m.write_byte, 0)
m.close()

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.skipIf(os.name == 'nt', 'trackfd not present on Windows')
def test_trackfd_parameter(self):
size = 64
Expand Down Expand Up @@ -308,7 +306,6 @@ def test_trackfd_parameter(self):
self.assertEqual(m.closed, True)
self.assertEqual(os.stat(TESTFN).st_size, size)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.skipIf(os.name == 'nt', 'trackfd not present on Windows')
def test_trackfd_neg1(self):
size = 64
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_poll.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ def test_poll_c_limits(self):
self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1)
self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1)

@unittest.skip("TODO: RUSTPYTHON; fd reallocation")
@threading_helper.reap_threads
def test_threaded_poll(self):
r, w = os.pipe()
Expand Down
11 changes: 0 additions & 11 deletions Lib/test/test_pty.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ def write_all(fd, data):

# Marginal testing of pty suite. Cannot do extensive 'do or fail' testing
# because pty code is not too portable.
@unittest.skipIf(getattr(tty, "tcgetwinsize", None) is None, "TODO: RUSTPYTHON; `tty.tcgetwinsize` is required for setUp")
class PtyTest(unittest.TestCase):
def setUp(self):
old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup)
Expand Down Expand Up @@ -195,11 +194,6 @@ def test_openpty(self):
s2 = _readline(master_fd)
self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2))

# skip (not expectedFailure) because the test still forks a real child
# process, which crashes on missing os.login_tty() inside the parallel
# test runner's worker process, corrupting its JSON reporting channel
# ("worker bug", reproducible under --slow-ci -j N; not under plain -m test).
@unittest.skip("TODO: RUSTPYTHON; pty.fork() calls os.login_tty(), which is not implemented")
def test_fork(self):
debug("calling pty.fork()")
pid, master_fd = pty.fork()
Expand Down Expand Up @@ -301,11 +295,6 @@ def test_master_read(self):

self.assertEqual(data, b"")

# skip (not expectedFailure) because the test still forks a real child
# process, which crashes on missing os.login_tty() inside the parallel
# test runner's worker process, corrupting its JSON reporting channel
# ("worker bug", reproducible under --slow-ci -j N; not under plain -m test).
@unittest.skip("TODO: RUSTPYTHON; pty.fork() calls os.login_tty(), which is not implemented")
def test_spawn_doesnt_hang(self):
# gh-140482: Do the test in a pty.fork() child to avoid messing
# with the interactive test runner's terminal settings.
Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ def test_select(self):
@unittest.skipIf(
support.is_emscripten, "Emscripten cannot select a fd multiple times."
)
@unittest.skip("TODO: RUSTPYTHON timed out")
def test_select_mutated(self):
a = []
class F:
Expand All @@ -92,7 +91,6 @@ def fileno(self):
a[:] = [F()] * 10
self.assertEqual(select.select([], a, []), ([], a[:5], []))

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: TypeError not raised by poll
def test_disallow_instantiation(self):
support.check_disallow_instantiation(self, type(select.poll()))

Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_syslog.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class Test(unittest.TestCase):
def tearDown(self):
syslog.closelog()

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_openlog(self):
syslog.openlog('python')
# Issue #6697.
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_termios.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ def test_ioctl_constants(self):
with self.subTest(name=name):
self.assertGreaterEqual(value, 0)

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: <class 'termios.error'> is a subclass of <class 'OSError'>
def test_exception(self):
self.assertIsSubclass(termios.error, Exception)
self.assertNotIsSubclass(termios.error, OSError)
Expand Down
10 changes: 10 additions & 0 deletions crates/host_env/src/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,16 @@ pub fn setresuid(ruid: u32, euid: u32, suid: u32) -> std::io::Result<()> {
.map_err(std::io::Error::from)
}

#[cfg(not(any(target_os = "wasi", target_os = "solaris", target_os = "illumos")))]
pub fn login_tty(fd: i32) -> std::io::Result<()> {
let ret = unsafe { libc::login_tty(fd) };
if ret < 0 {
Err(std::io::Error::last_os_error())
} else {
Ok(())
}
}

#[cfg(not(target_os = "redox"))]
pub fn openpty() -> std::io::Result<(OwnedFd, OwnedFd)> {
let pty = nix::pty::openpty(None, None).map_err(std::io::Error::from)?;
Expand Down
150 changes: 150 additions & 0 deletions crates/host_env/src/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,153 @@ pub mod epoll {
}
}
}

#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "dragonfly",
))]
pub mod kqueue {
use alloc::sync::{Arc, Weak};
use core::sync::atomic::{AtomicI32, Ordering};
use parking_lot::Mutex;
use std::io;
use std::os::fd::BorrowedFd;

pub use libc::{
EV_ADD, EV_CLEAR, EV_DELETE, EV_DISABLE, EV_ENABLE, EV_EOF, EV_ERROR, EV_FLAG1, EV_ONESHOT,
EV_SYSFLAGS, EVFILT_AIO, EVFILT_PROC, EVFILT_READ, EVFILT_SIGNAL, EVFILT_TIMER,
EVFILT_VNODE, EVFILT_WRITE, NOTE_ATTRIB, NOTE_CHILD, NOTE_DELETE, NOTE_EXEC, NOTE_EXIT,
NOTE_EXTEND, NOTE_FORK, NOTE_LINK, NOTE_LOWAT, NOTE_PCTRLMASK, NOTE_PDATAMASK, NOTE_RENAME,
NOTE_REVOKE, NOTE_TRACK, NOTE_TRACKERR, NOTE_WRITE,
};

#[derive(Copy, Clone, Debug)]
pub struct Event {
pub ident: usize,
pub filter: i16,
pub flags: u16,
pub fflags: u32,
pub data: isize,
pub udata: usize,
}

impl Event {
pub fn to_libc(self) -> libc::kevent {
// Field widths and optional `ext` differ across BSDs; assign
// rather than using a struct literal.
let mut ev: libc::kevent = unsafe { core::mem::zeroed() };
ev.ident = self.ident as _;
ev.filter = self.filter as _;
ev.flags = self.flags as _;
ev.fflags = self.fflags as _;
ev.data = self.data as _;
ev.udata = self.udata as *mut libc::c_void;
ev
}

#[allow(clippy::unnecessary_cast)]
pub fn from_libc(e: libc::kevent) -> Self {
Self {
ident: e.ident as usize,
filter: e.filter as i16,
flags: e.flags as u16,
fflags: e.fflags as u32,
data: e.data as isize,
udata: e.udata as usize,
}
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

static OPEN: Mutex<Vec<Weak<AtomicI32>>> = Mutex::new(Vec::new());

fn register_open(cell: &Arc<AtomicI32>) {
let mut open = OPEN.lock();
open.retain(|w| w.strong_count() > 0);
open.push(Arc::downgrade(cell));
}

pub fn create() -> io::Result<Arc<AtomicI32>> {
let fd = unsafe { libc::kqueue() };
if fd < 0 {
return Err(io::Error::last_os_error());
}
let borrowed = unsafe { BorrowedFd::borrow_raw(fd) };
if let Err(err) = crate::posix::set_inheritable(borrowed, false) {
let _ = unsafe { libc::close(fd) };
return Err(err);
}
let cell = Arc::new(AtomicI32::new(fd));
register_open(&cell);
Ok(cell)
}

pub fn from_fd(fd: i32) -> Arc<AtomicI32> {
let cell = Arc::new(AtomicI32::new(fd));
register_open(&cell);
cell
}

pub fn close(cell: &AtomicI32) -> io::Result<()> {
let fd = cell.swap(-1, Ordering::SeqCst);
if fd < 0 {
return Ok(());
}
let ret = unsafe { libc::close(fd) };
if ret < 0 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}

pub fn fd(cell: &AtomicI32) -> i32 {
cell.load(Ordering::SeqCst)
}

pub fn kevent(
kq: i32,
changelist: &[Event],
eventlist: &mut [Event],
timeout: Option<&libc::timespec>,
) -> io::Result<usize> {
let chl: Vec<libc::kevent> = changelist.iter().copied().map(Event::to_libc).collect();
let mut evl = vec![unsafe { core::mem::zeroed() }; eventlist.len()];
let timeout = timeout.map_or(core::ptr::null(), |t| t);
let ret = unsafe {
libc::kevent(
kq,
chl.as_ptr(),
chl.len() as _,
evl.as_mut_ptr(),
evl.len() as _,
timeout,
)
};
if ret < 0 {
return Err(io::Error::last_os_error());
}
let n = ret as usize;
for (dst, src) in eventlist.iter_mut().zip(evl.into_iter().take(n)) {
*dst = Event::from_libc(src);
}
Ok(n)
}

pub fn mark_closed_after_fork() {
// After fork only this thread exists. If the parent held OPEN,
// the child's copy stays locked until it is released.
if OPEN.try_lock().is_none() {
unsafe { OPEN.force_unlock() };
}
let mut open = OPEN.lock();
for weak in open.drain(..) {
if let Some(cell) = weak.upgrade() {
cell.store(-1, Ordering::SeqCst);
}
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
Loading
Loading