2019-09-22 21:06:21 +00:00
|
|
|
.\" Copyright (c) 2019 by Michael Kerrisk <mtk.manpages@gmail.com>
|
|
|
|
.\"
|
|
|
|
.\" %%%LICENSE_START(VERBATIM)
|
|
|
|
.\" Permission is granted to make and distribute verbatim copies of this
|
|
|
|
.\" manual provided the copyright notice and this permission notice are
|
|
|
|
.\" preserved on all copies.
|
|
|
|
.\"
|
|
|
|
.\" Permission is granted to copy and distribute modified versions of this
|
|
|
|
.\" manual under the conditions for verbatim copying, provided that the
|
|
|
|
.\" entire resulting derived work is distributed under the terms of a
|
|
|
|
.\" permission notice identical to this one.
|
|
|
|
.\"
|
|
|
|
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
|
|
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
|
|
.\" responsibility for errors or omissions, or for damages resulting from
|
|
|
|
.\" the use of the information contained herein. The author(s) may not
|
|
|
|
.\" have taken the same level of care in the production of this manual,
|
|
|
|
.\" which is licensed free of charge, as they might when working
|
|
|
|
.\" professionally.
|
|
|
|
.\"
|
|
|
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
|
|
.\" the source, must acknowledge the copyright and authors of this work.
|
|
|
|
.\" %%%LICENSE_END
|
|
|
|
.\"
|
iconv.1, locale.1, memusage.1, memusagestat.1, pldd.1, sprof.1, _syscall.2, add_key.2, adjtimex.2, bind.2, bpf.2, chown.2, clone.2, close.2, copy_file_range.2, eventfd.2, fanotify_init.2, fanotify_mark.2, fork.2, fsync.2, futex.2, getdents.2, getrlimit.2, getxattr.2, io_cancel.2, io_destroy.2, io_getevents.2, io_setup.2, ioctl_fat.2, ioctl_getfsmap.2, ioctl_ns.2, ioctl_tty.2, ioctl_userfaultfd.2, kcmp.2, keyctl.2, listen.2, listxattr.2, mbind.2, membarrier.2, memfd_create.2, mkdir.2, move_pages.2, mremap.2, msync.2, nfsservctl.2, open.2, perf_event_open.2, pidfd_send_signal.2, pipe.2, pivot_root.2, pkey_alloc.2, process_vm_readv.2, ptrace.2, readlink.2, readv.2, recv.2, recvmmsg.2, rename.2, request_key.2, s390_runtime_instr.2, sched_setaffinity.2, seccomp.2, send.2, sendmmsg.2, sigaltstack.2, signalfd.2, socket.2, socketpair.2, splice.2, spu_create.2, spu_run.2, statfs.2, syscall.2, sysctl.2, sysfs.2, tee.2, timer_getoverrun.2, timer_settime.2, umount.2, userfaultfd.2, utimensat.2, wait4.2, INFINITY.3, __ppc_get_timebase.3, __setfpucw.3, abort.3, aio_cancel.3, aio_error.3, aio_read.3, aio_return.3, atexit.3, backtrace.3, basename.3, bsearch.3, bswap.3, cacos.3, cacosh.3, catan.3, catanh.3, cexp2.3, clock_getcpuclockid.3, clog2.3, cmsg.3, confstr.3, div.3, dl_iterate_phdr.3, dlerror.3, dlinfo.3, dlopen.3, dlsym.3, duplocale.3, encrypt.3, end.3, endian.3, envz_add.3, err.3, expm1.3, fdim.3, flockfile.3, fmtmsg.3, frexp.3, ftw.3, get_nprocs_conf.3, get_phys_pages.3, getaddrinfo_a.3, getauxval.3, getdate.3, getdtablesize.3, getgrent_r.3, getgrouplist.3, gethostbyname.3, getline.3, getnameinfo.3, getopt.3, getprotoent_r.3, getpwent_r.3, getpwnam.3, getservent_r.3, getsubopt.3, getutent.3, glob.3, gnu_get_libc_version.3, hsearch.3, if_nameindex.3, inet.3, inet_net_pton.3, inet_ntop.3, inet_pton.3, insque.3, killpg.3, makecontext.3, mallinfo.3, malloc.3, malloc_hook.3, malloc_info.3, mallopt.3, matherr.3, mbsnrtowcs.3, mbstowcs.3, mcheck.3, mempcpy.3, mq_getattr.3, mq_notify.3, mtrace.3, newlocale.3, nextafter.3, ntp_gettime.3, offsetof.3, open_memstream.3, pow.3, printf.3, pthread_attr_init.3, pthread_attr_setdetachstate.3, pthread_attr_setguardsize.3, pthread_attr_setinheritsched.3, pthread_attr_setschedparam.3, pthread_attr_setschedpolicy.3, pthread_attr_setstack.3, pthread_attr_setstacksize.3, pthread_cancel.3, pthread_cleanup_push.3, pthread_create.3, pthread_detach.3, pthread_getattr_default_np.3, pthread_getattr_np.3, pthread_getcpuclockid.3, pthread_join.3, pthread_mutex_consistent.3, pthread_mutexattr_setrobust.3, pthread_setaffinity_np.3, pthread_setcancelstate.3, pthread_setname_np.3, pthread_setschedparam.3, pthread_sigmask.3, pthread_spin_init.3, pthread_testcancel.3, pthread_tryjoin_np.3, ptsname.3, qsort.3, rand.3, random.3, remainder.3, rpmatch.3, rtime.3, rtnetlink.3, scalb.3, scalbln.3, scandir.3, sem_getvalue.3, sem_wait.3, setaliasent.3, setlogmask.3, sigwait.3, sincos.3, sockatmark.3, stdarg.3, stpcpy.3, strcat.3, strfmon.3, strptime.3, strtod.3, strtok.3, strtol.3, strtoul.3, strverscmp.3, tsearch.3, uselocale.3, wcstok.3, wcstombs.3, wordexp.3, y0.3, loop.4, vcs.4, veth.4, charmap.5, core.5, filesystems.5, gai.conf.5, hosts.5, hosts.equiv.5, locale.5, nss.5, repertoiremap.5, securetty.5, shells.5, ttytype.5, ascii.7, complex.7, cpuset.7, credentials.7, fanotify.7, hier.7, inotify.7, ip.7, mount_namespaces.7, mq_overview.7, netlink.7, network_namespaces.7, pid_namespaces.7, pkeys.7, rtld-audit.7, rtnetlink.7, sem_overview.7, signal-safety.7, sock_diag.7, spufs.7, standards.7, symlink.7, tcp.7, time_namespaces.7, unix.7, user_namespaces.7, xattr.7, ldconfig.8: tstamp
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
2020-06-09 12:43:54 +00:00
|
|
|
.TH PIDFD_SEND_SIGNAL 2 2020-06-09 "Linux" "Linux Programmer's Manual"
|
2019-09-22 21:06:21 +00:00
|
|
|
.SH NAME
|
|
|
|
pidfd_send_signal \- send a signal to a process specified by a file descriptor
|
|
|
|
.SH SYNOPSIS
|
|
|
|
.nf
|
2019-09-24 19:09:12 +00:00
|
|
|
.B "#include <signal.h>"
|
|
|
|
.PP
|
2019-09-24 19:10:39 +00:00
|
|
|
.BI "int pidfd_send_signal(int " pidfd ", int " sig ", siginfo_t *" info ,
|
2019-09-22 21:06:21 +00:00
|
|
|
.BI " unsigned int " flags );
|
|
|
|
.fi
|
|
|
|
.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
|
|
|
|
.PP
|
|
|
|
If the
|
|
|
|
.I info
|
|
|
|
argument points to a
|
|
|
|
.I siginfo_t
|
|
|
|
buffer, that buffer should be populated as described in
|
|
|
|
.BR rt_sigqueueinfo (2).
|
|
|
|
.PP
|
|
|
|
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):
|
|
|
|
.PP
|
|
|
|
.PD 0
|
|
|
|
.IP * 3
|
|
|
|
.I si_signo
|
|
|
|
is set to the signal number;
|
|
|
|
.IP *
|
|
|
|
.I si_errno
|
|
|
|
is set to 0;
|
|
|
|
.IP *
|
|
|
|
.I si_code
|
|
|
|
is set to
|
2020-06-21 07:26:30 +00:00
|
|
|
.BR SI_USER ;
|
2019-09-22 21:06:21 +00:00
|
|
|
.IP *
|
|
|
|
.I si_pid
|
|
|
|
is set to the caller's PID; and
|
|
|
|
.IP *
|
|
|
|
.I si_uid
|
|
|
|
is set to the caller's real user ID.
|
|
|
|
.PD
|
|
|
|
.PP
|
|
|
|
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.
|
|
|
|
.PP
|
|
|
|
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.
|
2019-09-23 20:26:29 +00:00
|
|
|
On error, \-1 is returned and
|
2019-09-22 21:06:21 +00:00
|
|
|
.I errno
|
|
|
|
is set to indicate the cause of 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
|
|
|
|
.IR info.si_code
|
|
|
|
is invalid (see
|
|
|
|
.BR rt_sigqueueinfo (2)).
|
|
|
|
.TP
|
|
|
|
.B ESRCH
|
2019-09-24 19:09:12 +00:00
|
|
|
The target process does not exist
|
|
|
|
(i.e., it has terminated and been waited on).
|
2019-09-22 21:06:21 +00:00
|
|
|
.SH VERSIONS
|
|
|
|
.BR pidfd_send_signal ()
|
|
|
|
first appeared in Linux 5.1.
|
|
|
|
.SH CONFORMING TO
|
|
|
|
.BR pidfd_send_signal ()
|
|
|
|
is Linux specific.
|
|
|
|
.SH NOTES
|
|
|
|
Currently, there is no glibc wrapper for this system call; call it using
|
|
|
|
.BR syscall (2).
|
|
|
|
.\"
|
|
|
|
.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 * 3
|
|
|
|
by opening a
|
|
|
|
.IR /proc/[pid]
|
|
|
|
directory;
|
|
|
|
.IP *
|
|
|
|
using
|
|
|
|
.BR pidfd_open (2);
|
|
|
|
or
|
|
|
|
.IP *
|
|
|
|
via the PID file descriptor that is returned by a call to
|
|
|
|
.BR clone (2)
|
|
|
|
or
|
|
|
|
.BR clone3 (2)
|
|
|
|
that specifies the
|
|
|
|
.BR CLONE_PIDFD
|
|
|
|
flag.
|
|
|
|
.PP
|
|
|
|
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 ()
|
2019-09-24 19:54:03 +00:00
|
|
|
fails with the error
|
|
|
|
.BR ESRCH .
|
2020-05-21 08:00:37 +00:00
|
|
|
.SH EXAMPLES
|
2019-09-22 21:06:21 +00:00
|
|
|
.nf
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <limits.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/syscall.h>
|
|
|
|
|
|
|
|
#ifndef __NR_pidfd_send_signal
|
|
|
|
#define __NR_pidfd_send_signal 424
|
|
|
|
#endif
|
|
|
|
|
2019-09-23 09:43:32 +00:00
|
|
|
static int
|
|
|
|
pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
|
2019-09-22 21:06:21 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
siginfo_t info;
|
|
|
|
char path[PATH_MAX];
|
|
|
|
int pidfd, sig;
|
|
|
|
|
|
|
|
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 \(aqsiginfo_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);
|
|
|
|
}
|
|
|
|
.fi
|
|
|
|
.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)
|