[vte] lib: Check for close_range function and use it when available
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] lib: Check for close_range function and use it when available
- Date: Sun, 7 Nov 2021 12:38:30 +0000 (UTC)
commit ebecf6ac04488d0d697c255d582ea891c3bf1577
Author: Christian Persch <chpe src gnome org>
Date: Sun Nov 7 13:38:23 2021 +0100
lib: Check for close_range function and use it when available
This should enable using close_range also on non-linux platforms that
do have close_range, e.g. freebsd and (soon) hurd.
Part of https://gitlab.gnome.org/GNOME/vte/-/issues/2528 .
meson.build | 7 +++++++
src/missing.cc | 29 +++++++++--------------------
src/missing.hh | 11 +++++++++++
src/spawn.cc | 12 ++++++++++++
4 files changed, 39 insertions(+), 20 deletions(-)
---
diff --git a/meson.build b/meson.build
index 09607052..93b7f376 100644
--- a/meson.build
+++ b/meson.build
@@ -325,6 +325,13 @@ check_functions = [
[],
false,
],
+ [
+ 'close_range',
+ 'int (*func)(unsigned int, unsigned int, int)',
+ ['unistd.h'],
+ [],
+ false,
+ ],
# Math functions
diff --git a/src/missing.cc b/src/missing.cc
index 536b1e03..b5a0742e 100644
--- a/src/missing.cc
+++ b/src/missing.cc
@@ -134,17 +134,17 @@ getrlimit_NOFILE_max(void)
return RLIM_INFINITY;
}
-#ifdef __linux__
+#ifndef HAVE_CLOSE_RANGE
-static inline int
-_vte_close_range(int first_fd,
- int last_fd,
- unsigned flags)
+int
+close_range(unsigned int first_fd,
+ unsigned int last_fd,
+ unsigned int flags)
{
-#ifdef SYS_close_range
+#if defined(__linux__) && defined(SYS_close_range)
return syscall(SYS_close_range,
- unsigned(first_fd),
- last_fd == -1 ? ~0u : unsigned(last_fd),
+ first_fd,
+ last_fd == unsigned(-1) ? ~0u : last_fd,
flags);
#else
errno = ENOSYS;
@@ -152,7 +152,7 @@ _vte_close_range(int first_fd,
#endif
}
-#endif /* __linux__ */
+#endif /* !HAVE_CLOSE_RANGE */
/* This function is called between fork and execve/_exit and so must be
* async-signal-safe; see man:signal-safety(7).
@@ -170,17 +170,6 @@ fdwalk(int (*cb)(void *data, int fd),
#ifdef __linux__
- /* First, try close_range(CLOEXEC) which is faster than the methods
- * below, and works even if /proc is not available.
- */
- res = _vte_close_range(0, -1, CLOSE_RANGE_CLOEXEC);
- if (res == 0)
- return 0;
- if (res == -1 &&
- errno != ENOSYS /* old kernel */ &&
- errno != EINVAL /* flags not supported */)
- return res;
-
/* Fall back to iterating over /proc/self/fd.
* Avoid use of opendir/closedir since these are not async-signal-safe.
*/
diff --git a/src/missing.hh b/src/missing.hh
index 7902e41e..0d92f4c7 100644
--- a/src/missing.hh
+++ b/src/missing.hh
@@ -21,12 +21,17 @@
#include <csignal>
#include <fcntl.h>
+#include <unistd.h>
#ifdef __linux__
#include <sys/ioctl.h>
#include <sys/syscall.h>
+#if __has_include(<linux/close_range.h>)
+#include <linux/close_range.h>
+#endif
+
#if defined(__mips__) || defined(__mips64__)
#include <asm/sgidefs.h>
#endif
@@ -48,6 +53,12 @@ char* strchrnul(char const* s,
int c);
#endif
+#ifndef HAVE_CLOSE_RANGE
+int close_range(unsigned int first,
+ unsigned int last,
+ unsigned int flags);
+#endif
+
#ifdef __linux__
/* BEGIN
diff --git a/src/spawn.cc b/src/spawn.cc
index a0d706cd..fd0ec654 100644
--- a/src/spawn.cc
+++ b/src/spawn.cc
@@ -68,6 +68,18 @@ set_cloexec_cb(void* data,
static int
cloexec_from(int fd)
{
+ /* First, try close_range(CLOEXEC) which is faster than the methods
+ * below, and works even if /proc is not available.
+ */
+ auto const res = close_range(fd, -1, CLOSE_RANGE_CLOEXEC);
+ if (res == 0)
+ return 0;
+ if (res == -1 &&
+ errno != ENOSYS /* old kernel, or not supported on this platform */ &&
+ errno != EINVAL /* flags not supported */)
+ return res;
+
+ /* Fall back to fdwalk */
return fdwalk(set_cloexec_cb, &fd);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]