diff options
| author | Julian Andres Klode <jak@debian.org> | 2025-10-20 16:11:37 +0000 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2025-10-20 16:11:37 +0000 |
| commit | 683214eed4aced71f94f12a0cc70509bdb473c82 (patch) | |
| tree | cd51616b1f6b42c7d3e53a39f1400e292b6ea476 /apt-pkg | |
| parent | 86be82f9877e29cb27de98c8680026df28e99af4 (diff) | |
| parent | 6aca3716f051b5b6bff63d51fff68b9c7ebc7474 (diff) | |
Merge branch 'close-range' into 'main'
ExecFork: Use close_range() if available
See merge request apt-team/apt!524
Diffstat (limited to 'apt-pkg')
| -rw-r--r-- | apt-pkg/contrib/fileutl.cc | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 85997275c..50b983924 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -85,6 +85,7 @@ #include <endian.h> #if __gnu_linux__ +#include <linux/close_range.h> #include <sys/prctl.h> #endif @@ -919,8 +920,37 @@ pid_t ExecFork(std::set<int> KeepFDs) signal(SIGCONT,SIG_DFL); signal(SIGTSTP,SIG_DFL); - DIR *dir = opendir("/proc/self/fd"); - if (dir != NULL) +#ifdef CLOSE_RANGE_CLOEXEC + // Close all our file descriptors using close_range() if available. This is substantially + // faster than the naive method and may be faster than the /proc/self/fd one. + { + // Used for testing. + auto DebugCloseRange = _config->FindB("Debug::CloseRange", false); + int first = 3; + for (auto keep : KeepFDs) + { + if (keep > first) + { + if (DebugCloseRange) + std::clog << "close_range(" << first << ", " << keep - 1 << ")" << std::endl; + if (close_range(first, keep - 1, CLOSE_RANGE_CLOEXEC)) + goto err; + } + first = keep + 1; + } + if (DebugCloseRange) + std::clog << "close_range(" << first << ", " << ~0U << ")" << std::endl; + if (close_range(first, ~0U, CLOSE_RANGE_CLOEXEC)) + goto err; + + return Process; + err: + if (DebugCloseRange) + std::clog << "close_range() failed" << std::endl; + // fallthrough + } +#endif + if (DIR *dir = opendir("/proc/self/fd")) { struct dirent *ent; while ((ent = readdir(dir))) |
