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:
authored and GitHub committed 2026-01-06 15:10:23 +09:00
1 parent 03380dc4ec
commit e367145a4a
3 files changed
+52

No files matched your search

+1
View File
@@ -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
+17
View File
@@ -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;
+34
View File
@@ -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<()> {