1CLOSE_RANGE(2)             Linux Programmer's Manual            CLOSE_RANGE(2)
2
3
4

NAME

6       close_range - close all file descriptors in a given range
7

SYNOPSIS

9       #include <linux/close_range.h>
10
11       int close_range(unsigned int first, unsigned int last,
12                       unsigned int flags);
13
14       Note: There is no glibc wrapper for this system call; see NOTES.
15

DESCRIPTION

17       The  close_range()  system  call  closes all open file descriptors from
18       first to last (included).
19
20       Errors closing a given file descriptor are currently ignored.
21
22       flags is a bit mask containing 0 or more of the following:
23
24       CLOSE_RANGE_CLOEXEC (since Linux 5.11)
25              Set the close-on-exec flag on the  specified  file  descriptors,
26              rather than immediately closing them.
27
28       CLOSE_RANGE_UNSHARE
29              Unshare  the specified file descriptors from any other processes
30              before closing them, avoiding races with other  threads  sharing
31              the file descriptor table.
32

RETURN VALUE

34       On  success, close_range() returns 0.  On error, -1 is returned and er‐
35       rno is set to indicate the error.
36

ERRORS

38       EINVAL flags is not valid, or first is greater than last.
39
40       The following can occur with CLOSE_RANGE_UNSHARE (when constructing the
41       new descriptor table):
42
43       EMFILE The  number of open file descriptors exceeds the limit specified
44              in /proc/sys/fs/nr_open (see proc(5)).  This error can occur  in
45              situations  where  that  limit  was  lowered  before  a  call to
46              close_range() where the CLOSE_RANGE_UNSHARE flag is specified.
47
48       ENOMEM Insufficient kernel memory was available.
49

VERSIONS

51       close_range() first appeared in Linux 5.9.
52

CONFORMING TO

54       close_range() is a nonstandard function that is also present  on  Free‐
55       BSD.
56

NOTES

58       Glibc  does  not  provide a wrapper for this system call; call it using
59       syscall(2).
60
61   Closing all open file descriptors
62       To avoid blindly closing file descriptors in the range of possible file
63       descriptors,  this  is sometimes implemented (on Linux) by listing open
64       file descriptors in /proc/self/fd/ and calling close(2)  on  each  one.
65       close_range()  can take care of this without requiring /proc and within
66       a single system call, which provides significant performance benefits.
67
68   Closing file descriptors before exec
69       File descriptors can be closed safely using
70
71           /* we don't want anything past stderr here */
72           close_range(3, ~0U, CLOSE_RANGE_UNSHARE);
73           execve(....);
74
75       CLOSE_RANGE_UNSHARE is conceptually equivalent to
76
77           unshare(CLONE_FILES);
78           close_range(first, last, 0);
79
80       but can be more efficient: if the unshared range extends past the  cur‐
81       rent  maximum number of file descriptors allocated in the caller's file
82       descriptor table (the common case when last is ~0U),  the  kernel  will
83       unshare a new file descriptor table for the caller up to first, copying
84       as few file descriptors as possible.  This avoids  subsequent  close(2)
85       calls  entirely;  the whole operation is complete once the table is un‐
86       shared.
87
88   Closing files on exec
89       This is particularly useful in  cases  where  multiple  pre-exec  setup
90       steps risk conflicting with each other.  For example, setting up a sec‐
91       comp(2) profile can conflict with a close_range() call: if the file de‐
92       scriptors  are closed before the seccomp(2) profile is set up, the pro‐
93       file setup can't use them itself, or control their closure; if the file
94       descriptors  are closed afterwards, the seccomp profile can't block the
95       close_range() call or any fallbacks.  Using CLOSE_RANGE_CLOEXEC  avoids
96       this:  the  descriptors  can be marked before the seccomp(2) profile is
97       set up, and the profile can control access to close_range() without af‐
98       fecting the calling process.
99

EXAMPLES

101       The program shown below opens the files named in its command-line argu‐
102       ments, displays the list of files that  it  has  opened  (by  iterating
103       through  the  entries in /proc/PID/fd), uses close_range() to close all
104       file descriptors greater than or equal to 3, and then  once  more  dis‐
105       plays  the  process's list of open files.  The following example demon‐
106       strates the use of the program:
107
108           $ touch /tmp/a /tmp/b /tmp/c
109           $ ./a.out /tmp/a /tmp/b /tmp/c
110           /tmp/a opened as FD 3
111           /tmp/b opened as FD 4
112           /tmp/c opened as FD 5
113           /proc/self/fd/0 ==> /dev/pts/1
114           /proc/self/fd/1 ==> /dev/pts/1
115           /proc/self/fd/2 ==> /dev/pts/1
116           /proc/self/fd/3 ==> /tmp/a
117           /proc/self/fd/4 ==> /tmp/b
118           /proc/self/fd/5 ==> /tmp/b
119           /proc/self/fd/6 ==> /proc/9005/fd
120           ========= About to call close_range() =======
121           /proc/self/fd/0 ==> /dev/pts/1
122           /proc/self/fd/1 ==> /dev/pts/1
123           /proc/self/fd/2 ==> /dev/pts/1
124           /proc/self/fd/3 ==> /proc/9005/fd
125
126       Note that the lines showing the pathname /proc/9005/fd result from  the
127       calls to opendir(3).
128
129   Program source
130
131       #define _GNU_SOURCE
132       #include <fcntl.h>
133       #include <linux/close_range.h>
134       #include <stdio.h>
135       #include <stdlib.h>
136       #include <sys/syscall.h>
137       #include <string.h>
138       #include <unistd.h>
139       #include <dirent.h>
140
141       /* Show the contents of the symbolic links in /proc/self/fd */
142
143       static void
144       show_fds(void)
145       {
146           DIR *dirp = opendir("/proc/self/fd");
147           if (dirp  == NULL) {
148               perror("opendir");
149               exit(EXIT_FAILURE);
150           }
151
152           for (;;) {
153               struct dirent *dp = readdir(dirp);
154               if (dp == NULL)
155                   break;
156
157               if (dp->d_type == DT_LNK) {
158                   char path[PATH_MAX], target[PATH_MAX];
159                   snprintf(path, sizeof(path), "/proc/self/fd/%s",
160                            dp->d_name);
161
162                   ssize_t len = readlink(path, target, sizeof(target));
163                   printf("%s ==> %.*s\n", path, (int) len, target);
164               }
165           }
166
167           closedir(dirp);
168       }
169
170       int
171       main(int argc, char *argv[])
172       {
173           for (int j = 1; j < argc; j++) {
174               int fd = open(argv[j], O_RDONLY);
175               if (fd == -1) {
176                   perror(argv[j]);
177                   exit(EXIT_FAILURE);
178               }
179               printf("%s opened as FD %d\n", argv[j], fd);
180           }
181
182           show_fds();
183
184           printf("========= About to call close_range() =======\n");
185
186           if (syscall(__NR_close_range, 3, ~0U, 0) == -1) {
187               perror("close_range");
188               exit(EXIT_FAILURE);
189           }
190
191           show_fds();
192           exit(EXIT_FAILURE);
193       }
194

SEE ALSO

196       close(2)
197

COLOPHON

199       This  page  is  part of release 5.12 of the Linux man-pages project.  A
200       description of the project, information about reporting bugs,  and  the
201       latest     version     of     this    page,    can    be    found    at
202       https://www.kernel.org/doc/man-pages/.
203
204
205
206Linux                             2021-03-22                    CLOSE_RANGE(2)
Impressum