mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Add Linux pidfd syscalls to expose asyncio pidfd watcher (#6660)
* Add pidfd support syscalls * Validate pidfd signal range * Clarify pidfd syscall return handling * Skip flaky is_alive_after_fork test --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
3 files changed
+52
No files matched your search
Vendored
+1
@@ -589,6 +589,7 @@ class ThreadTests(BaseTestCase):
|
||||
self.assertEqual(out, b'')
|
||||
self.assertEqual(err, b'')
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON; flaky")
|
||||
@support.requires_fork()
|
||||
def test_is_alive_after_fork(self):
|
||||
# Try hard to trigger #18418: is_alive() could sometimes be True on
|
||||
|
||||
@@ -1757,6 +1757,23 @@ pub mod module {
|
||||
libc::WTERMSIG(status)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pyfunction]
|
||||
fn pidfd_open(
|
||||
pid: libc::pid_t,
|
||||
flags: OptionalArg<u32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<OwnedFd> {
|
||||
let flags = flags.unwrap_or(0);
|
||||
let fd = unsafe { libc::syscall(libc::SYS_pidfd_open, pid, flags) as libc::c_long };
|
||||
if fd == -1 {
|
||||
Err(vm.new_last_errno_error())
|
||||
} else {
|
||||
// Safety: syscall returns a new owned file descriptor.
|
||||
Ok(unsafe { OwnedFd::from_raw_fd(fd as libc::c_int) })
|
||||
}
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn waitpid(pid: libc::pid_t, opt: i32, vm: &VirtualMachine) -> PyResult<(libc::pid_t, i32)> {
|
||||
let mut status = 0;
|
||||
|
||||
@@ -431,6 +431,40 @@ pub(crate) mod _signal {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pyfunction]
|
||||
fn pidfd_send_signal(
|
||||
pidfd: i32,
|
||||
sig: i32,
|
||||
siginfo: OptionalArg<PyObjectRef>,
|
||||
flags: OptionalArg<u32>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
signal::assert_in_range(sig, vm)?;
|
||||
if let OptionalArg::Present(obj) = siginfo
|
||||
&& !vm.is_none(&obj)
|
||||
{
|
||||
return Err(vm.new_type_error("siginfo must be None".to_owned()));
|
||||
}
|
||||
|
||||
let flags = flags.unwrap_or(0);
|
||||
let ret = unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_pidfd_send_signal,
|
||||
pidfd,
|
||||
sig,
|
||||
std::ptr::null::<libc::siginfo_t>(),
|
||||
flags,
|
||||
) as libc::c_long
|
||||
};
|
||||
|
||||
if ret == -1 {
|
||||
Err(vm.new_last_errno_error())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(target_os = "redox")))]
|
||||
#[pyfunction(name = "siginterrupt")]
|
||||
fn py_siginterrupt(signum: i32, flag: i32, vm: &VirtualMachine) -> PyResult<()> {
|
||||
|
||||
Reference in new issue
Block a user