1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
// SPDX-FileCopyrightText: edef <edef@unfathomable.blue>
// SPDX-License-Identifier: OSL-3.0
use {
nix::{libc::close, sys::signal::Signal, unistd::Pid, Result},
std::os::unix::prelude::*,
};
#[derive(Debug)]
pub struct PidFd {
lower: RawFd,
}
impl PidFd {
pub fn open(pid: Pid) -> Result<PidFd> {
lower::pidfd_open(pid).map(|lower| PidFd { lower })
}
pub fn kill(&self, signal: Signal) -> nix::Result<()> {
unsafe { lower::pidfd_send_signal(self.lower, signal) }
}
}
impl Drop for PidFd {
fn drop(&mut self) {
unsafe {
close(self.lower);
}
}
}
mod lower {
use {
nix::{
libc::{c_int, c_uint, c_void, syscall, SYS_pidfd_open, SYS_pidfd_send_signal},
sys::signal::Signal,
unistd::Pid,
Error, Result,
},
std::{os::unix::prelude::*, ptr},
};
pub fn pidfd_open(pid: Pid) -> Result<RawFd> {
unsafe {
let pid = pid.as_raw();
let ret = syscall(SYS_pidfd_open, pid, 0);
if ret >= 0 {
Ok(ret as RawFd)
} else {
Err(Error::last())
}
}
}
pub unsafe fn pidfd_send_signal(pidfd: RawFd, signal: Signal) -> Result<()> {
let signal = signal as c_int;
let info: *const c_void = ptr::null();
let flags: c_uint = 0;
let ret = syscall(SYS_pidfd_send_signal, pidfd, signal, info, flags);
if ret == 0 {
Ok(())
} else {
Err(Error::last())
}
}
}
|