* [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-21 20:11 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; as well as URLs for NNTP newsgroup(s).