]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/pidfd_send_signal.2
sched_setattr.2: tfix
[thirdparty/man-pages.git] / man2 / pidfd_send_signal.2
1 .\" Copyright (c) 2019 by Michael Kerrisk <mtk.manpages@gmail.com>
2 .\"
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
7 .\"
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
12 .\"
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
19 .\" professionally.
20 .\"
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" %%%LICENSE_END
24 .\"
25 .TH PIDFD_SEND_SIGNAL 2 2019-09-19 "Linux" "Linux Programmer's Manual"
26 .SH NAME
27 pidfd_send_signal \- send a signal to a process specified by a file descriptor
28 .SH SYNOPSIS
29 .nf
30 .B "#include <signal.h>"
31 .PP
32 .BI "int pidfd_send_signal(int " pidfd ", int " sig ", siginfo_t *" info ,
33 .BI " unsigned int " flags );
34 .fi
35 .SH DESCRIPTION
36 The
37 .BR pidfd_send_signal ()
38 system call sends the signal
39 .I sig
40 to the target process referred to by
41 .IR pidfd ,
42 a PID file descriptor that refers to a process.
43 .\" See the very detailed commit message for kernel commit
44 .\" 3eb39f47934f9d5a3027fe00d906a45fe3a15fad
45 .PP
46 If the
47 .I info
48 argument points to a
49 .I siginfo_t
50 buffer, that buffer should be populated as described in
51 .BR rt_sigqueueinfo (2).
52 .PP
53 If the
54 .I info
55 argument is a NULL pointer,
56 this is equivalent to specifying a pointer to a
57 .I siginfo_t
58 buffer whose fields match the values that are
59 implicitly supplied when a signal is sent using
60 .BR kill (2):
61 .PP
62 .PD 0
63 .IP * 3
64 .I si_signo
65 is set to the signal number;
66 .IP *
67 .I si_errno
68 is set to 0;
69 .IP *
70 .I si_code
71 is set to
72 .BR SI_USER;
73 .IP *
74 .I si_pid
75 is set to the caller's PID; and
76 .IP *
77 .I si_uid
78 is set to the caller's real user ID.
79 .PD
80 .PP
81 The calling process must either be in the same PID namespace as the
82 process referred to by
83 .IR pidfd ,
84 or be in an ancestor of that namespace.
85 .PP
86 The
87 .I flags
88 argument is reserved for future use;
89 currently, this argument must be specified as 0.
90 .SH RETURN VALUE
91 On success,
92 .BR pidfd_send_signal ()
93 returns 0.
94 On error, \-1 is returned and
95 .I errno
96 is set to indicate the cause of the error.
97 .SH ERRORS
98 .TP
99 .B EBADF
100 .I pidfd
101 is not a valid PID file descriptor.
102 .TP
103 .B EINVAL
104 .I sig
105 is not a valid signal.
106 .TP
107 .B EINVAL
108 The calling process is not in a PID namespace from which it can
109 send a signal to the target process.
110 .TP
111 .B EINVAL
112 .I flags
113 is not 0.
114 .TP
115 .B EPERM
116 The calling process does not have permission to send the signal
117 to the target process.
118 .TP
119 .B EPERM
120 .I pidfd
121 doesn't refer to the calling process, and
122 .IR info.si_code
123 is invalid (see
124 .BR rt_sigqueueinfo (2)).
125 .TP
126 .B ESRCH
127 The target process does not exist
128 (i.e., it has terminated and been waited on).
129 .SH VERSIONS
130 .BR pidfd_send_signal ()
131 first appeared in Linux 5.1.
132 .SH CONFORMING TO
133 .BR pidfd_send_signal ()
134 is Linux specific.
135 .SH NOTES
136 Currently, there is no glibc wrapper for this system call; call it using
137 .BR syscall (2).
138 .\"
139 .SS PID file descriptors
140 The
141 .I pidfd
142 argument is a PID file descriptor,
143 a file descriptor that refers to process.
144 Such a file descriptor can be obtained in any of the following ways:
145 .IP * 3
146 by opening a
147 .IR /proc/[pid]
148 directory;
149 .IP *
150 using
151 .BR pidfd_open (2);
152 or
153 .IP *
154 via the PID file descriptor that is returned by a call to
155 .BR clone (2)
156 or
157 .BR clone3 (2)
158 that specifies the
159 .BR CLONE_PIDFD
160 flag.
161 .PP
162 The
163 .BR pidfd_send_signal ()
164 system call allows the avoidance of race conditions that occur
165 when using traditional interfaces (such as
166 .BR kill (2))
167 to signal a process.
168 The problem is that the traditional interfaces specify the target process
169 via a process ID (PID),
170 with the result that the sender may accidentally send a signal to
171 the wrong process if the originally intended target process
172 has terminated and its PID has been recycled for another process.
173 By contrast,
174 a PID file descriptor is a stable reference to a specific process;
175 if that process terminates,
176 .BR pidfd_send_signal ()
177 fails with the error
178 .BR ESRCH .
179 .SH EXAMPLE
180 .nf
181 #define _GNU_SOURCE
182 #include <limits.h>
183 #include <signal.h>
184 #include <fcntl.h>
185 #include <stdio.h>
186 #include <string.h>
187 #include <stdlib.h>
188 #include <unistd.h>
189 #include <sys/syscall.h>
190
191 #ifndef __NR_pidfd_send_signal
192 #define __NR_pidfd_send_signal 424
193 #endif
194
195 static int
196 pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
197 unsigned int flags)
198 {
199 return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
200 }
201
202 int
203 main(int argc, char *argv[])
204 {
205 siginfo_t info;
206 char path[PATH_MAX];
207 int pidfd, sig;
208
209 if (argc != 3) {
210 fprintf(stderr, "Usage: %s <pid> <signal>\en", argv[0]);
211 exit(EXIT_FAILURE);
212 }
213
214 sig = atoi(argv[2]);
215
216 /* Obtain a PID file descriptor by opening the /proc/PID directory
217 of the target process */
218
219 snprintf(path, sizeof(path), "/proc/%s", argv[1]);
220
221 pidfd = open(path, O_RDONLY);
222 if (pidfd == \-1) {
223 perror("open");
224 exit(EXIT_FAILURE);
225 }
226
227 /* Populate a \(aqsiginfo_t\(aq structure for use with
228 pidfd_send_signal() */
229
230 memset(&info, 0, sizeof(info));
231 info.si_code = SI_QUEUE;
232 info.si_signo = sig;
233 info.si_errno = 0;
234 info.si_uid = getuid();
235 info.si_pid = getpid();
236 info.si_value.sival_int = 1234;
237
238 /* Send the signal */
239
240 if (pidfd_send_signal(pidfd, sig, &info, 0) == \-1) {
241 perror("pidfd_send_signal");
242 exit(EXIT_FAILURE);
243 }
244
245 exit(EXIT_SUCCESS);
246 }
247 .fi
248 .SH SEE ALSO
249 .BR clone (2),
250 .BR kill (2),
251 .BR pidfd_open (2),
252 .BR rt_sigqueueinfo (2),
253 .BR sigaction (2),
254 .BR pid_namespaces (7),
255 .BR signal (7)