pidfd_send_signal(2)
Send a signal to the process a pidfd refers to, without PID-reuse races.
- Since
- Linux 5.1check your kernel →
- glibc
- glibc 2.36
- System
- Linux
- Man page
- pidfd_send_signal(2)
Synopsis
#include <linux/signal.h>
#include <signal.h>
#include <sys/syscall.h>
#include <unistd.h>
int syscall(SYS_pidfd_send_signal, int pidfd, int sig,
siginfo_t *_Nullable info, unsigned int flags);Rod's take
kill(child, SIGTERM) after the child is gone is how you SIGTERM a stranger. pidfd_send_signal takes the fd, checks the actual task, and hands you ESRCH if your process already exited and got reaped, instead of shooting whoever inherited the number. It landed in 5.1, two releases before pidfd_open, back when you got the fd by opening /proc/<pid>. Pass NULL for info and it behaves like kill(2), which makes the migration close to a one-line diff. No excuse left for signalling by number.
Flags and arguments that matter
| Name | What it does |
|---|---|
| info = NULL | Equivalent to kill(2): the kernel fills in si_signo, si_code = SI_USER, sender PID and UID. |
| PIDFD_SIGNAL_THREADLinux 6.9 | Send the signal to the specific thread referenced by pidfd. |
| PIDFD_SIGNAL_THREAD_GROUPLinux 6.9 | If pidfd refers to a thread-group leader, signal the whole thread group. |
| PIDFD_SIGNAL_PROCESS_GROUPLinux 6.9 | If pidfd refers to a process-group leader, signal the whole process group. |
Errors you will actually hit
| errno | Meaning |
|---|---|
| ESRCH | The target process has terminated and been waited on. |
| EBADF | pidfd is not a valid PID file descriptor. |
| EPERM | No permission to signal the target, or invalid si_code when signalling another process. |
| EINVAL | Invalid signal, invalid flags, or caller's PID namespace can't signal the target. |
Example
int pfd = syscall(SYS_pidfd_open, pid, 0);
if (pfd < 0)
err(1, "pidfd_open");
if (syscall(SYS_pidfd_send_signal, pfd, SIGTERM, NULL, 0) < 0) {
if (errno == ESRCH)
warnx("already exited and reaped");
else
err(1, "pidfd_send_signal");
}
close(pfd);Trimmed from the full walkthrough in pidfd: Unix finally has a handle on your processes (only took 50 years).
BSD equivalent
FreeBSD: pdkill(2) on a process descriptor from pdfork(2) (FreeBSD 9.0). OpenBSD: none.
The long version, from the console
Sources
- pidfd_send_signal(2), man7.org
- pdfork(2), FreeBSD
- glibc 2.36 NEWS (pidfd_open, pidfd_getfd, pidfd_send_signal added)
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
