summaryrefslogtreecommitdiffstats
path: root/man/man2/pidfd_send_signal.2
diff options
context:
space:
mode:
Diffstat (limited to 'man/man2/pidfd_send_signal.2')
-rw-r--r--man/man2/pidfd_send_signal.2240
1 files changed, 240 insertions, 0 deletions
diff --git a/man/man2/pidfd_send_signal.2 b/man/man2/pidfd_send_signal.2
new file mode 100644
index 000000000..205808425
--- /dev/null
+++ b/man/man2/pidfd_send_signal.2
@@ -0,0 +1,240 @@
+.\" Copyright (c) 2019 by Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH pidfd_send_signal 2 (date) "Linux man-pages (unreleased)"
+.SH NAME
+pidfd_send_signal \- send a signal to a process specified by a file descriptor
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.BR "#include <linux/signal.h>" " /* Definition of " SIG* " constants */"
+.BR "#include <signal.h>" " /* Definition of " SI_* " constants */"
+.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */"
+.B #include <unistd.h>
+.P
+.BI "int syscall(SYS_pidfd_send_signal, int " pidfd ", int " sig ,
+.BI " siginfo_t *_Nullable " info ", unsigned int " flags );
+.fi
+.P
+.IR Note :
+glibc provides no wrapper for
+.BR pidfd_send_signal (),
+necessitating the use of
+.BR syscall (2).
+.SH DESCRIPTION
+The
+.BR pidfd_send_signal ()
+system call sends the signal
+.I sig
+to the target process referred to by
+.IR pidfd ,
+a PID file descriptor that refers to a process.
+.\" See the very detailed commit message for kernel commit
+.\" 3eb39f47934f9d5a3027fe00d906a45fe3a15fad
+.P
+If the
+.I info
+argument points to a
+.I siginfo_t
+buffer, that buffer should be populated as described in
+.BR rt_sigqueueinfo (2).
+.P
+If the
+.I info
+argument is a null pointer,
+this is equivalent to specifying a pointer to a
+.I siginfo_t
+buffer whose fields match the values that are
+implicitly supplied when a signal is sent using
+.BR kill (2):
+.P
+.PD 0
+.IP \[bu] 3
+.I si_signo
+is set to the signal number;
+.IP \[bu]
+.I si_errno
+is set to 0;
+.IP \[bu]
+.I si_code
+is set to
+.BR SI_USER ;
+.IP \[bu]
+.I si_pid
+is set to the caller's PID; and
+.IP \[bu]
+.I si_uid
+is set to the caller's real user ID.
+.PD
+.P
+The calling process must either be in the same PID namespace as the
+process referred to by
+.IR pidfd ,
+or be in an ancestor of that namespace.
+.P
+The
+.I flags
+argument is reserved for future use;
+currently, this argument must be specified as 0.
+.SH RETURN VALUE
+On success,
+.BR pidfd_send_signal ()
+returns 0.
+On error, \-1 is returned and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EBADF
+.I pidfd
+is not a valid PID file descriptor.
+.TP
+.B EINVAL
+.I sig
+is not a valid signal.
+.TP
+.B EINVAL
+The calling process is not in a PID namespace from which it can
+send a signal to the target process.
+.TP
+.B EINVAL
+.I flags
+is not 0.
+.TP
+.B EPERM
+The calling process does not have permission to send the signal
+to the target process.
+.TP
+.B EPERM
+.I pidfd
+doesn't refer to the calling process, and
+.I info.si_code
+is invalid (see
+.BR rt_sigqueueinfo (2)).
+.TP
+.B ESRCH
+The target process does not exist
+(i.e., it has terminated and been waited on).
+.SH STANDARDS
+Linux.
+.SH HISTORY
+Linux 5.1.
+.SH NOTES
+.SS PID file descriptors
+The
+.I pidfd
+argument is a PID file descriptor,
+a file descriptor that refers to process.
+Such a file descriptor can be obtained in any of the following ways:
+.IP \[bu] 3
+by opening a
+.IR /proc/ pid
+directory;
+.IP \[bu]
+using
+.BR pidfd_open (2);
+or
+.IP \[bu]
+via the PID file descriptor that is returned by a call to
+.BR clone (2)
+or
+.BR clone3 (2)
+that specifies the
+.B CLONE_PIDFD
+flag.
+.P
+The
+.BR pidfd_send_signal ()
+system call allows the avoidance of race conditions that occur
+when using traditional interfaces (such as
+.BR kill (2))
+to signal a process.
+The problem is that the traditional interfaces specify the target process
+via a process ID (PID),
+with the result that the sender may accidentally send a signal to
+the wrong process if the originally intended target process
+has terminated and its PID has been recycled for another process.
+By contrast,
+a PID file descriptor is a stable reference to a specific process;
+if that process terminates,
+.BR pidfd_send_signal ()
+fails with the error
+.BR ESRCH .
+.SH EXAMPLES
+.\" SRC BEGIN (pidfd_send_signal.c)
+.EX
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+\&
+static int
+pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
+ unsigned int flags)
+{
+ return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
+}
+\&
+int
+main(int argc, char *argv[])
+{
+ int pidfd, sig;
+ char path[PATH_MAX];
+ siginfo_t info;
+\&
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <pid> <signal>\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ sig = atoi(argv[2]);
+\&
+ /* Obtain a PID file descriptor by opening the /proc/PID directory
+ of the target process. */
+\&
+ snprintf(path, sizeof(path), "/proc/%s", argv[1]);
+\&
+ pidfd = open(path, O_RDONLY);
+ if (pidfd == \-1) {
+ perror("open");
+ exit(EXIT_FAILURE);
+ }
+\&
+ /* Populate a \[aq]siginfo_t\[aq] structure for use with
+ pidfd_send_signal(). */
+\&
+ memset(&info, 0, sizeof(info));
+ info.si_code = SI_QUEUE;
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_uid = getuid();
+ info.si_pid = getpid();
+ info.si_value.sival_int = 1234;
+\&
+ /* Send the signal. */
+\&
+ if (pidfd_send_signal(pidfd, sig, &info, 0) == \-1) {
+ perror("pidfd_send_signal");
+ exit(EXIT_FAILURE);
+ }
+\&
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR clone (2),
+.BR kill (2),
+.BR pidfd_open (2),
+.BR rt_sigqueueinfo (2),
+.BR sigaction (2),
+.BR pid_namespaces (7),
+.BR signal (7)