diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc index ee4ef0681..4f1f277d6 100644 --- a/lix/libstore/build/local-derivation-goal.cc +++ b/lix/libstore/build/local-derivation-goal.cc @@ -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 diff --git a/lix/libutil/file-descriptor.cc b/lix/libutil/file-descriptor.cc index 5d1d6f1e0..1875a3473 100644 --- a/lix/libutil/file-descriptor.cc +++ b/lix/libutil/file-descriptor.cc @@ -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; diff --git a/lix/libutil/file-descriptor.hh b/lix/libutil/file-descriptor.hh index 15e2bfc77..d899d23f8 100644 --- a/lix/libutil/file-descriptor.hh +++ b/lix/libutil/file-descriptor.hh @@ -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. */