X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust-comm%2Flttng-ust-fd-tracker.c;h=a2227e62115cb137369a44cb3d12eb33bbcad3ab;hb=refs%2Fheads%2Fstable-2.12;hp=9909c0606a45044ab33f37ed09603d87d60dcf3c;hpb=595c15773def8e249145c4dead560ba7329810c7;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 9909c060..a2227e62 100644 --- a/liblttng-ust-comm/lttng-ust-fd-tracker.c +++ b/liblttng-ust-comm/lttng-ust-fd-tracker.c @@ -479,3 +479,62 @@ int lttng_ust_safe_closefrom_fd(int lowfd, int (*close_cb)(int fd)) end: return ret; } + +/* + * Implement helper for close_range() override. + */ +int lttng_ust_safe_close_range_fd(unsigned int first, unsigned int last, int flags, + int (*close_range_cb)(unsigned int first, unsigned int last, int flags)) +{ + int ret = 0, i; + + lttng_ust_fixup_fd_tracker_tls(); + + /* + * Ensure the tracker is initialized when called from + * constructors. + */ + lttng_ust_init_fd_tracker(); + + if (first > last || last > INT_MAX) { + ret = -1; + errno = EINVAL; + goto end; + } + /* + * If called from lttng-ust, we directly call close_range + * without validating whether the FD is part of the tracked set. + */ + if (URCU_TLS(ust_fd_mutex_nest)) { + if (close_range_cb(first, last, flags) < 0) { + ret = -1; + goto end; + } + } else { + int last_check = last; + + if (last > lttng_ust_max_fd) + last_check = lttng_ust_max_fd; + lttng_ust_lock_fd_tracker(); + for (i = first; i <= last_check; i++) { + if (IS_FD_VALID(i) && IS_FD_SET(i, lttng_fd_set)) + continue; + if (close_range_cb(i, i, flags) < 0) { + ret = -1; + /* propagate errno from close_range_cb. */ + lttng_ust_unlock_fd_tracker(); + goto end; + } + } + if (last > lttng_ust_max_fd) { + if (close_range_cb(lttng_ust_max_fd + 1, last, flags) < 0) { + ret = -1; + lttng_ust_unlock_fd_tracker(); + goto end; + } + } + lttng_ust_unlock_fd_tracker(); + } +end: + return ret; +}