summaryrefslogtreecommitdiffstats
path: root/man/man2/pidfd_open.2
diff options
context:
space:
mode:
Diffstat (limited to 'man/man2/pidfd_open.2')
-rw-r--r--man/man2/pidfd_open.2269
1 files changed, 269 insertions, 0 deletions
diff --git a/man/man2/pidfd_open.2 b/man/man2/pidfd_open.2
new file mode 100644
index 000000000..02c741f2b
--- /dev/null
+++ b/man/man2/pidfd_open.2
@@ -0,0 +1,269 @@
+.\" Copyright (c) 2019 by Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH pidfd_open 2 (date) "Linux man-pages (unreleased)"
+.SH NAME
+pidfd_open \- obtain a file descriptor that refers to a process
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */"
+.B #include <unistd.h>
+.P
+.BI "int syscall(SYS_pidfd_open, pid_t " pid ", unsigned int " flags );
+.fi
+.P
+.IR Note :
+glibc provides no wrapper for
+.BR pidfd_open (),
+necessitating the use of
+.BR syscall (2).
+.SH DESCRIPTION
+The
+.BR pidfd_open ()
+system call creates a file descriptor that refers to
+the process whose PID is specified in
+.IR pid .
+The file descriptor is returned as the function result;
+the close-on-exec flag is set on the file descriptor.
+.P
+The
+.I flags
+argument either has the value 0, or contains the following flag:
+.TP
+.BR PIDFD_NONBLOCK " (since Linux 5.10)"
+.\" commit 4da9af0014b51c8b015ed8c622440ef28912efe6
+Return a nonblocking file descriptor.
+If the process referred to by the file descriptor has not yet terminated,
+then an attempt to wait on the file descriptor using
+.BR waitid (2)
+will immediately return the error
+.B EAGAIN
+rather than blocking.
+.SH RETURN VALUE
+On success,
+.BR pidfd_open ()
+returns a file descriptor (a nonnegative integer).
+On error, \-1 is returned and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EINVAL
+.I flags
+is not valid.
+.TP
+.B EINVAL
+.I pid
+is not valid.
+.TP
+.B EMFILE
+The per-process limit on the number of open file descriptors has been reached
+(see the description of
+.B RLIMIT_NOFILE
+in
+.BR getrlimit (2)).
+.TP
+.B ENFILE
+The system-wide limit on the total number of open files has been reached.
+.TP
+.B ENODEV
+The anonymous inode filesystem is not available in this kernel.
+.TP
+.B ENOMEM
+Insufficient kernel memory was available.
+.TP
+.B ESRCH
+The process specified by
+.I pid
+does not exist.
+.SH STANDARDS
+Linux.
+.SH HISTORY
+Linux 5.3.
+.SH NOTES
+The following code sequence can be used to obtain a file descriptor
+for the child of
+.BR fork (2):
+.P
+.in +4n
+.EX
+pid = fork();
+if (pid > 0) { /* If parent */
+ pidfd = pidfd_open(pid, 0);
+ ...
+}
+.EE
+.in
+.P
+Even if the child has already terminated by the time of the
+.BR pidfd_open ()
+call, its PID will not have been recycled and the returned
+file descriptor will refer to the resulting zombie process.
+Note, however, that this is guaranteed only if the following
+conditions hold true:
+.IP \[bu] 3
+the disposition of
+.B SIGCHLD
+has not been explicitly set to
+.B SIG_IGN
+(see
+.BR sigaction (2));
+.IP \[bu]
+the
+.B SA_NOCLDWAIT
+flag was not specified while establishing a handler for
+.B SIGCHLD
+or while setting the disposition of that signal to
+.B SIG_DFL
+(see
+.BR sigaction (2));
+and
+.IP \[bu]
+the zombie process was not reaped elsewhere in the program
+(e.g., either by an asynchronously executed signal handler or by
+.BR wait (2)
+or similar in another thread).
+.P
+If any of these conditions does not hold,
+then the child process (along with a PID file descriptor that refers to it)
+should instead be created using
+.BR clone (2)
+with the
+.B CLONE_PIDFD
+flag.
+.\"
+.SS Use cases for PID file descriptors
+A PID file descriptor returned by
+.BR pidfd_open ()
+(or by
+.BR clone (2)
+with the
+.B CLONE_PID
+flag) can be used for the following purposes:
+.IP \[bu] 3
+The
+.BR pidfd_send_signal (2)
+system call can be used to send a signal to the process referred to by
+a PID file descriptor.
+.IP \[bu]
+A PID file descriptor can be monitored using
+.BR poll (2),
+.BR select (2),
+and
+.BR epoll (7).
+When the process that it refers to terminates,
+these interfaces indicate the file descriptor as readable.
+Note, however, that in the current implementation,
+nothing can be read from the file descriptor
+.RB ( read (2)
+on the file descriptor fails with the error
+.BR EINVAL ).
+.IP \[bu]
+If the PID file descriptor refers to a child of the calling process,
+then it can be waited on using
+.BR waitid (2).
+.IP \[bu]
+The
+.BR pidfd_getfd (2)
+system call can be used to obtain a duplicate of a file descriptor
+of another process referred to by a PID file descriptor.
+.IP \[bu]
+A PID file descriptor can be used as the argument of
+.BR setns (2)
+in order to move into one or more of the same namespaces as the process
+referred to by the file descriptor.
+.IP \[bu]
+A PID file descriptor can be used as the argument of
+.BR process_madvise (2)
+in order to provide advice on the memory usage patterns of the process
+referred to by the file descriptor.
+.P
+The
+.BR pidfd_open ()
+system call is the preferred way of obtaining a PID file descriptor
+for an already existing process.
+The alternative is to obtain a file descriptor by opening a
+.IR /proc/ pid
+directory.
+However, the latter technique is possible only if the
+.BR proc (5)
+filesystem is mounted;
+furthermore, the file descriptor obtained in this way is
+.I not
+pollable and can't be waited on with
+.BR waitid (2).
+.SH EXAMPLES
+The program below opens a PID file descriptor for the
+process whose PID is specified as its command-line argument.
+It then uses
+.BR poll (2)
+to monitor the file descriptor for process exit, as indicated by an
+.B EPOLLIN
+event.
+.\"
+.SS Program source
+\&
+.\" SRC BEGIN (pidfd_open.c)
+.EX
+#define _GNU_SOURCE
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+\&
+static int
+pidfd_open(pid_t pid, unsigned int flags)
+{
+ return syscall(SYS_pidfd_open, pid, flags);
+}
+\&
+int
+main(int argc, char *argv[])
+{
+ int pidfd, ready;
+ struct pollfd pollfd;
+\&
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <pid>\en", argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+\&
+ pidfd = pidfd_open(atoi(argv[1]), 0);
+ if (pidfd == \-1) {
+ perror("pidfd_open");
+ exit(EXIT_FAILURE);
+ }
+\&
+ pollfd.fd = pidfd;
+ pollfd.events = POLLIN;
+\&
+ ready = poll(&pollfd, 1, \-1);
+ if (ready == \-1) {
+ perror("poll");
+ exit(EXIT_FAILURE);
+ }
+\&
+ printf("Events (%#x): POLLIN is %sset\en", pollfd.revents,
+ (pollfd.revents & POLLIN) ? "" : "not ");
+\&
+ close(pidfd);
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR clone (2),
+.BR kill (2),
+.BR pidfd_getfd (2),
+.BR pidfd_send_signal (2),
+.BR poll (2),
+.BR process_madvise (2),
+.BR select (2),
+.BR setns (2),
+.BR waitid (2),
+.BR epoll (7)