static int (*__lttng_ust_fd_plibc_close)(int fd) = NULL;
static int (*__lttng_ust_fd_plibc_fclose)(FILE *stream) = NULL;
+static int (*__lttng_ust_fd_plibc_close_range)(unsigned int first,
+ unsigned int last, int flags) = NULL;
/*
* Use dlsym to find the original libc close() symbol and store it in
return __lttng_ust_fd_plibc_fclose;
}
+/*
+ * Use dlsym to find the original libc close_range() symbol and store it
+ * in __lttng_ust_fd_plibc_close_range. The close_range symbol only
+ * appears in glibc 2.34, so it is considered optional.
+ */
+static
+void *_lttng_ust_fd_init_plibc_close_range(void)
+{
+ if (__lttng_ust_fd_plibc_close_range == NULL) {
+ __lttng_ust_fd_plibc_close_range = dlsym(RTLD_NEXT, "close_range");
+
+ if (__lttng_ust_fd_plibc_close_range == NULL)
+ __lttng_ust_fd_plibc_close_range = (void *) LTTNG_UST_DLSYM_FAILED_PTR;
+ }
+
+ return __lttng_ust_fd_plibc_close_range;
+}
+
static
void _lttng_ust_fd_ctor(void)
__attribute__((constructor));
*/
(void) _lttng_ust_fd_init_plibc_close();
(void) _lttng_ust_fd_init_plibc_fclose();
+ (void) _lttng_ust_fd_init_plibc_close_range();
}
/*
__lttng_ust_fd_plibc_fclose);
}
+/*
+ * Override the libc close_range() symbol with our own, allowing
+ * applications to close arbitrary file descriptors. If the fd is owned
+ * by lttng-ust, return -1, errno=EBADF instead of closing it.
+ *
+ * If dlsym failed to find the original libc close_range() symbol,
+ * return -1, errno=ENOSYS.
+ *
+ * There is a short window before the library constructor has executed where
+ * this wrapper could call dlsym() and thus not be async-signal-safe.
+ */
+int close_range(unsigned int first, unsigned int last, int flags)
+{
+ /*
+ * We can't retry dlsym here since close is async-signal-safe.
+ */
+ if (_lttng_ust_fd_init_plibc_close_range() == (void *) LTTNG_UST_DLSYM_FAILED_PTR) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return lttng_ust_safe_close_range_fd(first, last, flags, __lttng_ust_fd_plibc_close_range);
+}
+
#if defined(__sun__) || defined(__FreeBSD__)
/* Solaris and FreeBSD. */
void closefrom(int lowfd)