libutil, libstore: move closeExtraFDs to derivation goal
it's only used there. Change-Id: I61ee47d37214c59c073cc9ed671ac1c82430227c
This commit is contained in:
@@ -1199,6 +1199,52 @@ void LocalDerivationGoal::chownToBuilder(const AutoCloseFD & fd)
|
||||
throw SysError("cannot change ownership of file '%1%'", fd.guessOrInventPath());
|
||||
}
|
||||
|
||||
static void closeExtraFDs()
|
||||
{
|
||||
constexpr int MAX_KEPT_FD = 2;
|
||||
static_assert(std::max({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) == MAX_KEPT_FD);
|
||||
|
||||
// Both Linux and FreeBSD support close_range.
|
||||
#if __linux__ || __FreeBSD__
|
||||
auto closeRange = [](unsigned int first, unsigned int last, int flags) -> int {
|
||||
// musl does not have close_range as of 2024-08-10
|
||||
// patch: https://www.openwall.com/lists/musl/2024/08/01/9
|
||||
#if HAVE_CLOSE_RANGE
|
||||
return close_range(first, last, flags);
|
||||
#else
|
||||
return syscall(SYS_close_range, first, last, flags);
|
||||
#endif
|
||||
};
|
||||
// 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 (closeRange(3, ~0U, 0) == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __linux__
|
||||
try {
|
||||
for (auto & s : readDirectory("/proc/self/fd")) {
|
||||
auto fd = std::stoi(s.name);
|
||||
if (fd > MAX_KEPT_FD) {
|
||||
debug("closing leaked FD %d", fd);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch (SysError &) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int maxFD = 0;
|
||||
maxFD = sysconf(_SC_OPEN_MAX);
|
||||
for (int fd = MAX_KEPT_FD + 1; fd < maxFD; ++fd) {
|
||||
close(fd); /* ignore result */
|
||||
}
|
||||
}
|
||||
|
||||
void LocalDerivationGoal::runChild(const Path & builder, const Strings & envStrs, const Strings & args)
|
||||
{
|
||||
/* Warning: in the child we should absolutely not make any SQLite
|
||||
|
||||
@@ -268,52 +268,6 @@ void Pipe::close()
|
||||
writeSide.close();
|
||||
}
|
||||
|
||||
|
||||
void closeExtraFDs()
|
||||
{
|
||||
constexpr int MAX_KEPT_FD = 2;
|
||||
static_assert(std::max({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) == MAX_KEPT_FD);
|
||||
|
||||
// Both Linux and FreeBSD support close_range.
|
||||
#if __linux__ || __FreeBSD__
|
||||
auto closeRange = [](unsigned int first, unsigned int last, int flags) -> int {
|
||||
// musl does not have close_range as of 2024-08-10
|
||||
// patch: https://www.openwall.com/lists/musl/2024/08/01/9
|
||||
#if HAVE_CLOSE_RANGE
|
||||
return close_range(first, last, flags);
|
||||
#else
|
||||
return syscall(SYS_close_range, first, last, flags);
|
||||
#endif
|
||||
};
|
||||
// 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 (closeRange(3, ~0U, 0) == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __linux__
|
||||
try {
|
||||
for (auto & s : readDirectory("/proc/self/fd")) {
|
||||
auto fd = std::stoi(s.name);
|
||||
if (fd > MAX_KEPT_FD) {
|
||||
debug("closing leaked FD %d", fd);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch (SysError &) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int maxFD = 0;
|
||||
maxFD = sysconf(_SC_OPEN_MAX);
|
||||
for (int fd = MAX_KEPT_FD + 1; fd < maxFD; ++fd)
|
||||
close(fd); /* ignore result */
|
||||
}
|
||||
|
||||
void closeOnExec(int fd, bool doClose)
|
||||
{
|
||||
int prev;
|
||||
|
||||
@@ -101,12 +101,6 @@ private:
|
||||
SocketPair(AutoCloseFD a, AutoCloseFD b) : a(std::move(a)), b(std::move(b)) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Close all file descriptors except stdio fds (ie 0, 1, 2).
|
||||
* Good practice in child processes.
|
||||
*/
|
||||
void closeExtraFDs();
|
||||
|
||||
/**
|
||||
* Set or clear the close-on-exec flag for the given file descriptor.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user