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
This commit is contained in:
parent
35a2f28a46
commit
c7d97802e4
3 changed files with 18 additions and 8 deletions
|
@ -1618,7 +1618,7 @@ void LocalDerivationGoal::runChild()
|
|||
throw SysError("changing into '%1%'", tmpDir);
|
||||
|
||||
/* Close all other file descriptors. */
|
||||
closeMostFDs({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO});
|
||||
closeExtraFDs();
|
||||
|
||||
setPersonality(drv->platform);
|
||||
|
||||
|
|
|
@ -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,8 +247,7 @@ 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))
|
||||
for (int fd = MAX_KEPT_FD + 1; fd < maxFD; ++fd)
|
||||
close(fd); /* ignore result */
|
||||
}
|
||||
|
||||
|
|
|
@ -66,10 +66,10 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* Close all file descriptors except those listed in the given set.
|
||||
* Close all file descriptors except stdio fds (ie 0, 1, 2).
|
||||
* Good practice in child processes.
|
||||
*/
|
||||
void closeMostFDs(const std::set<int> & exceptions);
|
||||
void closeExtraFDs();
|
||||
|
||||
/**
|
||||
* Set the close-on-exec flag for the given file descriptor.
|
||||
|
|
Loading…
Reference in a new issue