Skip to content

Commit

Permalink
Use close_range when available
Browse files Browse the repository at this point in the history
This fixes the FreeBSD build of nix-util

(cherry picked from commit 5c87c40)

# Conflicts:
#	src/libutil/unix/file-descriptor.cc
  • Loading branch information
roberth authored and mergify[bot] committed Sep 19, 2024
1 parent fc1d6b2 commit 3bd3919
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static char buf[1024];]],
AC_LANG_POP(C++)


AC_CHECK_FUNCS([statvfs pipe2])
AC_CHECK_FUNCS([statvfs pipe2 close_range])


# Check for lutimes, optionally used for changing the mtime of
Expand Down
1 change: 1 addition & 0 deletions src/libutil/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ subdir('build-utils-meson/subprojects')
# HAVE_LUTIMES 1`. The `#define` is unconditional, 0 for not found and 1
# for found. One therefore uses it with `#if` not `#ifdef`.
check_funcs = [
'close_range',
# Optionally used for changing the mtime of symlinks.
'lutimes',
# Optionally used for creating pipes on Unix
Expand Down
29 changes: 29 additions & 0 deletions src/libutil/unix/file-descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,37 @@ void Pipe::create()

//////////////////////////////////////////////////////////////////////

<<<<<<< HEAD
void unix::closeMostFDs(const std::set<int> & exceptions)
{
=======
#if __linux__ || __FreeBSD__
static int unix_close_range(unsigned int first, unsigned int last, int flags)
{
#if !HAVE_CLOSE_RANGE
return syscall(SYS_close_range, first, last, (unsigned int)flags);
#else
return close_range(first, last, flags);
#endif
}
#endif

void unix::closeExtraFDs()
{
constexpr int MAX_KEPT_FD = 2;
static_assert(std::max({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) == MAX_KEPT_FD);

#if __linux__ || __FreeBSD__
// 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 (unix_close_range(MAX_KEPT_FD + 1, ~0U, 0) == 0) {
return;
}
#endif

>>>>>>> 5c87c40a5 (Use close_range when available)
#if __linux__
try {
for (auto & s : std::filesystem::directory_iterator{"/proc/self/fd"}) {
Expand Down

0 comments on commit 3bd3919

Please sign in to comment.