From 449c4a290a1f48639a70735bf1abaae53ddebd6e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 29 Oct 2013 08:16:42 -0600 Subject: [PATCH] Add sudo_ev_get_timeleft() to get the amount of time left before an event times out and use it in sudoreplay. --- common/event.c | 19 +++++++++++++++++++ include/sudo_event.h | 5 ++++- plugins/sudoers/sudoreplay.c | 16 +++++----------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/common/event.c b/common/event.c index b7b243480..8301705db 100644 --- a/common/event.c +++ b/common/event.c @@ -369,3 +369,22 @@ sudo_ev_got_break(struct sudo_event_base *base) debug_decl(sudo_ev_got_break, SUDO_DEBUG_EVENT) debug_return_bool(ISSET(base->flags, SUDO_EVBASE_GOT_BREAK)); } + +int +sudo_ev_get_timeleft(struct sudo_event *ev, struct timeval *tv) +{ + struct timeval now; + debug_decl(sudo_ev_get_timeleft, SUDO_DEBUG_EVENT) + + if (!ISSET(ev->flags, SUDO_EVQ_TIMEOUTS)) { + timevalclear(tv); + debug_return_int(-1); + } + + gettimeofday(&now, NULL); + *tv = ev->timeout; + timevalsub(tv, &now); + if (tv->tv_sec < 0 || (tv->tv_sec == 0 && tv->tv_usec < 0)) + timevalclear(tv); + debug_return_int(0); +} diff --git a/include/sudo_event.h b/include/sudo_event.h index 77e44597e..09ff724f2 100644 --- a/include/sudo_event.h +++ b/include/sudo_event.h @@ -100,6 +100,9 @@ int sudo_ev_del(struct sudo_event_base *head, struct sudo_event *ev); /* Main event loop, returns SUDO_CB_SUCCESS, SUDO_CB_BREAK or SUDO_CB_ERROR */ int sudo_ev_loop(struct sudo_event_base *head, int flags); +/* Return the remaining timeout associated with an event. */ +int sudo_ev_get_timeleft(struct sudo_event *ev, struct timeval *tv); + /* Cause the event loop to exit after one run through. */ void sudo_ev_loopexit(struct sudo_event_base *base); @@ -120,7 +123,7 @@ bool sudo_ev_got_break(struct sudo_event_base *base); /* Return the (absolute) timeout associated with an event or NULL. */ #define sudo_ev_get_timeout(_ev) \ - (((_ev) && timevalisset(&(_ev)->timeout)) ? &(_ev)->timeout : NULL) + (ISSET((_ev)->flags, SUDO_EVQ_TIMEOUTS) ? &(_ev)->timeout : NULL) /* Return the base an event is associated with or NULL. */ #define sudo_ev_get_base(_ev) ((_ev) ? (_ev)->base : NULL) diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c index 0c6f26470..b8edcbc6d 100644 --- a/plugins/sudoers/sudoreplay.c +++ b/plugins/sudoers/sudoreplay.c @@ -1114,18 +1114,12 @@ check_input(int fd, int what, void *v) } if (!paused) { /* Determine remaining timeout, if any. */ - timeout = sudo_ev_get_timeout(ev); - if (timeout != NULL) { - struct timeval now; - gettimeofday(&now, NULL); - tv = *timeout; - timevalsub(&tv, &now); - if (tv.tv_sec < 0 || (tv.tv_sec == 0 && tv.tv_usec <= 0)) { - /* No time left, event is done. */ - debug_return; - } - timeout = &tv; + sudo_ev_get_timeleft(ev, &tv); + if (!timevalisset(&tv)) { + /* No time left, event is done. */ + debug_return; } + timeout = &tv; } /* Re-enable event. */ sudo_ev_add(evbase, ev, timeout, false); -- 2.40.0