summary refs log tree commit diff
path: root/ripple/minitrace/src/pidfd.rs
blob: ede0524b1ea7df7293071f5f1e60de1b929054bb (plain)
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())
		}
	}
}