1 .\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org>
2 .\" and Copyright (c) 2021 Michael Kerrisk <mtk.manpages@gmail.com>
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date. The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein. The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
26 .TH CLOSE_RANGE 2 2021-03-22 "Linux" "Linux Programmer's Manual"
28 close_range \- close all file descriptors in a given range
31 .B #include <linux/close_range.h>
33 .BI "int close_range(unsigned int " first ", unsigned int " last ,
34 .BI " unsigned int " flags );
38 There is no glibc wrapper for this system call; see NOTES.
42 system call closes all open file descriptors from
48 Errors closing a given file descriptor are currently ignored.
51 is a bit mask containing 0 or more of the following:
53 .BR CLOSE_RANGE_CLOEXEC " (since Linux 5.11)"
54 Set the close-on-exec flag on the specified file descriptors,
55 rather than immediately closing them.
57 .B CLOSE_RANGE_UNSHARE
58 Unshare the specified file descriptors from any other processes
60 avoiding races with other threads sharing the file descriptor table.
65 On error, \-1 is returned and
67 is set to indicate the error.
77 The following can occur with
78 .B CLOSE_RANGE_UNSHARE
79 (when constructing the new descriptor table):
82 The number of open file descriptors exceeds the limit specified in
83 .IR /proc/sys/fs/nr_open
86 This error can occur in situations where that limit was lowered before
90 .B CLOSE_RANGE_UNSHARE
94 Insufficient kernel memory was available.
97 first appeared in Linux 5.9.
100 is a nonstandard function that is also present on FreeBSD.
102 Glibc does not provide a wrapper for this system call; call it using
104 .SS Closing all open file descriptors
105 .\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de
106 To avoid blindly closing file descriptors
107 in the range of possible file descriptors,
108 this is sometimes implemented (on Linux)
109 by listing open file descriptors in
115 can take care of this without requiring
117 and within a single system call,
118 which provides significant performance benefits.
119 .SS Closing file descriptors before exec
120 .\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8
121 File descriptors can be closed safely using
125 /* we don't want anything past stderr here */
126 close_range(3, ~0U, CLOSE_RANGE_UNSHARE);
131 .B CLOSE_RANGE_UNSHARE
132 is conceptually equivalent to
136 unshare(CLONE_FILES);
137 close_range(first, last, 0);
141 but can be more efficient:
142 if the unshared range extends past
143 the current maximum number of file descriptors allocated
144 in the caller's file descriptor table
145 (the common case when
148 the kernel will unshare a new file descriptor table for the caller up to
150 copying as few file descriptors as possible.
151 This avoids subsequent
154 the whole operation is complete once the table is unshared.
155 .SS Closing files on \fBexec\fP
156 .\" 582f1fb6b721facf04848d2ca57f34468da1813e
157 This is particularly useful in cases where multiple
159 setup steps risk conflicting with each other.
160 For example, setting up a
162 profile can conflict with a
165 if the file descriptors are closed before the
168 the profile setup can't use them itself,
169 or control their closure;
170 if the file descriptors are closed afterwards,
171 the seccomp profile can't block the
173 call or any fallbacks.
175 .B CLOSE_RANGE_CLOEXEC
177 the descriptors can be marked before the
180 and the profile can control access to
182 without affecting the calling process.
184 The program shown below opens the files named in its command-line arguments,
185 displays the list of files that it has opened
186 (by iterating through the entries in
190 to close all file descriptors greater than or equal to 3,
191 and then once more displays the process's list of open files.
192 The following example demonstrates the use of the program:
196 $ \fBtouch /tmp/a /tmp/b /tmp/c\fP
197 $ \fB./a.out /tmp/a /tmp/b /tmp/c\fP
198 /tmp/a opened as FD 3
199 /tmp/b opened as FD 4
200 /tmp/c opened as FD 5
201 /proc/self/fd/0 ==> /dev/pts/1
202 /proc/self/fd/1 ==> /dev/pts/1
203 /proc/self/fd/2 ==> /dev/pts/1
204 /proc/self/fd/3 ==> /tmp/a
205 /proc/self/fd/4 ==> /tmp/b
206 /proc/self/fd/5 ==> /tmp/b
207 /proc/self/fd/6 ==> /proc/9005/fd
208 ========= About to call close_range() =======
209 /proc/self/fd/0 ==> /dev/pts/1
210 /proc/self/fd/1 ==> /dev/pts/1
211 /proc/self/fd/2 ==> /dev/pts/1
212 /proc/self/fd/3 ==> /proc/9005/fd
216 Note that the lines showing the pathname
218 result from the calls to
225 #include <linux/close_range.h>
228 #include <sys/syscall.h>
233 /* Show the contents of the symbolic links in /proc/self/fd */
238 DIR *dirp = opendir("/proc/self/fd");
245 struct dirent *dp = readdir(dirp);
249 if (dp\->d_type == DT_LNK) {
250 char path[PATH_MAX], target[PATH_MAX];
251 snprintf(path, sizeof(path), "/proc/self/fd/%s",
254 ssize_t len = readlink(path, target, sizeof(target));
255 printf("%s ==> %.*s\en", path, (int) len, target);
263 main(int argc, char *argv[])
265 for (int j = 1; j < argc; j++) {
266 int fd = open(argv[j], O_RDONLY);
271 printf("%s opened as FD %d\en", argv[j], fd);
276 printf("========= About to call close_range() =======\en");
278 if (syscall(__NR_close_range, 3, \(ti0U, 0) == \-1) {
279 perror("close_range");