X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust-comm%2Flttng-ust-fd-tracker.c;h=8d2acb69f55f5cb32b7841ba7dafcdb96064326b;hb=7d34f27dce903a88241e96787c1f900b6ea08245;hp=5a763ff2960550c094306d9d7d90de3d2bf9d037;hpb=6548fca464f68be5ded73be6b9a479daf08e62d6;p=lttng-ust.git diff --git a/liblttng-ust-comm/lttng-ust-fd-tracker.c b/liblttng-ust-comm/lttng-ust-fd-tracker.c index 5a763ff2..8d2acb69 100644 --- a/liblttng-ust-comm/lttng-ust-fd-tracker.c +++ b/liblttng-ust-comm/lttng-ust-fd-tracker.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,7 @@ static DEFINE_URCU_TLS(int, thread_fd_tracking); static fd_set *lttng_fd_set; static int lttng_ust_max_fd; static int num_fd_sets; +static int init_done; /* * Force a read (imply TLS fixup for dlopen) of TLS variables. @@ -90,6 +92,9 @@ void lttng_ust_init_fd_tracker(void) struct rlimit rlim; int i; + if (CMM_LOAD_SHARED(init_done)) + return; + memset(&rlim, 0, sizeof(rlim)); /* Get the current possible max number of fd for this process. */ if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) @@ -113,6 +118,7 @@ void lttng_ust_init_fd_tracker(void) abort(); for (i = 0; i < num_fd_sets; i++) FD_ZERO((<tng_fd_set[i])); + CMM_STORE_SHARED(init_done, 1); } void lttng_ust_lock_fd_tracker(void) @@ -143,6 +149,12 @@ void lttng_ust_unlock_fd_tracker(void) */ void lttng_ust_add_fd_to_tracker(int fd) { + /* + * Ensure the tracker is initialized when called from + * constructors. + */ + lttng_ust_init_fd_tracker(); + assert(URCU_TLS(thread_fd_tracking)); /* Trying to add an fd which we can not accommodate. */ assert(IS_FD_VALID(fd)); @@ -158,6 +170,12 @@ void lttng_ust_add_fd_to_tracker(int fd) */ void lttng_ust_delete_fd_from_tracker(int fd) { + /* + * Ensure the tracker is initialized when called from + * constructors. + */ + lttng_ust_init_fd_tracker(); + assert(URCU_TLS(thread_fd_tracking)); /* Not a valid fd. */ assert(IS_FD_VALID(fd)); @@ -178,6 +196,12 @@ int lttng_ust_safe_close_fd(int fd, int (*close_cb)(int fd)) lttng_ust_fixup_fd_tracker_tls(); + /* + * Ensure the tracker is initialized when called from + * constructors. + */ + lttng_ust_init_fd_tracker(); + /* * If called from lttng-ust, we directly call close without * validating whether the FD is part of the tracked set. @@ -197,6 +221,44 @@ int lttng_ust_safe_close_fd(int fd, int (*close_cb)(int fd)) return ret; } +/* + * Interface allowing applications to close arbitrary streams. + * We check if it is owned by lttng-ust, and return -1, errno=EBADF + * instead of closing it if it is the case. + */ +int lttng_ust_safe_fclose_stream(FILE *stream, int (*fclose_cb)(FILE *stream)) +{ + int ret = 0, fd; + + lttng_ust_fixup_fd_tracker_tls(); + + /* + * Ensure the tracker is initialized when called from + * constructors. + */ + lttng_ust_init_fd_tracker(); + + /* + * If called from lttng-ust, we directly call fclose without + * validating whether the FD is part of the tracked set. + */ + if (URCU_TLS(thread_fd_tracking)) + return fclose_cb(stream); + + fd = fileno(stream); + + lttng_ust_lock_fd_tracker(); + if (IS_FD_VALID(fd) && IS_FD_SET(fd, lttng_fd_set)) { + ret = -1; + errno = EBADF; + } else { + ret = fclose_cb(stream); + } + lttng_ust_unlock_fd_tracker(); + + return ret; +} + #ifdef __OpenBSD__ static void set_close_success(int *p) { @@ -225,6 +287,12 @@ int lttng_ust_safe_closefrom_fd(int lowfd, int (*close_cb)(int fd)) lttng_ust_fixup_fd_tracker_tls(); + /* + * Ensure the tracker is initialized when called from + * constructors. + */ + lttng_ust_init_fd_tracker(); + if (lowfd < 0) { /* * NetBSD return EBADF if fd is invalid.