[PATCH] openat2.2, pipe.2, prctl.2: Document O_SPECIFIC_FD and PR_INCREASE_MIN_FD
From: Josh Triplett
Date:  Wed Apr 22 2020 - 00:54:25 EST
Signed-off-by: Josh Triplett <josh@xxxxxxxxxxxxxxxx>
---
 man2/openat2.2 | 83 ++++++++++++++++++++++++++++++++++++++++++++++++--
 man2/pipe.2    | 42 +++++++++++++++++++++++++
 man2/prctl.2   | 12 ++++++++
 3 files changed, 134 insertions(+), 3 deletions(-)
diff --git a/man2/openat2.2 b/man2/openat2.2
index fb976f259..994210ad1 100644
--- a/man2/openat2.2
+++ b/man2/openat2.2
@@ -103,9 +103,11 @@ This argument is a pointer to a structure of the following form:
 .in +4n
 .EX
 struct open_how {
-    u64 flags;    /* O_* flags */
-    u64 mode;     /* Mode for O_{CREAT,TMPFILE} */
-    u64 resolve;  /* RESOLVE_* flags */
+    u64 flags;     /* O_* flags */
+    u64 mode;      /* Mode for O_{CREAT,TMPFILE} */
+    u64 resolve;   /* RESOLVE_* flags */
+    u32 fd;        /* File descriptor for O_SPECIFIC_FD */
+    u32 __padding; /* Must be zeroed */
     /* ... */
 };
 .EE
@@ -147,6 +149,12 @@ argument,
 .BR openat2 ()
 returns an error if unknown or conflicting flags are specified in
 .IR how.flags .
+.IP
+The flag
+.B O_SPECIFIC_FD
+is only valid for openat2, as it requires the
+.I fd
+field.
 .TP
 .I mode
 This field specifies the
@@ -390,6 +398,48 @@ so that a pathname component (now) contains a bind mount.
 If any bits other than those listed above are set in
 .IR how.resolve ,
 an error is returned.
+.TP
+.I fd
+If
+.I flags
+contains
+.BR O_SPECIFIC_FD ,
+.BR openat2 ()
+will allocate and return that specific file descriptor, rather than using the
+lowest available file descriptor.
+If
+.I fd
+contains \-1,
+.BR openat2 ()
+will return the lowest available file descriptor just as if
+.B O_SPECIFIC_FD
+had not been specified.
+.IP
+The caller may wish to use the
+.BR prctl (2)
+option
+.B PR_INCREASE_MIN_FD
+to reserve a range of file descriptors for such usage.
+.IP
+If the specified file descriptor is already in use,
+.BR openat2 ()
+will return \-1 and set
+.I errno
+to
+.BR EBUSY .
+.IP
+If
+.I flags
+does not contain
+.BR O_SPECIFIC_FD ,
+.I fd
+must be zero.
+.TP
+.I __padding
+This value must be zero, and must not be referenced by name.
+Future versions of the
+.I open_how
+structure may give a new name and semantic to this field.
 .SH RETURN VALUE
 On success, a new file descriptor is returned.
 On error, \-1 is returned, and
@@ -421,6 +471,26 @@ The caller may choose to retry the
 .BR openat2 ()
 call.
 .TP
+.B EBUSY
+.I how.flags
+contains
+.B O_SPECIFIC_FD
+and the file descriptor specified in
+.I fd
+was in use.
+.TP
+.B EMFILE
+.I how.flags
+contains
+.B O_SPECIFIC_FD
+and
+.I how.fd
+exceeds the maximum file descriptor allowed for the process
+(see the description of
+.BR RLIMIT_NOFILE
+in
+.BR getrlimit (2)).
+.TP
 .B EINVAL
 An unknown flag or invalid value was specified in
 .IR how .
@@ -435,6 +505,13 @@ or
 .BR O_TMPFILE .
 .TP
 .B EINVAL
+.I how.fd
+is non-zero, but
+.I how.flags
+does not contain
+.BR O_SPECIFIC_FD .
+.TP
+.B EINVAL
 .I size
 was smaller than any known version of
 .IR "struct open_how" .
diff --git a/man2/pipe.2 b/man2/pipe.2
index 4a5a10567..af07b9c59 100644
--- a/man2/pipe.2
+++ b/man2/pipe.2
@@ -146,6 +146,31 @@ referred to by the new file descriptors.
 Using this flag saves extra calls to
 .BR fcntl (2)
 to achieve the same result.
+.TP
+.B O_SPECIFIC_FD
+Rather than allocating the next available file descriptors, read the file
+descriptor values specified in
+.I pipefd
+and allocate those specific file descriptors.
+If one or both of the entries in
+.I pipefd
+contains \-1,
+.BR pipe2 ()
+will allocate the lowest available file descriptor for that end of the pipe as
+usual.
+.IP
+The caller may wish to use the
+.BR prctl (2)
+option
+.B PR_INCREASE_MIN_FD
+to reserve a range of file descriptors for such usage.
+.IP
+If the specified file descriptor is already in use,
+.BR pipe2 ()
+will return \-1 and set
+.I errno
+to
+.BR EBUSY .
 .SH RETURN VALUE
 On success, zero is returned.
 On error, \-1 is returned,
@@ -169,6 +194,12 @@ likewise does not modify
 on failure.
 .SH ERRORS
 .TP
+.B EBUSY
+.I flags
+contains
+.B O_SPECIFIC_FD
+and one of the specified file descriptors was in use.
+.TP
 .B EFAULT
 .I pipefd
 is not valid.
@@ -181,6 +212,17 @@ Invalid value in
 .B EMFILE
 The per-process limit on the number of open file descriptors has been reached.
 .TP
+.B EMFILE
+.I flags
+contains
+.B O_SPECIFIC_FD
+and one of the specified file descriptors exceeds the maximum file descriptor
+allowed for the process
+(see the description of
+.BR RLIMIT_NOFILE
+in
+.BR getrlimit (2)).
+.TP
 .B ENFILE
 The system-wide limit on the total number of open files has been reached.
 .TP
diff --git a/man2/prctl.2 b/man2/prctl.2
index 7a5af76f4..d54d9cb67 100644
--- a/man2/prctl.2
+++ b/man2/prctl.2
@@ -531,6 +531,18 @@ All unused
 .BR prctl ()
 arguments must be zero.
 .TP
+.BR PR_INCREASE_MIN_FD " (since Linux 5.8)"
+Increase the minimum file descriptor that the kernel will automatically
+allocate when the process opens a new file descriptor, by
+.IR arg2 .
+Return (as the function result) the current minimum.
+A process may pass 0 as
+.I arg2
+to return the current minimum without changing it.
+The remaining unused
+.BR prctl ()
+arguments must be zero for future compatibility.
+.TP
 .BR PR_SET_MM " (since Linux 3.3)"
 .\" commit 028ee4be34a09a6d48bdf30ab991ae933a7bc036
 Modify certain kernel memory map descriptor fields
-- 
2.26.2
--5vNYLRcllDrimb99--