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

DESCRIPTION

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

RETURN VALUE

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

ERRORS

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

VERSIONS

49       close_range() first appeared in Linux 5.9.  Library support  was  added
50       in glibc in version 2.34.
51

CONFORMING TO

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

NOTES

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

EXAMPLES

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

SEE ALSO

192       close(2)
193

COLOPHON

195       This  page  is  part of release 5.13 of the Linux man-pages project.  A
196       description of the project, information about reporting bugs,  and  the
197       latest     version     of     this    page,    can    be    found    at
198       https://www.kernel.org/doc/man-pages/.
199
200
201
202Linux                             2021-08-27                    CLOSE_RANGE(2)
Impressum