bionic spawn: simplify implementation by relying on kernel's close_range() syscall
This is valid now that we only support 5.10+ kernels for 25Q4+.
See https://docs.partner.android.com/partners/guides/gki/whatsnew
January 10, 2025 -- ACK Branch Announcements (4.19 and 5.4)
Since the Android version numbers are now bumped in Q2 instead of Q3, the last platform release that will support 5.4 kernels is the 25Q2 release. The 25Q3 and 25Q4 releases will not support 5.4 kernels. All 5.4 kernels will reach EOL on January 1, 2026.
I have no need to drop 5.4 support in 25Q3, but I do want to start using 5.10 only features (like bpf ringbuffers) in 25Q4.
Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I37e79b3a910aa01fcc5725e3df8867e88f24da1a
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index d97057f..f1b8eb0 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -42,28 +42,6 @@
#include "private/ScopedSignalBlocker.h"
-static int set_cloexec(int i) {
- int v = fcntl(i, F_GETFD);
- if (v == -1) return -1; // almost certainly: errno == EBADF
- return fcntl(i, F_SETFD, v | FD_CLOEXEC);
-}
-
-// mark all open fds except stdin/out/err as close-on-exec
-static int cloexec_except_stdioe() {
- // requires 5.11+ or ACK 5.10-T kernel, otherwise returns ENOSYS or EINVAL
- if (!close_range(3, ~0U, CLOSE_RANGE_CLOEXEC)) return 0;
-
- // unfortunately getrlimit can lie:
- // - both soft and hard limits can be lowered to 0, with fds still open, so it can underestimate
- // - in practice it usually is some really large value (like 32K or more)
- // even though only a handful of small fds are actually open (ie. < 500),
- // this results in poor performance when trying to act on all possibly open fds
- struct rlimit m;
- int max = getrlimit(RLIMIT_NOFILE, &m) ? 1000000 : m.rlim_max;
- for (int i = 3; i < max; ++i) set_cloexec(i);
- return 0;
-}
-
enum Action {
kOpen,
kClose,
@@ -175,7 +153,8 @@
}
if ((flags & POSIX_SPAWN_CLOEXEC_DEFAULT) != 0) {
- if (cloexec_except_stdioe()) _exit(127);
+ // mark all open fds except stdin/out/err as close-on-exec
+ if (close_range(3, ~0U, CLOSE_RANGE_CLOEXEC)) _exit(127);
}
}