[glib: 1/2] gspawn: Use CLOSE_RANGE_CLOEXEC if available
- From: Simon McVittie <smcv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/2] gspawn: Use CLOSE_RANGE_CLOEXEC if available
- Date: Mon, 2 Aug 2021 14:49:28 +0000 (UTC)
commit b5556a2c6831825fab90c03f8834d298194d8202
Author: Philip Withnall <pwithnall endlessos org>
Date: Fri Jul 9 12:40:47 2021 +0100
gspawn: Use CLOSE_RANGE_CLOEXEC if available
It’s a new flag added to `close_range()` in kernel 5.11, which will
allow us to speed up setting `CLOEXEC` on ranges of file descriptors.
This currently happens in some situations when executing a new binary
with `GSpawn`.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
glib/gspawn.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
---
diff --git a/glib/gspawn.c b/glib/gspawn.c
index 3073a10a4..98986d8a7 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -1482,6 +1482,28 @@ safe_fdwalk (int (*cb)(void *data, int fd), void *data)
#endif
}
+/* This function is called between fork() and exec() and hence must be
+ * async-signal-safe (see signal-safety(7)). */
+static void
+safe_fdwalk_set_cloexec (int lowfd)
+{
+#if defined(HAVE_CLOSE_RANGE) && defined(CLOSE_RANGE_CLOEXEC)
+ /* close_range() is available in Linux since kernel 5.9, and on FreeBSD at
+ * around the same time. It was designed for use in async-signal-safe
+ * situations: https://bugs.python.org/issue38061
+ *
+ * The `CLOSE_RANGE_CLOEXEC` flag was added in Linux 5.11, and is not yet
+ * present in FreeBSD.
+ *
+ * Handle ENOSYS in case it’s supported in libc but not the kernel; if so,
+ * fall back to safe_fdwalk(). Handle EINVAL in case `CLOSE_RANGE_CLOEXEC`
+ * is not supported. */
+ if (close_range (lowfd, G_MAXUINT, CLOSE_RANGE_CLOEXEC) != 0 &&
+ (errno == ENOSYS || errno == EINVAL))
+#endif /* HAVE_CLOSE_RANGE */
+ (void) safe_fdwalk (set_cloexec, GINT_TO_POINTER (lowfd));
+}
+
/* This function is called between fork() and exec() and hence must be
* async-signal-safe (see signal-safety(7)). */
static void
@@ -1689,7 +1711,7 @@ do_exec (gint child_err_report_fd,
}
else
{
- safe_fdwalk (set_cloexec, GINT_TO_POINTER (3));
+ safe_fdwalk_set_cloexec (3);
}
}
else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]