std/sys/pal/unix/linux/
pidfd.rs
1use crate::io;
2use crate::os::fd::{AsRawFd, FromRawFd, RawFd};
3use crate::sys::cvt;
4use crate::sys::pal::unix::fd::FileDesc;
5use crate::sys::process::ExitStatus;
6use crate::sys_common::{AsInner, FromInner, IntoInner};
7
8#[cfg(test)]
9mod tests;
10
11#[derive(Debug)]
12pub(crate) struct PidFd(FileDesc);
13
14impl PidFd {
15 pub fn kill(&self) -> io::Result<()> {
16 cvt(unsafe {
17 libc::syscall(
18 libc::SYS_pidfd_send_signal,
19 self.0.as_raw_fd(),
20 libc::SIGKILL,
21 crate::ptr::null::<()>(),
22 0,
23 )
24 })
25 .map(drop)
26 }
27
28 pub fn wait(&self) -> io::Result<ExitStatus> {
29 let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() };
30 cvt(unsafe {
31 libc::waitid(libc::P_PIDFD, self.0.as_raw_fd() as u32, &mut siginfo, libc::WEXITED)
32 })?;
33 Ok(ExitStatus::from_waitid_siginfo(siginfo))
34 }
35
36 pub fn try_wait(&self) -> io::Result<Option<ExitStatus>> {
37 let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() };
38
39 cvt(unsafe {
40 libc::waitid(
41 libc::P_PIDFD,
42 self.0.as_raw_fd() as u32,
43 &mut siginfo,
44 libc::WEXITED | libc::WNOHANG,
45 )
46 })?;
47 if unsafe { siginfo.si_pid() } == 0 {
48 Ok(None)
49 } else {
50 Ok(Some(ExitStatus::from_waitid_siginfo(siginfo)))
51 }
52 }
53}
54
55impl AsInner<FileDesc> for PidFd {
56 fn as_inner(&self) -> &FileDesc {
57 &self.0
58 }
59}
60
61impl IntoInner<FileDesc> for PidFd {
62 fn into_inner(self) -> FileDesc {
63 self.0
64 }
65}
66
67impl FromInner<FileDesc> for PidFd {
68 fn from_inner(inner: FileDesc) -> Self {
69 Self(inner)
70 }
71}
72
73impl FromRawFd for PidFd {
74 unsafe fn from_raw_fd(fd: RawFd) -> Self {
75 Self(FileDesc::from_raw_fd(fd))
76 }
77}