readv2: Note preadv2(..., RWF_NOWAIT) bug in BUGS section
[man-pages.git] / man2 / close_range.2
blobca84dc448d93d5bf85d6ca30a8dfc03ef5b04bf8
1 .\" Copyright (c) 2020 Stephen Kitt <steve@sk2.org>
2 .\" and Copyright (c) 2021 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
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.
8 .\"
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.
13 .\"
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
20 .\" professionally.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
24 .\" %%%LICENSE_END
25 .\"
26 .TH CLOSE_RANGE 2 2021-03-22 "Linux" "Linux Programmer's Manual"
27 .SH NAME
28 close_range \- close all file descriptors in a given range
29 .SH SYNOPSIS
30 .nf
31 .B #include <linux/close_range.h>
32 .PP
33 .BI "int close_range(unsigned int " first ", unsigned int " last ,
34 .BI "                unsigned int " flags );
35 .fi
36 .PP
37 .IR Note :
38 There is no glibc wrapper for this system call; see NOTES.
39 .SH DESCRIPTION
40 The
41 .BR close_range ()
42 system call closes all open file descriptors from
43 .I first
45 .I last
46 (included).
47 .PP
48 Errors closing a given file descriptor are currently ignored.
49 .PP
50 .I flags
51 is a bit mask containing 0 or more of the following:
52 .TP
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.
56 .TP
57 .B CLOSE_RANGE_UNSHARE
58 Unshare the specified file descriptors from any other processes
59 before closing them,
60 avoiding races with other threads sharing the file descriptor table.
61 .SH RETURN VALUE
62 On success,
63 .BR close_range ()
64 returns 0.
65 On error, \-1 is returned and
66 .I errno
67 is set to indicate the error.
68 .SH ERRORS
69 .TP
70 .B EINVAL
71 .I flags
72 is not valid, or
73 .I first
74 is greater than
75 .IR last .
76 .PP
77 The following can occur with
78 .B CLOSE_RANGE_UNSHARE
79 (when constructing the new descriptor table):
80 .TP
81 .B EMFILE
82 The number of open file descriptors exceeds the limit specified in
83 .IR /proc/sys/fs/nr_open
84 (see
85 .BR proc (5)).
86 This error can occur in situations where that limit was lowered before
87 a call to
88 .BR close_range ()
89 where the
90 .B CLOSE_RANGE_UNSHARE
91 flag is specified.
92 .TP
93 .B ENOMEM
94 Insufficient kernel memory was available.
95 .SH VERSIONS
96 .BR close_range ()
97 first appeared in Linux 5.9.
98 Library support was added in glibc in version 2.34.
99 .SH CONFORMING TO
100 .BR close_range ()
101 is a nonstandard function that is also present on FreeBSD.
102 .SH NOTES
103 Glibc does not provide a wrapper for this system call; call it using
104 .BR syscall (2).
105 .SS Closing all open file descriptors
106 .\" 278a5fbaed89dacd04e9d052f4594ffd0e0585de
107 To avoid blindly closing file descriptors
108 in the range of possible file descriptors,
109 this is sometimes implemented (on Linux)
110 by listing open file descriptors in
111 .I /proc/self/fd/
112 and calling
113 .BR close (2)
114 on each one.
115 .BR close_range ()
116 can take care of this without requiring
117 .I /proc
118 and within a single system call,
119 which provides significant performance benefits.
120 .SS Closing file descriptors before exec
121 .\" 60997c3d45d9a67daf01c56d805ae4fec37e0bd8
122 File descriptors can be closed safely using
124 .in +4n
126 /* we don't want anything past stderr here */
127 close_range(3, ~0U, CLOSE_RANGE_UNSHARE);
128 execve(....);
132 .B CLOSE_RANGE_UNSHARE
133 is conceptually equivalent to
135 .in +4n
137 unshare(CLONE_FILES);
138 close_range(first, last, 0);
142 but can be more efficient:
143 if the unshared range extends past
144 the current maximum number of file descriptors allocated
145 in the caller's file descriptor table
146 (the common case when
147 .I last
148 is ~0U),
149 the kernel will unshare a new file descriptor table for the caller up to
150 .IR first ,
151 copying as few file descriptors as possible.
152 This avoids subsequent
153 .BR close (2)
154 calls entirely;
155 the whole operation is complete once the table is unshared.
156 .SS Closing files on \fBexec\fP
157 .\" 582f1fb6b721facf04848d2ca57f34468da1813e
158 This is particularly useful in cases where multiple
159 .RB pre- exec
160 setup steps risk conflicting with each other.
161 For example, setting up a
162 .BR seccomp (2)
163 profile can conflict with a
164 .BR close_range ()
165 call:
166 if the file descriptors are closed before the
167 .BR seccomp (2)
168 profile is set up,
169 the profile setup can't use them itself,
170 or control their closure;
171 if the file descriptors are closed afterwards,
172 the seccomp profile can't block the
173 .BR close_range ()
174 call or any fallbacks.
175 Using
176 .B CLOSE_RANGE_CLOEXEC
177 avoids this:
178 the descriptors can be marked before the
179 .BR seccomp (2)
180 profile is set up,
181 and the profile can control access to
182 .BR close_range ()
183 without affecting the calling process.
184 .SH EXAMPLES
185 The program shown below opens the files named in its command-line arguments,
186 displays the list of files that it has opened
187 (by iterating through the entries in
188 .IR /proc/PID/fd ),
189 uses
190 .BR close_range ()
191 to close all file descriptors greater than or equal to 3,
192 and then once more displays the process's list of open files.
193 The following example demonstrates the use of the program:
195 .in +4n
197 $ \fBtouch /tmp/a /tmp/b /tmp/c\fP
198 $ \fB./a.out /tmp/a /tmp/b /tmp/c\fP
199 /tmp/a opened as FD 3
200 /tmp/b opened as FD 4
201 /tmp/c opened as FD 5
202 /proc/self/fd/0 ==> /dev/pts/1
203 /proc/self/fd/1 ==> /dev/pts/1
204 /proc/self/fd/2 ==> /dev/pts/1
205 /proc/self/fd/3 ==> /tmp/a
206 /proc/self/fd/4 ==> /tmp/b
207 /proc/self/fd/5 ==> /tmp/b
208 /proc/self/fd/6 ==> /proc/9005/fd
209 ========= About to call close_range() =======
210 /proc/self/fd/0 ==> /dev/pts/1
211 /proc/self/fd/1 ==> /dev/pts/1
212 /proc/self/fd/2 ==> /dev/pts/1
213 /proc/self/fd/3 ==> /proc/9005/fd
217 Note that the lines showing the pathname
218 .I /proc/9005/fd
219 result from the calls to
220 .BR opendir (3).
221 .SS Program source
224 #define _GNU_SOURCE
225 #include <fcntl.h>
226 #include <linux/close_range.h>
227 #include <stdio.h>
228 #include <stdlib.h>
229 #include <sys/syscall.h>
230 #include <string.h>
231 #include <unistd.h>
232 #include <dirent.h>
234 /* Show the contents of the symbolic links in /proc/self/fd */
236 static void
237 show_fds(void)
239     DIR *dirp = opendir("/proc/self/fd");
240     if (dirp  == NULL) {
241         perror("opendir");
242         exit(EXIT_FAILURE);
243     }
245     for (;;) {
246         struct dirent *dp = readdir(dirp);
247         if (dp == NULL)
248             break;
250         if (dp\->d_type == DT_LNK) {
251             char path[PATH_MAX], target[PATH_MAX];
252             snprintf(path, sizeof(path), "/proc/self/fd/%s",
253                      dp\->d_name);
255             ssize_t len = readlink(path, target, sizeof(target));
256             printf("%s ==> %.*s\en", path, (int) len, target);
257         }
258     }
260     closedir(dirp);
264 main(int argc, char *argv[])
266     for (int j = 1; j < argc; j++) {
267         int fd = open(argv[j], O_RDONLY);
268         if (fd == \-1) {
269             perror(argv[j]);
270             exit(EXIT_FAILURE);
271         }
272         printf("%s opened as FD %d\en", argv[j], fd);
273     }
275     show_fds();
277     printf("========= About to call close_range() =======\en");
279     if (syscall(__NR_close_range, 3, \(ti0U, 0) == \-1) {
280         perror("close_range");
281         exit(EXIT_FAILURE);
282     }
284     show_fds();
285     exit(EXIT_FAILURE);
288 .SH SEE ALSO
289 .BR close (2)