From 13f6608a3276e620a2e7392133d2038c08ba0319 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Sun, 18 Dec 2022 18:31:58 +0000 Subject: [PATCH] pidfd_send_signal --- CHANGELOG.md | 2 ++ src/sys/mod.rs | 2 +- src/sys/pidfd.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d6816223e..50c0539197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). ([#1868](https://github.com/nix-rust/nix/pull/1868)) - Added `pid_open` on Linux. ([#1868](https://github.com/nix-rust/nix/pull/1868)) +- Added `pidfd_send_signal` on Linux. + ([#1868](https://github.com/nix-rust/nix/pull/1868)) ### Changed diff --git a/src/sys/mod.rs b/src/sys/mod.rs index e34a5a7e90..1f90ab0b8a 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -227,6 +227,6 @@ feature! { pub mod timer; } -#[cfg(all(target_os = "linux", feature = "process"))] +#[cfg(all(target_os = "linux", feature = "signal", feature = "process"))] /// pidfd related functionality pub mod pidfd; diff --git a/src/sys/pidfd.rs b/src/sys/pidfd.rs index 26bbb1fffb..f9150750ff 100644 --- a/src/sys/pidfd.rs +++ b/src/sys/pidfd.rs @@ -1,4 +1,5 @@ use crate::errno::Errno; +use crate::sys::signal::Signal; use crate::unistd::Pid; use crate::Result; use std::convert::TryFrom; @@ -74,3 +75,44 @@ pub fn pid_open(pid: Pid, nonblock: bool) -> Result { _ => unreachable!(), } } + +/// Sends the signal `sig` to the target process referred to by `pid`, a PID file descriptor that +/// refers to a process. +/// +/// If the info argument is some [`libc::siginfo_t`] buffer, that buffer should be populated as +/// described in [rt_sigqueueinfo(2)](https://man7.org/linux/man-pages/man2/rt_sigqueueinfo.2.html). +/// +/// If the info argument is `None`, this is equivalent to specifying a pointer to a `siginfo_t` +/// buffer whose fields match the values that are implicitly supplied when a signal is sent using +/// [`crate::sys::signal::kill`]: +/// +/// - `si_signo` is set to the signal number; +/// - `si_errno` is set to 0; +/// - `si_code` is set to SI_USER; +/// - `si_pid` is set to the caller's PID; and +/// - `si_uid` is set to the caller's real user ID. +/// +/// The calling process must either be in the same PID namespace as the process referred to by +/// pidfd, or be in an ancestor of that namespace. +pub fn pidfd_send_signal( + pid: Fd, + sig: Signal, + info: Option, +) -> Result<()> { + let info = match info { + Some(i) => &i, + None => std::ptr::null(), + }; + match unsafe { + libc::syscall( + libc::SYS_pidfd_send_signal, + pid.as_raw_fd(), + sig as i32, + info, + ) + } { + -1 => Err(Errno::last()), + 0 => Ok(()), + _ => unreachable!(), + } +}