| 1 | use crate::io; |
| 2 | use crate::os::fd::{AsRawFd, FromRawFd, RawFd}; |
| 3 | use crate::sys::cvt; |
| 4 | use crate::sys::fd::FileDesc; |
| 5 | use crate::sys::process::ExitStatus; |
| 6 | use crate::sys_common::{AsInner, FromInner, IntoInner}; |
| 7 | |
| 8 | #[cfg (test)] |
| 9 | mod tests; |
| 10 | |
| 11 | #[derive (Debug)] |
| 12 | pub(crate) struct PidFd(FileDesc); |
| 13 | |
| 14 | impl 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 | |
| 55 | impl AsInner<FileDesc> for PidFd { |
| 56 | fn as_inner(&self) -> &FileDesc { |
| 57 | &self.0 |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | impl IntoInner<FileDesc> for PidFd { |
| 62 | fn into_inner(self) -> FileDesc { |
| 63 | self.0 |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | impl FromInner<FileDesc> for PidFd { |
| 68 | fn from_inner(inner: FileDesc) -> Self { |
| 69 | Self(inner) |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | impl FromRawFd for PidFd { |
| 74 | unsafe fn from_raw_fd(fd: RawFd) -> Self { |
| 75 | Self(FileDesc::from_raw_fd(fd)) |
| 76 | } |
| 77 | } |
| 78 | |