1pidfd_open(2) System Calls Manual pidfd_open(2)
2
3
4
6 pidfd_open - obtain a file descriptor that refers to a process
7
9 Standard C library (libc, -lc)
10
12 #include <sys/syscall.h> /* Definition of SYS_* constants */
13 #include <unistd.h>
14
15 int syscall(SYS_pidfd_open, pid_t pid, unsigned int flags);
16
17 Note: glibc provides no wrapper for pidfd_open(), necessitating the use
18 of syscall(2).
19
21 The pidfd_open() system call creates a file descriptor that refers to
22 the process whose PID is specified in pid. The file descriptor is re‐
23 turned as the function result; the close-on-exec flag is set on the
24 file descriptor.
25
26 The flags argument either has the value 0, or contains the following
27 flag:
28
29 PIDFD_NONBLOCK (since Linux 5.10)
30 Return a nonblocking file descriptor. If the process referred
31 to by the file descriptor has not yet terminated, then an at‐
32 tempt to wait on the file descriptor using waitid(2) will imme‐
33 diately return the error EAGAIN rather than blocking.
34
36 On success, pidfd_open() returns a file descriptor (a nonnegative inte‐
37 ger). On error, -1 is returned and errno is set to indicate the error.
38
40 EINVAL flags is not valid.
41
42 EINVAL pid is not valid.
43
44 EMFILE The per-process limit on the number of open file descriptors has
45 been reached (see the description of RLIMIT_NOFILE in getr‐
46 limit(2)).
47
48 ENFILE The system-wide limit on the total number of open files has been
49 reached.
50
51 ENODEV The anonymous inode filesystem is not available in this kernel.
52
53 ENOMEM Insufficient kernel memory was available.
54
55 ESRCH The process specified by pid does not exist.
56
58 Linux.
59
61 Linux 5.3.
62
64 The following code sequence can be used to obtain a file descriptor for
65 the child of fork(2):
66
67 pid = fork();
68 if (pid > 0) { /* If parent */
69 pidfd = pidfd_open(pid, 0);
70 ...
71 }
72
73 Even if the child has already terminated by the time of the
74 pidfd_open() call, its PID will not have been recycled and the returned
75 file descriptor will refer to the resulting zombie process. Note, how‐
76 ever, that this is guaranteed only if the following conditions hold
77 true:
78
79 • the disposition of SIGCHLD has not been explicitly set to SIG_IGN
80 (see sigaction(2));
81
82 • the SA_NOCLDWAIT flag was not specified while establishing a handler
83 for SIGCHLD or while setting the disposition of that signal to
84 SIG_DFL (see sigaction(2)); and
85
86 • the zombie process was not reaped elsewhere in the program (e.g.,
87 either by an asynchronously executed signal handler or by wait(2) or
88 similar in another thread).
89
90 If any of these conditions does not hold, then the child process (along
91 with a PID file descriptor that refers to it) should instead be created
92 using clone(2) with the CLONE_PIDFD flag.
93
94 Use cases for PID file descriptors
95 A PID file descriptor returned by pidfd_open() (or by clone(2) with the
96 CLONE_PID flag) can be used for the following purposes:
97
98 • The pidfd_send_signal(2) system call can be used to send a signal to
99 the process referred to by a PID file descriptor.
100
101 • A PID file descriptor can be monitored using poll(2), select(2), and
102 epoll(7). When the process that it refers to terminates, these in‐
103 terfaces indicate the file descriptor as readable. Note, however,
104 that in the current implementation, nothing can be read from the
105 file descriptor (read(2) on the file descriptor fails with the error
106 EINVAL).
107
108 • If the PID file descriptor refers to a child of the calling process,
109 then it can be waited on using waitid(2).
110
111 • The pidfd_getfd(2) system call can be used to obtain a duplicate of
112 a file descriptor of another process referred to by a PID file de‐
113 scriptor.
114
115 • A PID file descriptor can be used as the argument of setns(2) in or‐
116 der to move into one or more of the same namespaces as the process
117 referred to by the file descriptor.
118
119 • A PID file descriptor can be used as the argument of process_mad‐
120 vise(2) in order to provide advice on the memory usage patterns of
121 the process referred to by the file descriptor.
122
123 The pidfd_open() system call is the preferred way of obtaining a PID
124 file descriptor for an already existing process. The alternative is to
125 obtain a file descriptor by opening a /proc/pid directory. However,
126 the latter technique is possible only if the proc(5) filesystem is
127 mounted; furthermore, the file descriptor obtained in this way is not
128 pollable and can't be waited on with waitid(2).
129
131 The program below opens a PID file descriptor for the process whose PID
132 is specified as its command-line argument. It then uses poll(2) to
133 monitor the file descriptor for process exit, as indicated by an
134 EPOLLIN event.
135
136 Program source
137
138 #define _GNU_SOURCE
139 #include <poll.h>
140 #include <stdio.h>
141 #include <stdlib.h>
142 #include <sys/syscall.h>
143 #include <unistd.h>
144
145 static int
146 pidfd_open(pid_t pid, unsigned int flags)
147 {
148 return syscall(SYS_pidfd_open, pid, flags);
149 }
150
151 int
152 main(int argc, char *argv[])
153 {
154 int pidfd, ready;
155 struct pollfd pollfd;
156
157 if (argc != 2) {
158 fprintf(stderr, "Usage: %s <pid>\n", argv[0]);
159 exit(EXIT_SUCCESS);
160 }
161
162 pidfd = pidfd_open(atoi(argv[1]), 0);
163 if (pidfd == -1) {
164 perror("pidfd_open");
165 exit(EXIT_FAILURE);
166 }
167
168 pollfd.fd = pidfd;
169 pollfd.events = POLLIN;
170
171 ready = poll(&pollfd, 1, -1);
172 if (ready == -1) {
173 perror("poll");
174 exit(EXIT_FAILURE);
175 }
176
177 printf("Events (%#x): POLLIN is %sset\n", pollfd.revents,
178 (pollfd.revents & POLLIN) ? "" : "not ");
179
180 close(pidfd);
181 exit(EXIT_SUCCESS);
182 }
183
185 clone(2), kill(2), pidfd_getfd(2), pidfd_send_signal(2), poll(2),
186 process_madvise(2), select(2), setns(2), waitid(2), epoll(7)
187
188
189
190Linux man-pages 6.05 2023-05-03 pidfd_open(2)