diff --git a/include/sudo_event.h b/include/sudo_event.h index ad58b928b..d74c90c09 100644 --- a/include/sudo_event.h +++ b/include/sudo_event.h @@ -148,7 +148,11 @@ __dso_public int sudo_ev_dispatch_v1(struct sudo_event_base *head); __dso_public int sudo_ev_loop_v1(struct sudo_event_base *head, int flags); #define sudo_ev_loop(_a, _b) sudo_ev_loop_v1((_a), (_b)) -/* Return the remaining timeout associated with an event. */ +/* Return pending event types, fills in ts if non-NULL and there is a timeout */ +__dso_public int sudo_ev_pending_v1(struct sudo_event *ev, short events, struct timespec *ts); +#define sudo_ev_pending(_a, _b, _c) sudo_ev_pending_v1((_a), (_b), (_c)) + +/* Return the remaining timeout associated with an event (deprecated). */ __dso_public int sudo_ev_get_timeleft_v1(struct sudo_event *ev, struct timeval *tv); __dso_public int sudo_ev_get_timeleft_v2(struct sudo_event *ev, struct timespec *tv); #define sudo_ev_get_timeleft(_a, _b) sudo_ev_get_timeleft_v2((_a), (_b)) diff --git a/lib/util/event.c b/lib/util/event.c index 64ad0d98f..b66748b7e 100644 --- a/lib/util/event.c +++ b/lib/util/event.c @@ -830,17 +830,36 @@ sudo_ev_get_timeleft_v1(struct sudo_event *ev, struct timeval *tv) int sudo_ev_get_timeleft_v2(struct sudo_event *ev, struct timespec *ts) { - struct timespec now; debug_decl(sudo_ev_get_timeleft, SUDO_DEBUG_EVENT) - if (!ISSET(ev->flags, SUDO_EVQ_TIMEOUTS)) { + if (sudo_ev_pending_v1(ev, SUDO_EV_TIMEOUT, ts) != SUDO_EV_TIMEOUT) { sudo_timespecclear(ts); debug_return_int(-1); } - - sudo_gettime_mono(&now); - sudo_timespecsub(&ev->timeout, &now, ts); - if (ts->tv_sec < 0) - sudo_timespecclear(ts); debug_return_int(0); } + +int +sudo_ev_pending_v1(struct sudo_event *ev, short events, struct timespec *ts) +{ + int ret = 0; + debug_decl(sudo_ev_pending, SUDO_DEBUG_EVENT) + + if (!ISSET(ev->flags, SUDO_EVQ_INSERTED)) + debug_return_int(0); + + ret = ev->events & events; + if (ISSET(ev->flags, SUDO_EVQ_TIMEOUTS) && ISSET(events, SUDO_EV_TIMEOUT)) { + ret |= SUDO_EV_TIMEOUT; + if (ts != NULL) { + struct timespec now; + + sudo_gettime_mono(&now); + sudo_timespecsub(&ev->timeout, &now, ts); + if (ts->tv_sec < 0) + sudo_timespecclear(ts); + } + } + + debug_return_int(ret); +} diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index 4e0f645b4..3cbe11c4a 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -65,6 +65,7 @@ sudo_ev_loop_v1 sudo_ev_loopbreak_v1 sudo_ev_loopcontinue_v1 sudo_ev_loopexit_v1 +sudo_ev_pending_v1 sudo_ev_set_v1 sudo_fatal_callback_deregister_v1 sudo_fatal_callback_register_v1