libutil: deal with Linux systems that do not implement close_range
Seems a little bit Rich that musl does not implement close_range because they suspect that the system call itself is a bad idea, so they uhhhh are considering not implementing a wrapper. Let's just fix the problem at hand by writing our own wrapper. Change-Id: I1f8e5858e4561d58a5450503d9c4585aded2b216
This commit is contained in:
parent
b15d5cc6ee
commit
b9ed79c99a
2 changed files with 19 additions and 2 deletions
|
@ -417,6 +417,11 @@ check_funcs = [
|
||||||
'strsignal',
|
'strsignal',
|
||||||
'sysconf',
|
'sysconf',
|
||||||
]
|
]
|
||||||
|
if target_machine.kernel() in ['linux', 'freebsd']
|
||||||
|
# musl does not have close_range as of 2024-08-10
|
||||||
|
# patch: https://www.openwall.com/lists/musl/2024/08/01/9
|
||||||
|
check_funcs += [ 'close_range' ]
|
||||||
|
endif
|
||||||
foreach funcspec : check_funcs
|
foreach funcspec : check_funcs
|
||||||
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
|
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
|
||||||
define_value = cxx.has_function(funcspec).to_int()
|
define_value = cxx.has_function(funcspec).to_int()
|
||||||
|
|
|
@ -223,15 +223,27 @@ void closeExtraFDs()
|
||||||
constexpr int MAX_KEPT_FD = 2;
|
constexpr int MAX_KEPT_FD = 2;
|
||||||
static_assert(std::max({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) == MAX_KEPT_FD);
|
static_assert(std::max({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) == MAX_KEPT_FD);
|
||||||
|
|
||||||
#if __linux__
|
// 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
|
||||||
|
#ifdef 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
|
// 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
|
// 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
|
// 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.
|
// to the old method. we should remove that though, in some future.
|
||||||
if (close_range(3, ~0U, 0) == 0) {
|
if (closeRange(3, ~0U, 0) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __linux__
|
||||||
try {
|
try {
|
||||||
for (auto & s : readDirectory("/proc/self/fd")) {
|
for (auto & s : readDirectory("/proc/self/fd")) {
|
||||||
auto fd = std::stoi(s.name);
|
auto fd = std::stoi(s.name);
|
||||||
|
|
Loading…
Reference in a new issue