aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/file-descriptor.cc
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-08-09 21:17:52 +0200
committereldritch horrors <pennae@lix.systems>2024-08-09 19:59:17 +0000
commitc7d97802e4f59b8621e67cf62275d6a7fde8fe62 (patch)
tree8798b34ab28dd2b704da20a21659de2ad24fda07 /src/libutil/file-descriptor.cc
parent35a2f28a46613ad185b96d6e38c3f5d13bfc79b5 (diff)
libutil: rename and optimize closeMostFDs
this is only used to close non-stdio files in derivation sandboxes. we may as well encode that in its name, drop the unnecessary integer set, and use close_range to deal with the actual closing of files. not only is this clearer, it also makes sandbox setup on linux fast by 1ms each Change-Id: Id90e259a49c7bc896189e76bfbbf6ef2c0bcd3b2
Diffstat (limited to 'src/libutil/file-descriptor.cc')
-rw-r--r--src/libutil/file-descriptor.cc20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/libutil/file-descriptor.cc b/src/libutil/file-descriptor.cc
index be9f8c889..4807869f9 100644
--- a/src/libutil/file-descriptor.cc
+++ b/src/libutil/file-descriptor.cc
@@ -218,13 +218,24 @@ void Pipe::close()
}
-void closeMostFDs(const std::set<int> & exceptions)
+void closeExtraFDs()
{
+ constexpr int MAX_KEPT_FD = 2;
+ static_assert(std::max({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) == MAX_KEPT_FD);
+
#if __linux__
+ // first try to close_range everything we don't care about. if this
+ // returns an error with these parameters we're running on a kernel
+ // that does not implement close_range (i.e. pre 5.9) and fall back
+ // to the old method. we should remove that though, in some future.
+ if (close_range(3, ~0U, 0) == 0) {
+ return;
+ }
+
try {
for (auto & s : readDirectory("/proc/self/fd")) {
auto fd = std::stoi(s.name);
- if (!exceptions.count(fd)) {
+ if (fd > MAX_KEPT_FD) {
debug("closing leaked FD %d", fd);
close(fd);
}
@@ -236,9 +247,8 @@ void closeMostFDs(const std::set<int> & exceptions)
int maxFD = 0;
maxFD = sysconf(_SC_OPEN_MAX);
- for (int fd = 0; fd < maxFD; ++fd)
- if (!exceptions.count(fd))
- close(fd); /* ignore result */
+ for (int fd = MAX_KEPT_FD + 1; fd < maxFD; ++fd)
+ close(fd); /* ignore result */
}