1close_range(2)                System Calls Manual               close_range(2)
2
3
4

NAME

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

LIBRARY

9       Standard C library (libc, -lc)
10

SYNOPSIS

12       #include <linux/close_range.h>
13
14       int close_range(unsigned int first, unsigned int last,
15                       unsigned int flags);
16

DESCRIPTION

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

RETURN VALUE

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

ERRORS

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

STANDARDS

52       None.
53

HISTORY

55       FreeBSD.  Linux 5.9, glibc 2.34.
56

NOTES

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

EXAMPLES

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

SEE ALSO

198       close(2)
199
200
201
202Linux man-pages 6.04              2023-03-30                    close_range(2)
Impressum