* [PATCH v3] close_range.2: new page documenting close_range(2)
@ 2020-12-18 16:58 Stephen Kitt
2020-12-19 14:00 ` Alejandro Colomar (man-pages)
0 siblings, 1 reply; 7+ messages in thread
From: Stephen Kitt @ 2020-12-18 16:58 UTC (permalink / raw)
To: linux-man, Alejandro Colomar, Michael Kerrisk
Cc: Christian Brauner, Giuseppe Scrivano, linux-kernel, Stephen Kitt
This documents close_range(2) based on information in
278a5fbaed89dacd04e9d052f4594ffd0e0585de,
60997c3d45d9a67daf01c56d805ae4fec37e0bd8, and
582f1fb6b721facf04848d2ca57f34468da1813e.
Signed-off-by: Stephen Kitt <steve@sk2.org>
---
V3: fix synopsis overflow
copy notes from membarrier.2 re the lack of wrapper
semantic newlines
drop non-standard "USE CASES" section heading
add code example
V2: unsigned int to match the kernel declarations
groff and grammar tweaks
CLOSE_RANGE_UNSHARE unshares *and* closes
Explain that EMFILE and ENOMEM can occur with C_R_U
"Conforming to" phrasing
Detailed explanation of CLOSE_RANGE_UNSHARE
Reading /proc isn't common
man2/close_range.2 | 266 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 266 insertions(+)
create mode 100644 man2/close_range.2
diff --git a/man2/close_range.2 b/man2/close_range.2
new file mode 100644
index 000000000..f8f2053ac
--- /dev/null
+++ b/man2/close_range.2
@@ -0,0 +1,266 @@
+.\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org>
+.\"
+.\" %%%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
+.\"
+.TH CLOSE_RANGE 2 2020-12-08 "Linux" "Linux Programmer's Manual"
+.SH NAME
+close_range \- close all file descriptors in a given range
+.SH SYNOPSIS
+.nf
+.B #include <linux/close_range.h>
+.PP
+.BI "int close_range(unsigned int " first ", unsigned int " last ,
+.BI " unsigned int " flags );
+.fi
+.PP
+.IR Note :
+There is no glibc wrapper for this system call; see NOTES.
+.SH DESCRIPTION
+The
+.BR close_range ()
+system call closes all open file descriptors from
+.I first
+to
+.I last
+(included).
+.PP
+Errors closing a given file descriptor are currently ignored.
+.PP
+.I flags
+can be 0 or set to one or both of the following:
+.TP
+.B CLOSE_RANGE_UNSHARE
+unshares the range of file descriptors from any other processes,
+before closing them,
+avoiding races with other threads sharing the file descriptor table.
+.TP
+.BR CLOSE_RANGE_CLOEXEC " (since Linux 5.10)"
+sets the close-on-exec bit instead of immediately closing the file
+descriptors.
+.SH RETURN VALUE
+On success,
+.BR close_range ()
+returns 0.
+On error, \-1 is returned and
+.I errno
+is set to indicate the cause of the error.
+.SH ERRORS
+.TP
+.B EINVAL
+.I flags
+is not valid, or
+.I first
+is greater than
+.IR last .
+.PP
+The following can occur with
+.B CLOSE_RANGE_UNSHARE
+(when constructing the new descriptor table):
+.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 ENOMEM
+Insufficient kernel memory was available.
+.SH VERSIONS
+.BR close_range ()
+first appeared in Linux 5.9.
+.SH CONFORMING TO
+.BR close_range ()
+is a nonstandard function that is also present on FreeBSD.
+.SH NOTES
+Glibc does not provide a wrapper for this system call; call it using
+.BR syscall (2).
+.\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de
+.SS Closing all open file descriptors
+To avoid blindly closing file descriptors in the range of possible
+file descriptors,
+this is sometimes implemented (on Linux) by listing open file
+descriptors in
+.I /proc/self/fd/
+and calling
+.BR close (2)
+on each one.
+.BR close_range ()
+can take care of this without requiring
+.I /proc
+and with a single system call,
+which provides significant performance benefits.
+.\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8
+.SS Closing file descriptors before exec
+File descriptors can be closed safely using
+.PP
+.in +4n
+.EX
+/* we don't want anything past stderr here */
+close_range(3, ~0U, CLOSE_RANGE_UNSHARE);
+execve(....);
+.EE
+.in
+.PP
+.B CLOSE_RANGE_UNSHARE
+is conceptually equivalent to
+.PP
+.in +4n
+.EX
+unshare(CLONE_FILES);
+close_range(first, last, 0);
+.EE
+.in
+.PP
+but can be more efficient:
+if the unshared range extends past the current maximum number of file
+descriptors allocated in the caller's file descriptor table
+(the common case when
+.I last
+is
+.BR ~0U ),
+the kernel will unshare a new file descriptor table for the caller up
+to
+.IR first .
+This avoids subsequent close calls entirely;
+the whole operation is complete once the table is unshared.
+.\" 582f1fb6b721facf04848d2ca57f34468da1813e
+.SS Closing files on \fBexec\fP
+This is particularly useful in cases where multiple
+.RB pre- exec
+setup steps risk conflicting with each other.
+For example, setting up a
+.BR seccomp (2)
+profile can conflict with a
+.B close_range
+call:
+if the file descriptors are closed before the seccomp profile is set
+up,
+the profile setup can't use them control their closure;
+if the file descriptors are closed afterwards,
+the seccomp profile can't block the
+.B close_range
+call or any fallbacks.
+Using
+.B CLOSE_RANGE_CLOEXEC
+avoids this:
+the descriptors can be marked before the seccomp profile is set up,
+and the profile can control access to
+.B close_range
+without affecting the calling process.
+.SH EXAMPLES
+The following program is designed to be execed by the second program
+below.
+It lists its open file descriptors:
+.PP
+.in +4n
+.EX
+/* listopen.c */
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+ struct stat buf;
+
+ for (i = 0; i < 100; i++) {
+ if (!fstat(i, &buf))
+ printf("FD %d is open.\n", i);
+ }
+
+ exit(EXIT_SUCCESS);
+)
+.EE
+.in
+.PP
+This program executes the command given on its command-line after
+opening the files listed after the command,
+and then using
+.B close_range
+to close them:
+.PP
+.in +4n
+.EX
+/* close_range.c */
+
+#include <fcntl.h>
+#include <linux/close_range.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int
+main(int argc, char *argv[])
+{
+ char *newargv[] = { NULL };
+ char *newenviron[] = { NULL };
+ int i;
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s <command-to-run> <files-to-open>\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 2; i < argc; i++) {
+ if (open(argv[i], O_RDONLY) == -1) {
+ perror(argv[i]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (syscall(__NR_close_range, 3, ~0U, CLOSE_RANGE_UNSHARE) == -1) {
+ perror("close_range");
+ exit(EXIT_FAILURE);
+ }
+
+ execve(argv[1], newargv, newenviron);
+ perror("execve");
+ exit(EXIT_FAILURE);
+}
+.EE
+.in
+.PP
+We can use the second program to exec the first as follows:
+.PP
+.in +4n
+.EX
+.RB "$" " make listopen close_range"
+.RB "$" " ./close_range ./listopen /dev/null /dev/zero"
+FD 0 is open.
+FD 1 is open.
+FD 2 is open.
+.EE
+.in
+.PP
+Removing the call to
+.B close_range
+will show different output, with the file descriptors for the named
+files still open.
+.SH SEE ALSO
+.BR close (2)
base-commit: b5dae3959625f5ff378e9edf9139057d1c06bb55
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v3] close_range.2: new page documenting close_range(2) 2020-12-18 16:58 [PATCH v3] close_range.2: new page documenting close_range(2) Stephen Kitt @ 2020-12-19 14:00 ` Alejandro Colomar (man-pages) 2020-12-20 22:00 ` Stephen Kitt 2020-12-21 19:24 ` Stephen Kitt 0 siblings, 2 replies; 7+ messages in thread From: Alejandro Colomar (man-pages) @ 2020-12-19 14:00 UTC (permalink / raw) To: Stephen Kitt, linux-man, Michael Kerrisk Cc: Christian Brauner, Giuseppe Scrivano, linux-kernel Hi Stephen, Please see some comments below. It's looking good ;) Thanks, Alex On 12/18/20 5:58 PM, Stephen Kitt wrote: > This documents close_range(2) based on information in > 278a5fbaed89dacd04e9d052f4594ffd0e0585de, > 60997c3d45d9a67daf01c56d805ae4fec37e0bd8, and > 582f1fb6b721facf04848d2ca57f34468da1813e. > > Signed-off-by: Stephen Kitt <steve@sk2.org> > --- > V3: fix synopsis overflow > copy notes from membarrier.2 re the lack of wrapper > semantic newlines > drop non-standard "USE CASES" section heading > add code example > > V2: unsigned int to match the kernel declarations > groff and grammar tweaks > CLOSE_RANGE_UNSHARE unshares *and* closes > Explain that EMFILE and ENOMEM can occur with C_R_U > "Conforming to" phrasing > Detailed explanation of CLOSE_RANGE_UNSHARE > Reading /proc isn't common > > man2/close_range.2 | 266 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 266 insertions(+) > create mode 100644 man2/close_range.2 > > diff --git a/man2/close_range.2 b/man2/close_range.2 > new file mode 100644 > index 000000000..f8f2053ac > --- /dev/null > +++ b/man2/close_range.2 > @@ -0,0 +1,266 @@ > +.\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org> > +.\" > +.\" %%%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 > +.\" > +.TH CLOSE_RANGE 2 2020-12-08 "Linux" "Linux Programmer's Manual" > +.SH NAME > +close_range \- close all file descriptors in a given range > +.SH SYNOPSIS > +.nf > +.B #include <linux/close_range.h> > +.PP > +.BI "int close_range(unsigned int " first ", unsigned int " last , > +.BI " unsigned int " flags ); > +.fi > +.PP > +.IR Note : > +There is no glibc wrapper for this system call; see NOTES. > +.SH DESCRIPTION > +The > +.BR close_range () > +system call closes all open file descriptors from > +.I first > +to > +.I last > +(included). > +.PP > +Errors closing a given file descriptor are currently ignored. > +.PP > +.I flags > +can be 0 or set to one or both of the following: > +.TP > +.B CLOSE_RANGE_UNSHARE > +unshares the range of file descriptors from any other processes, > +before closing them, > +avoiding races with other threads sharing the file descriptor table. > +.TP > +.BR CLOSE_RANGE_CLOEXEC " (since Linux 5.10)" |sort I prefer alphabetic order rather than adding new items at the bottom. When lists grow, it becomes difficult to find what you're looking for. CLOEXEC should go before UNSHARE. > +sets the close-on-exec bit instead of immediately closing the file > +descriptors. [ sets the close-on-exec bit instead of immediately closing the file descriptors. ] > +.SH RETURN VALUE > +On success, > +.BR close_range () > +returns 0. > +On error, \-1 is returned and > +.I errno > +is set to indicate the cause of the error. > +.SH ERRORS > +.TP > +.B EINVAL > +.I flags > +is not valid, or > +.I first > +is greater than > +.IR last . > +.PP > +The following can occur with > +.B CLOSE_RANGE_UNSHARE > +(when constructing the new descriptor table): > +.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 ENOMEM > +Insufficient kernel memory was available. > +.SH VERSIONS > +.BR close_range () > +first appeared in Linux 5.9. > +.SH CONFORMING TO > +.BR close_range () > +is a nonstandard function that is also present on FreeBSD. > +.SH NOTES > +Glibc does not provide a wrapper for this system call; call it using > +.BR syscall (2). > +.\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de > +.SS Closing all open file descriptors The comment with the commit would be better inside the section it refers to, so: [ .SS Closing all open file descriptors .\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de ] > +To avoid blindly closing file descriptors in the range of possible > +file descriptors, [ To avoid blindly closing file descriptors in the range of possible file descriptors, ] > +this is sometimes implemented (on Linux) by listing open file > +descriptors in [ this is sometimes implemented (on Linux) by listing open file descriptors in ] > +.I /proc/self/fd/ > +and calling > +.BR close (2) > +on each one. > +.BR close_range () > +can take care of this without requiring > +.I /proc > +and with a single system call, s/with/within/ > +which provides significant performance benefits. > +.\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8 > +.SS Closing file descriptors before exec [ .SS Closing file descriptors before exec .\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8 ] > +File descriptors can be closed safely using > +.PP > +.in +4n > +.EX > +/* we don't want anything past stderr here */ > +close_range(3, ~0U, CLOSE_RANGE_UNSHARE); > +execve(....);> +.EE > +.in > +.PP > +.B CLOSE_RANGE_UNSHARE > +is conceptually equivalent to > +.PP > +.in +4n > +.EX > +unshare(CLONE_FILES); > +close_range(first, last, 0); > +.EE > +.in > +.PP > +but can be more efficient: > +if the unshared range extends past the current maximum number of file > +descriptors allocated in the caller's file descriptor table [ if the unshared range extends past the current maximum number of file descriptors allocated in the caller's file descriptor table ] > +(the common case when > +.I last > +is > +.BR ~0U ), Literal values are not (usually) formatted. [ .I last is ~0U), ] > +the kernel will unshare a new file descriptor table for the caller up > +to [ the kernel will unshare a new file descriptor table for the caller up to ] > +.IR first . > +This avoids subsequent close calls entirely; > +the whole operation is complete once the table is unshared. > +.\" 582f1fb6b721facf04848d2ca57f34468da1813e > +.SS Closing files on \fBexec\fP [ .SS Closing files on \fBexec\fP .\" 582f1fb6b721facf04848d2ca57f34468da1813e ] > +This is particularly useful in cases where multiple > +.RB pre- exec > +setup steps risk conflicting with each other. > +For example, setting up a > +.BR seccomp (2) > +profile can conflict with a > +.B close_range .BR close_range () > +call: > +if the file descriptors are closed before the seccomp profile is set .BR seccomp (2) > +up, Please, split at a different point. > +the profile setup can't use them control their closure; I don't understand what you wanted to say. them? > +if the file descriptors are closed afterwards, > +the seccomp profile can't block the > +.B close_range .BR close_range () > +call or any fallbacks. > +Using > +.B CLOSE_RANGE_CLOEXEC > +avoids this: > +the descriptors can be marked before the seccomp profile is set up, .BR seccomp (2) > +and the profile can control access to > +.B close_range .BR close_range () > +without affecting the calling process. > +.SH EXAMPLES > +The following program is designed to be execed by the second program > +below. > +It lists its open file descriptors: > +.PP > +.in +4n > +.EX > +/* listopen.c */ > + > +#include <stdio.h> > +#include <sys/stat.h> > + > +int > +main(int argc, char *argv[]) > +{ > + int i; We use C99 declarations for loop indices. > + struct stat buf; > + > + for (i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) { > + if (!fstat(i, &buf)) > + printf("FD %d is open.\n", i); s/\\/\\e/ see: d1a719857b7eb68f5e5c1c965089038dee683240 I sometimes forget to fix those after copying the program to the page. My solution is to copy the rendered text from the man page to a file and then compile, and those errors become obvious ;) > + } > + > + exit(EXIT_SUCCESS); > +) > +.EE > +.in > +.PP > +This program executes the command given on its command-line after > +opening the files listed after the command, > +and then using s/using/uses/ > +.B close_range .BR close_range () > +to close them: > +.PP > +.in +4n > +.EX > +/* close_range.c */ > + > +#include <fcntl.h> > +#include <linux/close_range.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <sys/stat.h> > +#include <sys/syscall.h> > +#include <sys/types.h> > +#include <unistd.h> > + > +int > +main(int argc, char *argv[]) > +{ > + char *newargv[] = { NULL }; > + char *newenviron[] = { NULL }; > + int i; dd > + > + if (argc < 3) { > + fprintf(stderr, "Usage: %s <command-to-run> <files-to-open>\n", argv[0]); s/\\/\\e/ > + exit(EXIT_FAILURE); > + } > + > + for (i = 2; i < argc; i++) { for (int i = 2; i < argc; i++) { > + if (open(argv[i], O_RDONLY) == -1) { > + perror(argv[i]); > + exit(EXIT_FAILURE); > + } > + } > + > + if (syscall(__NR_close_range, 3, ~0U, CLOSE_RANGE_UNSHARE) == -1) { > + perror("close_range"); > + exit(EXIT_FAILURE); > + } > + > + execve(argv[1], newargv, newenviron); > + perror("execve"); > + exit(EXIT_FAILURE); > +} > +.EE > +.in > +.PP > +We can use the second program to exec the first as follows: > +.PP > +.in +4n > +.EX > +.RB "$" " make listopen close_range" > +.RB "$" " ./close_range ./listopen /dev/null /dev/zero" > +FD 0 is open. > +FD 1 is open. > +FD 2 is open. > +.EE > +.in > +.PP > +Removing the call to > +.B close_range .BR close_range () > +will show different output, with the file descriptors for the named > +files still open. [ will show different output, with the file descriptors for the named files still open. ] > +.SH SEE ALSO > +.BR close (2) > > base-commit: b5dae3959625f5ff378e9edf9139057d1c06bb55 > -- Alejandro Colomar Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/ http://www.alejandro-colomar.es/ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] close_range.2: new page documenting close_range(2) 2020-12-19 14:00 ` Alejandro Colomar (man-pages) @ 2020-12-20 22:00 ` Stephen Kitt 2020-12-21 8:32 ` Alejandro Colomar (man-pages) 2020-12-21 19:24 ` Stephen Kitt 1 sibling, 1 reply; 7+ messages in thread From: Stephen Kitt @ 2020-12-20 22:00 UTC (permalink / raw) To: Alejandro Colomar (man-pages) Cc: linux-man, Michael Kerrisk, Christian Brauner, Giuseppe Scrivano, linux-kernel [-- Attachment #1: Type: text/plain, Size: 12369 bytes --] Hi Alex, On Sat, 19 Dec 2020 15:00:00 +0100, "Alejandro Colomar (man-pages)" <alx.manpages@gmail.com> wrote: > Please see some comments below. > It's looking good ;) Thanks for your review and patience! > On 12/18/20 5:58 PM, Stephen Kitt wrote: > > This documents close_range(2) based on information in > > 278a5fbaed89dacd04e9d052f4594ffd0e0585de, > > 60997c3d45d9a67daf01c56d805ae4fec37e0bd8, and > > 582f1fb6b721facf04848d2ca57f34468da1813e. > > > > Signed-off-by: Stephen Kitt <steve@sk2.org> > > --- > > V3: fix synopsis overflow > > copy notes from membarrier.2 re the lack of wrapper > > semantic newlines > > drop non-standard "USE CASES" section heading > > add code example > > > > V2: unsigned int to match the kernel declarations > > groff and grammar tweaks > > CLOSE_RANGE_UNSHARE unshares *and* closes > > Explain that EMFILE and ENOMEM can occur with C_R_U > > "Conforming to" phrasing > > Detailed explanation of CLOSE_RANGE_UNSHARE > > Reading /proc isn't common > > > > man2/close_range.2 | 266 +++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 266 insertions(+) > > create mode 100644 man2/close_range.2 > > > > diff --git a/man2/close_range.2 b/man2/close_range.2 > > new file mode 100644 > > index 000000000..f8f2053ac > > --- /dev/null > > +++ b/man2/close_range.2 > > @@ -0,0 +1,266 @@ > > +.\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org> > > +.\" > > +.\" %%%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 > > +.\" > > +.TH CLOSE_RANGE 2 2020-12-08 "Linux" "Linux Programmer's Manual" > > +.SH NAME > > +close_range \- close all file descriptors in a given range > > +.SH SYNOPSIS > > +.nf > > +.B #include <linux/close_range.h> > > +.PP > > +.BI "int close_range(unsigned int " first ", unsigned int " last , > > +.BI " unsigned int " flags ); > > +.fi > > +.PP > > +.IR Note : > > +There is no glibc wrapper for this system call; see NOTES. > > +.SH DESCRIPTION > > +The > > +.BR close_range () > > +system call closes all open file descriptors from > > +.I first > > +to > > +.I last > > +(included). > > +.PP > > +Errors closing a given file descriptor are currently ignored. > > +.PP > > +.I flags > > +can be 0 or set to one or both of the following: > > +.TP > > +.B CLOSE_RANGE_UNSHARE > > +unshares the range of file descriptors from any other processes, > > +before closing them, > > +avoiding races with other threads sharing the file descriptor table. > > +.TP > > +.BR CLOSE_RANGE_CLOEXEC " (since Linux 5.10)" > > |sort > > I prefer alphabetic order rather than adding new items at the bottom. > When lists grow, it becomes difficult to find what you're looking for. > > CLOEXEC should go before UNSHARE. That makes sense. > > +sets the close-on-exec bit instead of immediately closing the file > > +descriptors. > > [ > sets the close-on-exec bit instead of > immediately closing the file descriptors. > ] Is this for semantic reasons, or to balance the lines and make them easier to read in the roff source? > > +.SH RETURN VALUE > > +On success, > > +.BR close_range () > > +returns 0. > > +On error, \-1 is returned and > > +.I errno > > +is set to indicate the cause of the error. > > +.SH ERRORS > > +.TP > > +.B EINVAL > > +.I flags > > +is not valid, or > > +.I first > > +is greater than > > +.IR last . > > +.PP > > +The following can occur with > > +.B CLOSE_RANGE_UNSHARE > > +(when constructing the new descriptor table): > > +.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 ENOMEM > > +Insufficient kernel memory was available. > > +.SH VERSIONS > > +.BR close_range () > > +first appeared in Linux 5.9. > > +.SH CONFORMING TO > > +.BR close_range () > > +is a nonstandard function that is also present on FreeBSD. > > +.SH NOTES > > +Glibc does not provide a wrapper for this system call; call it using > > +.BR syscall (2). > > +.\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de > > +.SS Closing all open file descriptors > > The comment with the commit would be better inside the section it refers > to, so: > > [ > .SS Closing all open file descriptors > .\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de > ] Indeed! > > +To avoid blindly closing file descriptors in the range of possible > > +file descriptors, > > [ > To avoid blindly closing file descriptors > in the range of possible file descriptors, > ] > > > +this is sometimes implemented (on Linux) by listing open file > > +descriptors in > > [ > this is sometimes implemented (on Linux) > by listing open file descriptors in > ] > > > +.I /proc/self/fd/ > > +and calling > > +.BR close (2) > > +on each one. > > +.BR close_range () > > +can take care of this without requiring > > +.I /proc > > +and with a single system call, > > s/with/within/ > > > +which provides significant performance benefits. > > +.\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8 > > +.SS Closing file descriptors before exec > > [ > .SS Closing file descriptors before exec > .\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8 > ] > > > +File descriptors can be closed safely using > > +.PP > > +.in +4n > > +.EX > > +/* we don't want anything past stderr here */ > > +close_range(3, ~0U, CLOSE_RANGE_UNSHARE); > > +execve(....);> +.EE > > +.in > > +.PP > > +.B CLOSE_RANGE_UNSHARE > > +is conceptually equivalent to > > +.PP > > +.in +4n > > +.EX > > +unshare(CLONE_FILES); > > +close_range(first, last, 0); > > +.EE > > +.in > > +.PP > > +but can be more efficient: > > +if the unshared range extends past the current maximum number of file > > +descriptors allocated in the caller's file descriptor table > > [ > if the unshared range extends past > the current maximum number of file descriptors allocated > in the caller's file descriptor table > ] > > > +(the common case when > > +.I last > > +is > > +.BR ~0U ), > > Literal values are not (usually) formatted. > > [ > .I last > is ~0U), > ] > > > +the kernel will unshare a new file descriptor table for the caller up > > +to > > [ > the kernel will unshare a new file descriptor table for the caller up to > ] > > > +.IR first . > > +This avoids subsequent close calls entirely; > > +the whole operation is complete once the table is unshared. > > +.\" 582f1fb6b721facf04848d2ca57f34468da1813e > > +.SS Closing files on \fBexec\fP > > [ > .SS Closing files on \fBexec\fP > .\" 582f1fb6b721facf04848d2ca57f34468da1813e > ] > > > +This is particularly useful in cases where multiple > > +.RB pre- exec > > +setup steps risk conflicting with each other. > > +For example, setting up a > > +.BR seccomp (2) > > +profile can conflict with a > > +.B close_range > > .BR close_range () > > > +call: > > +if the file descriptors are closed before the seccomp profile is set > > .BR seccomp (2) > > > +up, > > Please, split at a different point. > > > +the profile setup can't use them control their closure; > > I don't understand what you wanted to say. them? Oops, I meant "the profile setup can't use them itself, or control their closure". > > > +if the file descriptors are closed afterwards, > > +the seccomp profile can't block the > > +.B close_range > > .BR close_range () > > > +call or any fallbacks. > > +Using > > +.B CLOSE_RANGE_CLOEXEC > > +avoids this: > > +the descriptors can be marked before the seccomp profile is set up, > > .BR seccomp (2) > > > +and the profile can control access to > > +.B close_range > > .BR close_range () > > > +without affecting the calling process. > > +.SH EXAMPLES > > +The following program is designed to be execed by the second program > > +below. > > +It lists its open file descriptors: > > +.PP > > +.in +4n > > +.EX > > +/* listopen.c */ > > + > > +#include <stdio.h> > > +#include <sys/stat.h> > > + > > +int > > +main(int argc, char *argv[]) > > +{ > > + int i; > > We use C99 declarations for loop indices. > > > + struct stat buf; > > + > > + for (i = 0; i < 100; i++) { > > for (int i = 0; i < 100; i++) { > > > + if (!fstat(i, &buf)) > > + printf("FD %d is open.\n", i); > > s/\\/\\e/ > > see: d1a719857b7eb68f5e5c1c965089038dee683240 > > I sometimes forget to fix those after copying the program to the page. > My solution is to copy the rendered text from the man page to a file > and then compile, and those errors become obvious ;) Ah yes, good catch. I was looking into automating checks for the source code included in man pages throughout the project, but that throws a spanner in the works! > > > + } > > + > > + exit(EXIT_SUCCESS); > > +) > > +.EE > > +.in > > +.PP > > +This program executes the command given on its command-line after > > +opening the files listed after the command, > > +and then using > > s/using/uses/ > > > +.B close_range > > .BR close_range () > > > +to close them: > > +.PP > > +.in +4n > > +.EX > > +/* close_range.c */ > > + > > +#include <fcntl.h> > > +#include <linux/close_range.h> > > +#include <stdio.h> > > +#include <stdlib.h> > > +#include <sys/stat.h> > > +#include <sys/syscall.h> > > +#include <sys/types.h> > > +#include <unistd.h> > > + > > +int > > +main(int argc, char *argv[]) > > +{ > > + char *newargv[] = { NULL }; > > + char *newenviron[] = { NULL }; > > + int i; > > dd > > > + > > + if (argc < 3) { > > + fprintf(stderr, "Usage: %s <command-to-run> <files-to-open>\n", > > argv[0]); > > s/\\/\\e/ > > > + exit(EXIT_FAILURE); > > + } > > + > > + for (i = 2; i < argc; i++) { > > for (int i = 2; i < argc; i++) { > > > + if (open(argv[i], O_RDONLY) == -1) { > > + perror(argv[i]); > > + exit(EXIT_FAILURE); > > + } > > + } > > + > > + if (syscall(__NR_close_range, 3, ~0U, CLOSE_RANGE_UNSHARE) == -1) { > > + perror("close_range"); > > + exit(EXIT_FAILURE); > > + } > > + > > + execve(argv[1], newargv, newenviron); > > + perror("execve"); > > + exit(EXIT_FAILURE); > > +} > > +.EE > > +.in > > +.PP > > +We can use the second program to exec the first as follows: > > +.PP > > +.in +4n > > +.EX > > +.RB "$" " make listopen close_range" > > +.RB "$" " ./close_range ./listopen /dev/null /dev/zero" > > +FD 0 is open. > > +FD 1 is open. > > +FD 2 is open. > > +.EE > > +.in > > +.PP > > +Removing the call to > > +.B close_range > > .BR close_range () > > > +will show different output, with the file descriptors for the named > > +files still open. > > [ > will show different output, > with the file descriptors for the named files still open. > ] Thanks, I'll send a v4 with all the fixes above. Regards, Stephen [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] close_range.2: new page documenting close_range(2) 2020-12-20 22:00 ` Stephen Kitt @ 2020-12-21 8:32 ` Alejandro Colomar (man-pages) 0 siblings, 0 replies; 7+ messages in thread From: Alejandro Colomar (man-pages) @ 2020-12-21 8:32 UTC (permalink / raw) To: Stephen Kitt Cc: linux-man, Michael Kerrisk, Christian Brauner, Giuseppe Scrivano, linux-kernel On 12/20/20 11:00 PM, Stephen Kitt wrote: > Hi Alex, > > On Sat, 19 Dec 2020 15:00:00 +0100, "Alejandro Colomar (man-pages)" > <alx.manpages@gmail.com> wrote: >> Please see some comments below. >> It's looking good ;) > > Thanks for your review and patience! > >> On 12/18/20 5:58 PM, Stephen Kitt wrote: >>> This documents close_range(2) based on information in >>> 278a5fbaed89dacd04e9d052f4594ffd0e0585de, >>> 60997c3d45d9a67daf01c56d805ae4fec37e0bd8, and >>> 582f1fb6b721facf04848d2ca57f34468da1813e. >>> >>> Signed-off-by: Stephen Kitt <steve@sk2.org> >>> --- >>> V3: fix synopsis overflow >>> copy notes from membarrier.2 re the lack of wrapper >>> semantic newlines >>> drop non-standard "USE CASES" section heading >>> add code example >>> >>> V2: unsigned int to match the kernel declarations >>> groff and grammar tweaks >>> CLOSE_RANGE_UNSHARE unshares *and* closes >>> Explain that EMFILE and ENOMEM can occur with C_R_U >>> "Conforming to" phrasing >>> Detailed explanation of CLOSE_RANGE_UNSHARE >>> Reading /proc isn't common >>> >>> man2/close_range.2 | 266 +++++++++++++++++++++++++++++++++++++++++++++ >>> 1 file changed, 266 insertions(+) >>> create mode 100644 man2/close_range.2 >>> >>> diff --git a/man2/close_range.2 b/man2/close_range.2 >>> new file mode 100644 >>> index 000000000..f8f2053ac >>> --- /dev/null >>> +++ b/man2/close_range.2 >>> @@ -0,0 +1,266 @@ >>> +.\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org> >>> +.\" >>> +.\" %%%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 >>> +.\" >>> +.TH CLOSE_RANGE 2 2020-12-08 "Linux" "Linux Programmer's Manual" >>> +.SH NAME >>> +close_range \- close all file descriptors in a given range >>> +.SH SYNOPSIS >>> +.nf >>> +.B #include <linux/close_range.h> >>> +.PP >>> +.BI "int close_range(unsigned int " first ", unsigned int " last , >>> +.BI " unsigned int " flags ); >>> +.fi >>> +.PP >>> +.IR Note : >>> +There is no glibc wrapper for this system call; see NOTES. >>> +.SH DESCRIPTION >>> +The >>> +.BR close_range () >>> +system call closes all open file descriptors from >>> +.I first >>> +to >>> +.I last >>> +(included). >>> +.PP >>> +Errors closing a given file descriptor are currently ignored. >>> +.PP >>> +.I flags >>> +can be 0 or set to one or both of the following: >>> +.TP >>> +.B CLOSE_RANGE_UNSHARE >>> +unshares the range of file descriptors from any other processes, >>> +before closing them, >>> +avoiding races with other threads sharing the file descriptor table. >>> +.TP >>> +.BR CLOSE_RANGE_CLOEXEC " (since Linux 5.10)" >> >> |sort >> >> I prefer alphabetic order rather than adding new items at the bottom. >> When lists grow, it becomes difficult to find what you're looking for. >> >> CLOEXEC should go before UNSHARE. > > That makes sense. > >>> +sets the close-on-exec bit instead of immediately closing the file >>> +descriptors. >> >> [ >> sets the close-on-exec bit instead of >> immediately closing the file descriptors. >> ] > > Is this for semantic reasons, or to balance the lines and make them easier to > read in the roff source? B is also true, but mostly A. Cheers, Alex > >>> +.SH RETURN VALUE >>> +On success, >>> +.BR close_range () >>> +returns 0. >>> +On error, \-1 is returned and >>> +.I errno >>> +is set to indicate the cause of the error. >>> +.SH ERRORS >>> +.TP >>> +.B EINVAL >>> +.I flags >>> +is not valid, or >>> +.I first >>> +is greater than >>> +.IR last . >>> +.PP >>> +The following can occur with >>> +.B CLOSE_RANGE_UNSHARE >>> +(when constructing the new descriptor table): >>> +.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 ENOMEM >>> +Insufficient kernel memory was available. >>> +.SH VERSIONS >>> +.BR close_range () >>> +first appeared in Linux 5.9. >>> +.SH CONFORMING TO >>> +.BR close_range () >>> +is a nonstandard function that is also present on FreeBSD. >>> +.SH NOTES >>> +Glibc does not provide a wrapper for this system call; call it using >>> +.BR syscall (2). >>> +.\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de >>> +.SS Closing all open file descriptors >> >> The comment with the commit would be better inside the section it refers >> to, so: >> >> [ >> .SS Closing all open file descriptors >> .\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de >> ] > > Indeed! > >>> +To avoid blindly closing file descriptors in the range of possible >>> +file descriptors, >> >> [ >> To avoid blindly closing file descriptors >> in the range of possible file descriptors, >> ] >> >>> +this is sometimes implemented (on Linux) by listing open file >>> +descriptors in >> >> [ >> this is sometimes implemented (on Linux) >> by listing open file descriptors in >> ] >> >>> +.I /proc/self/fd/ >>> +and calling >>> +.BR close (2) >>> +on each one. >>> +.BR close_range () >>> +can take care of this without requiring >>> +.I /proc >>> +and with a single system call, >> >> s/with/within/ >> >>> +which provides significant performance benefits. >>> +.\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8 >>> +.SS Closing file descriptors before exec >> >> [ >> .SS Closing file descriptors before exec >> .\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8 >> ] >> >>> +File descriptors can be closed safely using >>> +.PP >>> +.in +4n >>> +.EX >>> +/* we don't want anything past stderr here */ >>> +close_range(3, ~0U, CLOSE_RANGE_UNSHARE); >>> +execve(....);> +.EE >>> +.in >>> +.PP >>> +.B CLOSE_RANGE_UNSHARE >>> +is conceptually equivalent to >>> +.PP >>> +.in +4n >>> +.EX >>> +unshare(CLONE_FILES); >>> +close_range(first, last, 0); >>> +.EE >>> +.in >>> +.PP >>> +but can be more efficient: >>> +if the unshared range extends past the current maximum number of file >>> +descriptors allocated in the caller's file descriptor table >> >> [ >> if the unshared range extends past >> the current maximum number of file descriptors allocated >> in the caller's file descriptor table >> ] >> >>> +(the common case when >>> +.I last >>> +is >>> +.BR ~0U ), >> >> Literal values are not (usually) formatted. >> >> [ >> .I last >> is ~0U), >> ] >> >>> +the kernel will unshare a new file descriptor table for the caller up >>> +to >> >> [ >> the kernel will unshare a new file descriptor table for the caller up to >> ] >> >>> +.IR first . >>> +This avoids subsequent close calls entirely; >>> +the whole operation is complete once the table is unshared. >>> +.\" 582f1fb6b721facf04848d2ca57f34468da1813e >>> +.SS Closing files on \fBexec\fP >> >> [ >> .SS Closing files on \fBexec\fP >> .\" 582f1fb6b721facf04848d2ca57f34468da1813e >> ] >> >>> +This is particularly useful in cases where multiple >>> +.RB pre- exec >>> +setup steps risk conflicting with each other. >>> +For example, setting up a >>> +.BR seccomp (2) >>> +profile can conflict with a >>> +.B close_range >> >> .BR close_range () >> >>> +call: >>> +if the file descriptors are closed before the seccomp profile is set >> >> .BR seccomp (2) >> >>> +up, >> >> Please, split at a different point. >> >>> +the profile setup can't use them control their closure; >> >> I don't understand what you wanted to say. them? > > Oops, I meant "the profile setup can't use them itself, or control their > closure". > >> >>> +if the file descriptors are closed afterwards, >>> +the seccomp profile can't block the >>> +.B close_range >> >> .BR close_range () >> >>> +call or any fallbacks. >>> +Using >>> +.B CLOSE_RANGE_CLOEXEC >>> +avoids this: >>> +the descriptors can be marked before the seccomp profile is set up, >> >> .BR seccomp (2) >> >>> +and the profile can control access to >>> +.B close_range >> >> .BR close_range () >> >>> +without affecting the calling process. >>> +.SH EXAMPLES >>> +The following program is designed to be execed by the second program >>> +below. >>> +It lists its open file descriptors: >>> +.PP >>> +.in +4n >>> +.EX >>> +/* listopen.c */ >>> + >>> +#include <stdio.h> >>> +#include <sys/stat.h> >>> + >>> +int >>> +main(int argc, char *argv[]) >>> +{ >>> + int i; >> >> We use C99 declarations for loop indices. >> >>> + struct stat buf; >>> + >>> + for (i = 0; i < 100; i++) { >> >> for (int i = 0; i < 100; i++) { >> >>> + if (!fstat(i, &buf)) >>> + printf("FD %d is open.\n", i); >> >> s/\\/\\e/ >> >> see: d1a719857b7eb68f5e5c1c965089038dee683240 >> >> I sometimes forget to fix those after copying the program to the page. >> My solution is to copy the rendered text from the man page to a file >> and then compile, and those errors become obvious ;) > > Ah yes, good catch. I was looking into automating checks for the source code > included in man pages throughout the project, but that throws a spanner in > the works! > >> >>> + } >>> + >>> + exit(EXIT_SUCCESS); >>> +) >>> +.EE >>> +.in >>> +.PP >>> +This program executes the command given on its command-line after >>> +opening the files listed after the command, >>> +and then using >> >> s/using/uses/ >> >>> +.B close_range >> >> .BR close_range () >> >>> +to close them: >>> +.PP >>> +.in +4n >>> +.EX >>> +/* close_range.c */ >>> + >>> +#include <fcntl.h> >>> +#include <linux/close_range.h> >>> +#include <stdio.h> >>> +#include <stdlib.h> >>> +#include <sys/stat.h> >>> +#include <sys/syscall.h> >>> +#include <sys/types.h> >>> +#include <unistd.h> >>> + >>> +int >>> +main(int argc, char *argv[]) >>> +{ >>> + char *newargv[] = { NULL }; >>> + char *newenviron[] = { NULL }; >>> + int i; >> >> dd >> >>> + >>> + if (argc < 3) { >>> + fprintf(stderr, "Usage: %s <command-to-run> <files-to-open>\n", >>> argv[0]); >> >> s/\\/\\e/ >> >>> + exit(EXIT_FAILURE); >>> + } >>> + >>> + for (i = 2; i < argc; i++) { >> >> for (int i = 2; i < argc; i++) { >> >>> + if (open(argv[i], O_RDONLY) == -1) { >>> + perror(argv[i]); >>> + exit(EXIT_FAILURE); >>> + } >>> + } >>> + >>> + if (syscall(__NR_close_range, 3, ~0U, CLOSE_RANGE_UNSHARE) == -1) { >>> + perror("close_range"); >>> + exit(EXIT_FAILURE); >>> + } >>> + >>> + execve(argv[1], newargv, newenviron); >>> + perror("execve"); >>> + exit(EXIT_FAILURE); >>> +} >>> +.EE >>> +.in >>> +.PP >>> +We can use the second program to exec the first as follows: >>> +.PP >>> +.in +4n >>> +.EX >>> +.RB "$" " make listopen close_range" >>> +.RB "$" " ./close_range ./listopen /dev/null /dev/zero" >>> +FD 0 is open. >>> +FD 1 is open. >>> +FD 2 is open. >>> +.EE >>> +.in >>> +.PP >>> +Removing the call to >>> +.B close_range >> >> .BR close_range () >> >>> +will show different output, with the file descriptors for the named >>> +files still open. >> >> [ >> will show different output, >> with the file descriptors for the named files still open. >> ] > > Thanks, I'll send a v4 with all the fixes above. > > Regards, > > Stephen > -- Alejandro Colomar Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/ http://www.alejandro-colomar.es/ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] close_range.2: new page documenting close_range(2) 2020-12-19 14:00 ` Alejandro Colomar (man-pages) 2020-12-20 22:00 ` Stephen Kitt @ 2020-12-21 19:24 ` Stephen Kitt 2020-12-21 19:33 ` Alejandro Colomar (man-pages) 1 sibling, 1 reply; 7+ messages in thread From: Stephen Kitt @ 2020-12-21 19:24 UTC (permalink / raw) To: Alejandro Colomar (man-pages) Cc: linux-man, Michael Kerrisk, Christian Brauner, Giuseppe Scrivano, linux-kernel [-- Attachment #1: Type: text/plain, Size: 506 bytes --] Hi Alex, On Sat, 19 Dec 2020 15:00:00 +0100, "Alejandro Colomar (man-pages)" <alx.manpages@gmail.com> wrote: > On 12/18/20 5:58 PM, Stephen Kitt wrote: [...] > > +This program executes the command given on its command-line after > > +opening the files listed after the command, > > +and then using > > s/using/uses/ It’s the same form as “opening”: “after opening ... and then using”. The overall sequence is “open”, “close_range”, “execve”. Regards, Stephen [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] close_range.2: new page documenting close_range(2) 2020-12-21 19:24 ` Stephen Kitt @ 2020-12-21 19:33 ` Alejandro Colomar (man-pages) 2020-12-21 19:45 ` Stephen Kitt 0 siblings, 1 reply; 7+ messages in thread From: Alejandro Colomar (man-pages) @ 2020-12-21 19:33 UTC (permalink / raw) To: Stephen Kitt Cc: linux-man, Michael Kerrisk, Christian Brauner, Giuseppe Scrivano, linux-kernel Hi Stephen, On 12/21/20 8:24 PM, Stephen Kitt wrote: > Hi Alex, > > On Sat, 19 Dec 2020 15:00:00 +0100, "Alejandro Colomar (man-pages)" > <alx.manpages@gmail.com> wrote: >> On 12/18/20 5:58 PM, Stephen Kitt wrote: > [...] >>> +This program executes the command given on its command-line after >>> +opening the files listed after the command, >>> +and then using >> >> s/using/uses/ > > It’s the same form as “opening”: “after opening ... and then using”. The > overall sequence is “open”, “close_range”, “execve”. > > Regards, > > Stephen > Ahhh. Then I think the comma is misleading. What about the following?: On 12/18/20 5:58 PM, Stephen Kitt wrote: > +.PP > +This program executes the command given on its command-line after > +opening the files listed after the command, > +and then using > +.B close_range > +to close them: This program executes the command given on its command line, after opening the files listed after the command and then using *close_range()* to close them: Thanks, Alex -- Alejandro Colomar Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/ http://www.alejandro-colomar.es/ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] close_range.2: new page documenting close_range(2) 2020-12-21 19:33 ` Alejandro Colomar (man-pages) @ 2020-12-21 19:45 ` Stephen Kitt 0 siblings, 0 replies; 7+ messages in thread From: Stephen Kitt @ 2020-12-21 19:45 UTC (permalink / raw) To: Alejandro Colomar (man-pages) Cc: linux-man, Michael Kerrisk, Christian Brauner, Giuseppe Scrivano, linux-kernel [-- Attachment #1: Type: text/plain, Size: 1277 bytes --] Hi Alex, On Mon, 21 Dec 2020 20:33:06 +0100, "Alejandro Colomar (man-pages)" <alx.manpages@gmail.com> wrote: > On 12/21/20 8:24 PM, Stephen Kitt wrote: > > On Sat, 19 Dec 2020 15:00:00 +0100, "Alejandro Colomar (man-pages)" > > <alx.manpages@gmail.com> wrote: > >> On 12/18/20 5:58 PM, Stephen Kitt wrote: > > [...] > >>> +This program executes the command given on its command-line after > >>> +opening the files listed after the command, > >>> +and then using > >> > >> s/using/uses/ > > > > It’s the same form as “opening”: “after opening ... and then using”. The > > overall sequence is “open”, “close_range”, “execve”. > > Ahhh. Then I think the comma is misleading. > What about the following?: > > > On 12/18/20 5:58 PM, Stephen Kitt wrote: > > +.PP > > +This program executes the command given on its command-line after > > +opening the files listed after the command, > > +and then using > > +.B close_range > > +to close them: > > This program executes the command given on its command line, > after opening the files listed after the command > and then using *close_range()* to close them: Yes, that works better. I’ll follow up with a v5 with just that change. Regards, Stephen [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-12-22 0:51 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-12-18 16:58 [PATCH v3] close_range.2: new page documenting close_range(2) Stephen Kitt 2020-12-19 14:00 ` Alejandro Colomar (man-pages) 2020-12-20 22:00 ` Stephen Kitt 2020-12-21 8:32 ` Alejandro Colomar (man-pages) 2020-12-21 19:24 ` Stephen Kitt 2020-12-21 19:33 ` Alejandro Colomar (man-pages) 2020-12-21 19:45 ` Stephen Kitt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox