|
1 | 1 | use crate::errno::Errno;
|
| 2 | +use crate::sys::signal::Signal; |
2 | 3 | use crate::unistd::Pid;
|
3 | 4 | use crate::Result;
|
4 | 5 | use std::convert::TryFrom;
|
@@ -60,3 +61,39 @@ pub fn pid_open(pid_t: Pid, pidfd_nonblock: bool) -> Result<RawFd> {
|
60 | 61 | _ => unreachable!(),
|
61 | 62 | }
|
62 | 63 | }
|
| 64 | + |
| 65 | +/// Sends the signal `sig` to the target process referred to by `pidfd`, a PID file descriptor that |
| 66 | +/// refers to a process. |
| 67 | +/// |
| 68 | +/// If the info argument is some [`libc::siginfo_t`] buffer, that buffer should be populated as |
| 69 | +/// described in [rt_sigqueueinfo(2)](https://man7.org/linux/man-pages/man2/rt_sigqueueinfo.2.html). |
| 70 | +/// |
| 71 | +/// If the info argument is `None`, this is equivalent to specifying a pointer to a `siginfo_t` |
| 72 | +/// buffer whose fields match the values that are implicitly supplied when a signal is sent using |
| 73 | +/// [`crate::sys::signal::kill`]: |
| 74 | +/// |
| 75 | +/// - `si_signo` is set to the signal number; |
| 76 | +/// - `si_errno` is set to 0; |
| 77 | +/// - `si_code` is set to SI_USER; |
| 78 | +/// - `si_pid` is set to the caller's PID; and |
| 79 | +/// - `si_uid` is set to the caller's real user ID. |
| 80 | +/// |
| 81 | +/// The calling process must either be in the same PID namespace as the process referred to by |
| 82 | +/// pidfd, or be in an ancestor of that namespace. |
| 83 | +pub fn pidfd_send_signal( |
| 84 | + pidfd: RawFd, |
| 85 | + sig: Signal, |
| 86 | + info: Option<libc::siginfo_t>, |
| 87 | +) -> Result<()> { |
| 88 | + let info = match info { |
| 89 | + Some(i) => &i, |
| 90 | + None => std::ptr::null(), |
| 91 | + }; |
| 92 | + match unsafe { |
| 93 | + libc::syscall(libc::SYS_pidfd_send_signal, pidfd, sig as i32, info) |
| 94 | + } { |
| 95 | + -1 => Err(Errno::last()), |
| 96 | + 0 => Ok(()), |
| 97 | + _ => unreachable!(), |
| 98 | + } |
| 99 | +} |
0 commit comments