[RFC PATCH v5 8/9] libcamera: process: Use `close_range()` when available
Barnabás Pőcze
barnabas.pocze at ideasonboard.com
Thu Apr 24 13:41:02 CEST 2025
Use the `close_range()` system call when available as it is simpler
and faster than iterating `/proc/self/fd/`.
Signed-off-by: Barnabás Pőcze <barnabas.pocze at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
meson.build | 4 ++++
src/libcamera/process.cpp | 25 +++++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/meson.build b/meson.build
index 9ba5e2ca9..ae13727eb 100644
--- a/meson.build
+++ b/meson.build
@@ -74,6 +74,10 @@ cc = meson.get_compiler('c')
cxx = meson.get_compiler('cpp')
config_h = configuration_data()
+if cc.has_header_symbol('unistd.h', 'close_range', prefix : '#define _GNU_SOURCE')
+ config_h.set('HAVE_CLOSE_RANGE', 1)
+endif
+
if cc.has_header_symbol('fcntl.h', 'F_ADD_SEALS', prefix : '#define _GNU_SOURCE')
config_h.set('HAVE_FILE_SEALS', 1)
endif
diff --git a/src/libcamera/process.cpp b/src/libcamera/process.cpp
index 369fdb12d..42b56374d 100644
--- a/src/libcamera/process.cpp
+++ b/src/libcamera/process.cpp
@@ -70,6 +70,31 @@ void closeAllFdsExcept(Span<const int> fds)
ASSERT(v.empty() || v.front() >= 0);
+#if HAVE_CLOSE_RANGE
+ /*
+ * At the moment libcamera does not require at least Linux 5.9,
+ * which introduced the `close_range()` system call, so a runtime
+ * check is also needed to make sure that it is supported.
+ */
+ static const bool hasCloseRange = [] {
+ return close_range(~0u, 0, 0) < 0 && errno == EINVAL;
+ }();
+
+ if (hasCloseRange) {
+ unsigned int prev = 0;
+
+ for (unsigned int curr : v) {
+ ASSERT(prev <= curr + 1);
+ if (prev < curr)
+ close_range(prev, curr - 1, 0);
+ prev = curr + 1;
+ }
+
+ close_range(prev, ~0u, 0);
+ return;
+ }
+#endif
+
DIR *dir = opendir("/proc/self/fd");
if (!dir)
return;
--
2.49.0
More information about the libcamera-devel
mailing list