#include "lib/lttng-ust-common/fd-tracker.h"
+#define LTTNG_UST_DLSYM_FAILED_PTR 0x1
+
/* Operations on the fd set. */
#define IS_FD_VALID(fd) ((fd) >= 0 && (fd) < lttng_ust_max_fd)
#define GET_FD_SET_FOR_FD(fd, fd_sets) (&((fd_sets)[(fd) / FD_SETSIZE]))
asm volatile ("" : : "m" (URCU_TLS(ust_fd_mutex_nest)));
}
+#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
+static int (*__lttng_ust_safe_close_fd)(int fd, int (*close_cb)(int fd)) = NULL;
+
+void *lttng_ust_safe_close_fd_init(void)
+{
+ if (__lttng_ust_safe_close_fd == NULL) {
+ __lttng_ust_safe_close_fd = dlsym(RTLD_DEFAULT, "lttng_ust_safe_close_fd");
+
+ if (__lttng_ust_safe_close_fd == NULL) {
+ __lttng_ust_safe_close_fd = (void *) LTTNG_UST_DLSYM_FAILED_PTR;
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ }
+
+ return __lttng_ust_safe_close_fd;
+}
+
+static int lttng_ust_safe_close_fd_chain(int fd, int (*close_cb)(int fd))
+{
+ assert(__lttng_ust_safe_close_fd != NULL);
+ if (__lttng_ust_safe_close_fd != (void *) LTTNG_UST_DLSYM_FAILED_PTR) {
+ /* Chain on ust-2.12 preload */
+ return __lttng_ust_safe_close_fd(fd, close_cb);
+ } else {
+ /* Fallback to libc symbol */
+ return close_cb(fd);
+ }
+}
+#else
+static int lttng_ust_safe_close_fd_chain(int fd, int (*close_cb)(int fd))
+{
+ return close_cb(fd);
+}
+#endif
+
+#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
+static int (*__lttng_ust_safe_fclose_stream)(FILE *stream, int (*fclose_cb)(FILE *stream)) = NULL;
+
+void *lttng_ust_safe_fclose_stream_init(void)
+{
+ if (__lttng_ust_safe_fclose_stream == NULL) {
+ __lttng_ust_safe_fclose_stream = dlsym(RTLD_DEFAULT, "lttng_ust_safe_fclose_stream");
+
+ if (__lttng_ust_safe_fclose_stream == NULL) {
+ __lttng_ust_safe_fclose_stream = (void *) LTTNG_UST_DLSYM_FAILED_PTR;
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ }
+
+ return __lttng_ust_safe_fclose_stream;
+}
+
+static int lttng_ust_safe_fclose_stream_chain(FILE *stream, int (*fclose_cb)(FILE *stream))
+{
+ assert(__lttng_ust_safe_fclose_stream != NULL);
+ if (__lttng_ust_safe_fclose_stream != (void *) LTTNG_UST_DLSYM_FAILED_PTR) {
+ /* Chain on ust-2.12 preload */
+ return __lttng_ust_safe_fclose_stream(stream, fclose_cb);
+ } else {
+ /* Fallback to libc symbol */
+ return fclose_cb(stream);
+ }
+}
+#else
+static int lttng_ust_safe_fclose_stream_chain(FILE *stream, int (*fclose_cb)(FILE *stream))
+{
+ return fclose_cb(stream);
+}
+#endif
+
/*
* Allocate the fd set array based on the hard limit set for this
* process. This will be called during the constructor execution
DEL_FD_FROM_SET(fd, lttng_fd_set);
}
-#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
-static int (*__lttng_ust_safe_close_fd)(int fd, int (*close_cb)(int fd)) = NULL;
-
-static
-void *_init_lttng_ust_safe_close_fd(void)
-{
- if (__lttng_ust_safe_close_fd == NULL) {
- __lttng_ust_safe_close_fd = dlsym(RTLD_DEFAULT, "lttng_ust_safe_close_fd");
-
- if (__lttng_ust_safe_close_fd == NULL) {
- fprintf(stderr, "%s\n", dlerror());
- }
- }
-
- return __lttng_ust_safe_close_fd;
-}
-
-static int lttng_ust_safe_close_fd_chain(int fd, int (*close_cb)(int fd))
-{
- if (_init_lttng_ust_safe_close_fd()) {
- /* Chain on ust-2.12 preload */
- return __lttng_ust_safe_close_fd(fd, close_cb);
- } else {
- /* Fallback to libc symbol */
- return close_cb(fd);
- }
-}
-#endif
-
/*
* Interface allowing applications to close arbitrary file descriptors.
* We check if it is owned by lttng-ust, and return -1, errno=EBADF
ret = -1;
errno = EBADF;
} else {
-#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
ret = lttng_ust_safe_close_fd_chain(fd, close_cb);
-#else
- ret = close_cb(fd);
-#endif
}
lttng_ust_unlock_fd_tracker();
return ret;
}
-#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
-static int (*__lttng_ust_safe_fclose_stream)(FILE *stream, int (*fclose_cb)(FILE *stream)) = NULL;
-
-static
-void *_init_lttng_ust_safe_fclose_stream(void)
-{
- if (__lttng_ust_safe_fclose_stream == NULL) {
- __lttng_ust_safe_fclose_stream = dlsym(RTLD_DEFAULT, "lttng_ust_safe_fclose_stream");
-
- if (__lttng_ust_safe_fclose_stream == NULL) {
- fprintf(stderr, "%s\n", dlerror());
- }
- }
-
- return __lttng_ust_safe_fclose_stream;
-}
-
-static int lttng_ust_safe_fclose_stream_chain(FILE *stream, int (*fclose_cb)(FILE *stream))
-{
- if (_init_lttng_ust_safe_fclose_stream()) {
- /* Chain on ust-2.12 preload */
- return __lttng_ust_safe_fclose_stream(stream, fclose_cb);
- } else {
- /* Fallback to libc symbol */
- return fclose_cb(stream);
- }
-}
-#endif
-
/*
* Interface allowing applications to close arbitrary streams.
* We check if it is owned by lttng-ust, and return -1, errno=EBADF
ret = -1;
errno = EBADF;
} else {
-#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
ret = lttng_ust_safe_fclose_stream_chain(stream, fclose_cb);
-#else
- ret = fclose_cb(stream);
-#endif
}
lttng_ust_unlock_fd_tracker();
#include "common/macros.h"
#include "common/ust-fd.h"
+#include "lib/lttng-ust-common/fd-tracker.h"
#define LTTNG_UST_DLSYM_FAILED_PTR 0x1
return __lttng_ust_fd_plibc_fclose;
}
-static
-void _lttng_ust_fd_ctor(void)
- __attribute__((constructor));
-static
-void _lttng_ust_fd_ctor(void)
-{
#if !defined(LTTNG_UST_CUSTOM_UPGRADE_CONFLICTING_SYMBOLS)
- void *handle = NULL;
+static void *lttng_ust_2_12_handle;
+
+static
+void lttng_ust_init_close_chaining(void)
+{
+ if (lttng_ust_2_12_handle)
+ return;
/*
* Load ust-2.12 in the global symbol namespace.
*/
- handle = dlopen("liblttng-ust.so.0", RTLD_GLOBAL | RTLD_NOW);
- if (!handle) {
+ lttng_ust_2_12_handle = dlopen("liblttng-ust.so.0", RTLD_GLOBAL | RTLD_NOW);
+ if (!lttng_ust_2_12_handle) {
fprintf(stderr, "liblttng-ust-fd.so.1: Failed to dlopen liblttng-ust.so.0: %s\n", dlerror());
abort();
}
+ /*
+ * Initialize the function pointers to the ust 2.12 symbols in
+ * the constructor since close() has to stay async-signal-safe
+ * and as such, we can't call dlsym() in the override functions.
+ */
+ (void) lttng_ust_safe_close_fd_init();
+ (void) lttng_ust_safe_fclose_stream_init();
+}
+#else
+static
+void lttng_ust_init_close_chaining(void) { }
#endif
+static
+void _lttng_ust_fd_ctor(void)
+ __attribute__((constructor));
+static
+void _lttng_ust_fd_ctor(void)
+{
+ lttng_ust_init_close_chaining();
+
lttng_ust_common_ctor();
/*
* 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.
+ * this wrapper could call dlsym() and dlopen() and thus not be
+ * async-signal-safe.
*/
int close(int fd)
{
+ lttng_ust_init_close_chaining();
+
/*
* We can't retry dlsym here since close is async-signal-safe.
*/
*/
int fclose(FILE *stream)
{
+ lttng_ust_init_close_chaining();
+
if (_lttng_ust_fd_init_plibc_fclose() == (void *) LTTNG_UST_DLSYM_FAILED_PTR) {
errno = ENOSYS;
return -1;
}
#if defined(__sun__) || defined(__FreeBSD__)
+
+#error "Custom upgrade branch does not support Solaris/FreeBSD closefrom"
+
/* Solaris and FreeBSD. */
void closefrom(int lowfd)
{
(void) lttng_ust_safe_closefrom_fd(lowfd, __lttng_ust_fd_plibc_close);
}
#elif defined(__NetBSD__) || defined(__OpenBSD__)
+
+#error "Custom upgrade branch does not support NetBSD/OpenBSD closefrom"
+
/* NetBSD and OpenBSD. */
int closefrom(int lowfd)
{