// SPDX-FileCopyrightText: edef // 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 { 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 { 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()) } } }