From 59b7a6d78d4d9771787a4a4afad13874154f9941 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 17 Nov 2022 00:10:09 +0000 Subject: [PATCH] pidfd_send_signal --- CHANGELOG.md | 2 ++ src/sys/mod.rs | 2 +- src/sys/pidfd.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b81ca23b8..9b11cb783a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] - ReleaseDate ### Added +- Added `pidfd_send_signal` on Linux. + ([#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_getfd` on Linux. 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 f4229a8908..16911e87b8 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; @@ -58,3 +59,39 @@ pub fn pid_open(pid_t: Pid, pidfd_nonblock: bool) -> Result { _ => unreachable!(), } } + +/// Sends the signal `sig` to the target process referred to by `pidfd`, 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( + pidfd: RawFd, + 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, pidfd, sig as i32, info) + } { + -1 => Err(Errno::last()), + 0 => Ok(()), + _ => unreachable!(), + } +}