1 | use crate::io; |
2 | use crate::os::fd::{AsRawFd, FromRawFd, RawFd}; |
3 | use crate::sys::cvt; |
4 | use crate::sys::pal::unix::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 | |