Add support for libevent-style timed events. Adding a timed event
is currently O(n). The only consumer of timed events is sudoreplay which only used a singled one so O(n) == O(1) for now. This also allows us to remove the nanosleep compat function as we now use a timeout event instead.
This commit is contained in:
1
MANIFEST
1
MANIFEST
@@ -80,7 +80,6 @@ compat/mksiglist.h
|
|||||||
compat/mksigname.c
|
compat/mksigname.c
|
||||||
compat/mksigname.h
|
compat/mksigname.h
|
||||||
compat/mktemp.c
|
compat/mktemp.c
|
||||||
compat/nanosleep.c
|
|
||||||
compat/nss_dbdefs.h
|
compat/nss_dbdefs.h
|
||||||
compat/pw_dup.c
|
compat/pw_dup.c
|
||||||
compat/regress/fnmatch/fnm_test.c
|
compat/regress/fnmatch/fnm_test.c
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
@@ -58,6 +59,7 @@ sudo_ev_base_alloc(void)
|
|||||||
|
|
||||||
base = ecalloc(1, sizeof(*base));
|
base = ecalloc(1, sizeof(*base));
|
||||||
TAILQ_INIT(&base->events);
|
TAILQ_INIT(&base->events);
|
||||||
|
TAILQ_INIT(&base->timeouts);
|
||||||
if (sudo_ev_base_alloc_impl(base) != 0) {
|
if (sudo_ev_base_alloc_impl(base) != 0) {
|
||||||
efree(base);
|
efree(base);
|
||||||
base = NULL;
|
base = NULL;
|
||||||
@@ -88,6 +90,8 @@ sudo_ev_alloc(int fd, short events, sudo_ev_callback_t callback, void *closure)
|
|||||||
struct sudo_event *ev;
|
struct sudo_event *ev;
|
||||||
debug_decl(sudo_ev_alloc, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_alloc, SUDO_DEBUG_EVENT)
|
||||||
|
|
||||||
|
/* XXX - sanity check events value */
|
||||||
|
|
||||||
ev = ecalloc(1, sizeof(*ev));
|
ev = ecalloc(1, sizeof(*ev));
|
||||||
ev->fd = fd;
|
ev->fd = fd;
|
||||||
ev->events = events;
|
ev->events = events;
|
||||||
@@ -111,11 +115,12 @@ sudo_ev_free(struct sudo_event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_ev_add(struct sudo_event_base *base, struct sudo_event *ev, bool tohead)
|
sudo_ev_add(struct sudo_event_base *base, struct sudo_event *ev,
|
||||||
|
struct timeval *timo, bool tohead)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_ev_add, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_add, SUDO_DEBUG_EVENT)
|
||||||
|
|
||||||
/* Don't add an event twice; revisit if we want to support timeouts. */
|
/* Only add new events to the events list. */
|
||||||
if (ev->base == NULL) {
|
if (ev->base == NULL) {
|
||||||
if (sudo_ev_add_impl(base, ev) != 0)
|
if (sudo_ev_add_impl(base, ev) != 0)
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
@@ -125,6 +130,37 @@ sudo_ev_add(struct sudo_event_base *base, struct sudo_event *ev, bool tohead)
|
|||||||
} else {
|
} else {
|
||||||
TAILQ_INSERT_TAIL(&base->events, ev, entries);
|
TAILQ_INSERT_TAIL(&base->events, ev, entries);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* If no base specified, use existing one. */
|
||||||
|
if (base == NULL)
|
||||||
|
base = ev->base;
|
||||||
|
|
||||||
|
/* If event no longer has a timeout, remove from timeouts queue. */
|
||||||
|
if (timo == NULL && timevalisset(&ev->timeout)) {
|
||||||
|
timevalclear(&ev->timeout);
|
||||||
|
TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Timeouts can be changed for existing events. */
|
||||||
|
if (timo != NULL) {
|
||||||
|
struct sudo_event *evtmp;
|
||||||
|
if (timevalisset(&ev->timeout)) {
|
||||||
|
/* Remove from timeouts list, then add back. */
|
||||||
|
TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
|
||||||
|
}
|
||||||
|
/* Convert to absolute time and insert in sorted order; O(n). */
|
||||||
|
gettimeofday(&ev->timeout, NULL);
|
||||||
|
ev->timeout.tv_sec += timo->tv_sec;
|
||||||
|
ev->timeout.tv_usec += timo->tv_usec;
|
||||||
|
TAILQ_FOREACH(evtmp, &base->timeouts, timeouts_entries) {
|
||||||
|
if (timevalcmp(timo, &evtmp->timeout, <))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (evtmp != NULL) {
|
||||||
|
TAILQ_INSERT_BEFORE(evtmp, ev, timeouts_entries);
|
||||||
|
} else {
|
||||||
|
TAILQ_INSERT_TAIL(&base->timeouts, ev, timeouts_entries);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Clear pending delete so adding from callback works properly. */
|
/* Clear pending delete so adding from callback works properly. */
|
||||||
CLR(ev->flags, SUDO_EV_DELETE);
|
CLR(ev->flags, SUDO_EV_DELETE);
|
||||||
@@ -162,6 +198,10 @@ sudo_ev_del(struct sudo_event_base *base, struct sudo_event *ev)
|
|||||||
/* Unlink from event list. */
|
/* Unlink from event list. */
|
||||||
TAILQ_REMOVE(&base->events, ev, entries);
|
TAILQ_REMOVE(&base->events, ev, entries);
|
||||||
|
|
||||||
|
/* Unlink from timeouts list. */
|
||||||
|
if (ISSET(ev->events, SUDO_EV_TIMEOUT) && timevalisset(&ev->timeout))
|
||||||
|
TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
|
||||||
|
|
||||||
/* Unlink from active list and update base pointers as needed. */
|
/* Unlink from active list and update base pointers as needed. */
|
||||||
if (ISSET(ev->flags, SUDO_EV_ACTIVE)) {
|
if (ISSET(ev->flags, SUDO_EV_ACTIVE)) {
|
||||||
TAILQ_REMOVE(&base->active, ev, active_entries);
|
TAILQ_REMOVE(&base->active, ev, active_entries);
|
||||||
@@ -186,7 +226,9 @@ sudo_ev_del(struct sudo_event_base *base, struct sudo_event *ev)
|
|||||||
int
|
int
|
||||||
sudo_ev_loop(struct sudo_event_base *base, int flags)
|
sudo_ev_loop(struct sudo_event_base *base, int flags)
|
||||||
{
|
{
|
||||||
int rc;
|
struct timeval now;
|
||||||
|
struct sudo_event *ev;
|
||||||
|
int nready, rc = 0;
|
||||||
debug_decl(sudo_ev_loop, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_loop, SUDO_DEBUG_EVENT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -195,7 +237,7 @@ sudo_ev_loop(struct sudo_event_base *base, int flags)
|
|||||||
* All other base flags are ignored unless we are running events.
|
* All other base flags are ignored unless we are running events.
|
||||||
*/
|
*/
|
||||||
if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT))
|
if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT))
|
||||||
flags |= SUDO_EVLOOP_ONCE;
|
SET(flags, SUDO_EVLOOP_ONCE);
|
||||||
base->flags = 0;
|
base->flags = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -206,12 +248,32 @@ rescan:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call backend to setup the active queue. */
|
/* Call backend to scan for I/O events. */
|
||||||
TAILQ_INIT(&base->active);
|
TAILQ_INIT(&base->active);
|
||||||
rc = sudo_ev_loop_impl(base, flags);
|
nready = sudo_ev_scan_impl(base, flags);
|
||||||
if (rc == -1) {
|
switch (nready) {
|
||||||
|
case -1:
|
||||||
if (errno == EINTR || errno == ENOMEM)
|
if (errno == EINTR || errno == ENOMEM)
|
||||||
continue;
|
continue;
|
||||||
|
rc = -1;
|
||||||
|
goto done;
|
||||||
|
case 0:
|
||||||
|
/* Timed out, activate timeout events. */
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
while ((ev = TAILQ_FIRST(&base->timeouts)) != NULL) {
|
||||||
|
if (timevalcmp(&ev->timeout, &now, >))
|
||||||
|
break;
|
||||||
|
/* Remove from timeouts list. */
|
||||||
|
timevalclear(&ev->timeout);
|
||||||
|
TAILQ_REMOVE(&base->timeouts, ev, timeouts_entries);
|
||||||
|
/* Make event active. */
|
||||||
|
ev->revents = SUDO_EV_TIMEOUT;
|
||||||
|
SET(ev->flags, SUDO_EV_ACTIVE);
|
||||||
|
TAILQ_INSERT_TAIL(&base->active, ev, active_entries);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* I/O events active, sudo_ev_scan_impl() already added them. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +287,7 @@ rescan:
|
|||||||
if (!ISSET(base->cur->events, SUDO_EV_PERSIST))
|
if (!ISSET(base->cur->events, SUDO_EV_PERSIST))
|
||||||
SET(base->cur->flags, SUDO_EV_DELETE);
|
SET(base->cur->flags, SUDO_EV_DELETE);
|
||||||
base->cur->callback(base->cur->fd, base->cur->revents,
|
base->cur->callback(base->cur->fd, base->cur->revents,
|
||||||
base->cur->closure);
|
base->cur->closure == sudo_ev_self_cbarg() ? base->cur : base->cur->closure);
|
||||||
if (base->cur != NULL) {
|
if (base->cur != NULL) {
|
||||||
CLR(base->cur->flags, SUDO_EV_ACTIVE);
|
CLR(base->cur->flags, SUDO_EV_ACTIVE);
|
||||||
if (ISSET(base->cur->flags, SUDO_EV_DELETE))
|
if (ISSET(base->cur->flags, SUDO_EV_DELETE))
|
||||||
@@ -233,21 +295,23 @@ rescan:
|
|||||||
}
|
}
|
||||||
if (ISSET(base->flags, SUDO_EVBASE_LOOPBREAK)) {
|
if (ISSET(base->flags, SUDO_EVBASE_LOOPBREAK)) {
|
||||||
/* stop processing events immediately */
|
/* stop processing events immediately */
|
||||||
base->flags |= SUDO_EVBASE_GOT_BREAK;
|
SET(base->flags, SUDO_EVBASE_GOT_BREAK);
|
||||||
base->pending = NULL;
|
base->pending = NULL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (ISSET(base->flags, SUDO_EVBASE_LOOPCONT)) {
|
if (ISSET(base->flags, SUDO_EVBASE_LOOPCONT)) {
|
||||||
/* rescan events and start polling again */
|
/* rescan events and start polling again */
|
||||||
CLR(base->flags, SUDO_EVBASE_LOOPCONT);
|
CLR(base->flags, SUDO_EVBASE_LOOPCONT);
|
||||||
|
if (!ISSET(flags, SUDO_EVLOOP_ONCE)) {
|
||||||
base->pending = NULL;
|
base->pending = NULL;
|
||||||
goto rescan;
|
goto rescan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
base->pending = NULL;
|
base->pending = NULL;
|
||||||
if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT)) {
|
if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT)) {
|
||||||
/* exit loop after once through */
|
/* exit loop after once through */
|
||||||
base->flags |= SUDO_EVBASE_GOT_EXIT;
|
SET(base->flags, SUDO_EVBASE_GOT_EXIT);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (flags & (SUDO_EVLOOP_ONCE | SUDO_EVLOOP_NONBLOCK))
|
if (flags & (SUDO_EVLOOP_ONCE | SUDO_EVLOOP_NONBLOCK))
|
||||||
@@ -262,7 +326,7 @@ void
|
|||||||
sudo_ev_loopexit(struct sudo_event_base *base)
|
sudo_ev_loopexit(struct sudo_event_base *base)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_ev_loopexit, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_loopexit, SUDO_DEBUG_EVENT)
|
||||||
base->flags |= SUDO_EVBASE_LOOPEXIT;
|
SET(base->flags, SUDO_EVBASE_LOOPEXIT);
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +334,7 @@ void
|
|||||||
sudo_ev_loopbreak(struct sudo_event_base *base)
|
sudo_ev_loopbreak(struct sudo_event_base *base)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_ev_loopbreak, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_loopbreak, SUDO_DEBUG_EVENT)
|
||||||
base->flags |= SUDO_EVBASE_LOOPBREAK;
|
SET(base->flags, SUDO_EVBASE_LOOPBREAK);
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +342,7 @@ void
|
|||||||
sudo_ev_loopcontinue(struct sudo_event_base *base)
|
sudo_ev_loopcontinue(struct sudo_event_base *base)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_ev_loopcontinue, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_loopcontinue, SUDO_DEBUG_EVENT)
|
||||||
base->flags |= SUDO_EVBASE_LOOPCONT;
|
SET(base->flags, SUDO_EVBASE_LOOPCONT);
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
@@ -133,22 +134,33 @@ sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev)
|
|||||||
int
|
int
|
||||||
sudo_ev_loop_impl(struct sudo_event_base *base, int flags)
|
sudo_ev_loop_impl(struct sudo_event_base *base, int flags)
|
||||||
{
|
{
|
||||||
const int timeout = (flags & SUDO_EVLOOP_NONBLOCK) ? 0 : -1;
|
|
||||||
struct sudo_event *ev;
|
struct sudo_event *ev;
|
||||||
int nready;
|
int nready, timeout;
|
||||||
|
struct timeval now;
|
||||||
debug_decl(sudo_ev_loop_impl, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_loop_impl, SUDO_DEBUG_EVENT)
|
||||||
|
|
||||||
|
if ((ev = TAILQ_FIRST(&base->timeouts)) != NULL) {
|
||||||
|
struct timeval *timo = &ev->timeout;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
timeout = ((timo->tv_sec - now.tv_sec) * 1000) +
|
||||||
|
((timo->tv_usec - now.tv_usec) / 1000);
|
||||||
|
if (timeout <= 0)
|
||||||
|
debug_return_int(0);
|
||||||
|
} else {
|
||||||
|
timeout = (flags & SUDO_EVLOOP_NONBLOCK) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
nready = poll(base->pfds, base->pfd_high + 1, timeout);
|
nready = poll(base->pfds, base->pfd_high + 1, timeout);
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d fds ready", __func__, nready);
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d fds ready", __func__, nready);
|
||||||
switch (nready) {
|
switch (nready) {
|
||||||
case -1:
|
case -1:
|
||||||
/* error or interrupted by signal */
|
/* Error or interrupted by signal. */
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
case 0:
|
case 0:
|
||||||
/* timeout or no events */
|
/* Front end will activate timeout events. */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Activate each event that fired. */
|
/* Activate each I/O event that fired. */
|
||||||
TAILQ_FOREACH(ev, &base->events, entries) {
|
TAILQ_FOREACH(ev, &base->events, entries) {
|
||||||
if (ev->pfd_idx != -1 && base->pfds[ev->pfd_idx].revents) {
|
if (ev->pfd_idx != -1 && base->pfds[ev->pfd_idx].revents) {
|
||||||
int what = 0;
|
int what = 0;
|
||||||
|
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/param.h> /* for howmany() on Linux */
|
||||||
|
#include <sys/time.h>
|
||||||
#ifdef HAVE_SYS_SYSMACROS_H
|
#ifdef HAVE_SYS_SYSMACROS_H
|
||||||
# include <sys/sysmacros.h>
|
# include <sys/sysmacros.h> /* for howmany() on Solaris */
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
# include <sys/select.h>
|
# include <sys/select.h>
|
||||||
@@ -108,20 +109,28 @@ sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_ev_loop_impl(struct sudo_event_base *base, int flags)
|
sudo_ev_scan_impl(struct sudo_event_base *base, int flags)
|
||||||
{
|
{
|
||||||
struct timeval tv, *timeout;
|
struct timeval now, tv, *timeout;
|
||||||
struct sudo_event *ev;
|
struct sudo_event *ev;
|
||||||
int nready, highfd = 0;
|
int nready, highfd = 0;
|
||||||
debug_decl(sudo_ev_loop, SUDO_DEBUG_EVENT)
|
debug_decl(sudo_ev_loop, SUDO_DEBUG_EVENT)
|
||||||
|
|
||||||
|
if ((ev = TAILQ_FIRST(&base->timeouts)) != NULL) {
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
tv = ev->timeout;
|
||||||
|
timevalsub(&tv, &now);
|
||||||
|
if (tv.tv_sec < 0 || tv.tv_usec < 0)
|
||||||
|
debug_return_int(0);
|
||||||
|
timeout = &tv;
|
||||||
|
} else {
|
||||||
if (ISSET(flags, SUDO_EVLOOP_NONBLOCK)) {
|
if (ISSET(flags, SUDO_EVLOOP_NONBLOCK)) {
|
||||||
tv.tv_sec = 0;
|
timevalclear(&tv);
|
||||||
tv.tv_usec = 0;
|
|
||||||
timeout = &tv;
|
timeout = &tv;
|
||||||
} else {
|
} else {
|
||||||
timeout = NULL;
|
timeout = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* For select we need to redo readfds and writefds each time. */
|
/* For select we need to redo readfds and writefds each time. */
|
||||||
memset(base->readfds, 0, howmany(base->maxfd + 1, NFDBITS) * sizeof(fd_mask));
|
memset(base->readfds, 0, howmany(base->maxfd + 1, NFDBITS) * sizeof(fd_mask));
|
||||||
@@ -148,13 +157,13 @@ sudo_ev_loop_impl(struct sudo_event_base *base, int flags)
|
|||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d fds ready", __func__, nready);
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %d fds ready", __func__, nready);
|
||||||
switch (nready) {
|
switch (nready) {
|
||||||
case -1:
|
case -1:
|
||||||
/* error or interrupted by signal */
|
/* Error or interrupted by signal. */
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
case 0:
|
case 0:
|
||||||
/* timeout or no events */
|
/* Front end will activate timeout events. */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Activate each event that fired. */
|
/* Activate each I/O event that fired. */
|
||||||
TAILQ_FOREACH(ev, &base->events, entries) {
|
TAILQ_FOREACH(ev, &base->events, entries) {
|
||||||
int what = 0;
|
int what = 0;
|
||||||
if (FD_ISSET(ev->fd, base->readfds))
|
if (FD_ISSET(ev->fd, base->readfds))
|
||||||
@@ -170,5 +179,5 @@ sudo_ev_loop_impl(struct sudo_event_base *base, int flags)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
debug_return_int(0);
|
debug_return_int(nready);
|
||||||
}
|
}
|
||||||
|
@@ -209,9 +209,6 @@ mksigname.lo: $(srcdir)/mksigname.c $(top_builddir)/config.h \
|
|||||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/mksigname.c
|
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/mksigname.c
|
||||||
mktemp.lo: $(srcdir)/mktemp.c $(top_builddir)/config.h $(incdir)/missing.h
|
mktemp.lo: $(srcdir)/mktemp.c $(top_builddir)/config.h $(incdir)/missing.h
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/mktemp.c
|
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/mktemp.c
|
||||||
nanosleep.lo: $(srcdir)/nanosleep.c $(top_builddir)/config.h \
|
|
||||||
$(top_srcdir)/compat/timespec.h $(incdir)/missing.h
|
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/nanosleep.c
|
|
||||||
pw_dup.lo: $(srcdir)/pw_dup.c $(top_builddir)/config.h
|
pw_dup.lo: $(srcdir)/pw_dup.c $(top_builddir)/config.h
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/pw_dup.c
|
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/pw_dup.c
|
||||||
sig2str.lo: $(srcdir)/sig2str.c $(top_builddir)/config.h $(incdir)/missing.h
|
sig2str.lo: $(srcdir)/sig2str.c $(top_builddir)/config.h $(incdir)/missing.h
|
||||||
|
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2011, 2013 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#ifndef HAVE_NANOSLEEP
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif /* HAVE_SYS_SELECT_H */
|
|
||||||
#if TIME_WITH_SYS_TIME
|
|
||||||
# include <time.h>
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_STRUCT_TIMESPEC
|
|
||||||
# include "compat/timespec.h"
|
|
||||||
#endif
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "missing.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
nanosleep(const struct timespec *ts, struct timespec *rts)
|
|
||||||
{
|
|
||||||
struct timeval timeout, endtime, now;
|
|
||||||
int rval;
|
|
||||||
|
|
||||||
timeout.tv_sec = ts->tv_sec;
|
|
||||||
timeout.tv_usec = ts->tv_nsec / 1000;
|
|
||||||
if (rts != NULL) {
|
|
||||||
gettimeofday(&endtime, NULL);
|
|
||||||
timevaladd(&endtime, &timeout);
|
|
||||||
}
|
|
||||||
rval = select(0, NULL, NULL, NULL, &timeout);
|
|
||||||
if (rts != NULL && rval == -1 && errno == EINTR) {
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
timevalsub(&endtime, &now);
|
|
||||||
rts->tv_sec = endtime.tv_sec;
|
|
||||||
rts->tv_nsec = endtime.tv_usec * 1000;
|
|
||||||
}
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_NANOSLEEP */
|
|
@@ -397,9 +397,6 @@
|
|||||||
/* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
|
/* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
|
||||||
#undef HAVE_MPS_LDAP_SSL_H
|
#undef HAVE_MPS_LDAP_SSL_H
|
||||||
|
|
||||||
/* Define to 1 if you have the `nanosleep' function. */
|
|
||||||
#undef HAVE_NANOSLEEP
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||||
#undef HAVE_NDIR_H
|
#undef HAVE_NDIR_H
|
||||||
|
|
||||||
|
62
configure
vendored
62
configure
vendored
@@ -17653,68 +17653,6 @@ esac
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
for ac_func in nanosleep
|
|
||||||
do :
|
|
||||||
ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
|
|
||||||
if test "x$ac_cv_func_nanosleep" = xyes; then :
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
|
||||||
#define HAVE_NANOSLEEP 1
|
|
||||||
_ACEOF
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
# On Solaris, nanosleep is in librt
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5
|
|
||||||
$as_echo_n "checking for nanosleep in -lrt... " >&6; }
|
|
||||||
if ${ac_cv_lib_rt_nanosleep+:} false; then :
|
|
||||||
$as_echo_n "(cached) " >&6
|
|
||||||
else
|
|
||||||
ac_check_lib_save_LIBS=$LIBS
|
|
||||||
LIBS="-lrt $LIBS"
|
|
||||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
||||||
/* end confdefs.h. */
|
|
||||||
|
|
||||||
/* Override any GCC internal prototype to avoid an error.
|
|
||||||
Use char because int might match the return type of a GCC
|
|
||||||
builtin and then its argument prototype would still apply. */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
#endif
|
|
||||||
char nanosleep ();
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
return nanosleep ();
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_ACEOF
|
|
||||||
if ac_fn_c_try_link "$LINENO"; then :
|
|
||||||
ac_cv_lib_rt_nanosleep=yes
|
|
||||||
else
|
|
||||||
ac_cv_lib_rt_nanosleep=no
|
|
||||||
fi
|
|
||||||
rm -f core conftest.err conftest.$ac_objext \
|
|
||||||
conftest$ac_exeext conftest.$ac_ext
|
|
||||||
LIBS=$ac_check_lib_save_LIBS
|
|
||||||
fi
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5
|
|
||||||
$as_echo "$ac_cv_lib_rt_nanosleep" >&6; }
|
|
||||||
if test "x$ac_cv_lib_rt_nanosleep" = xyes; then :
|
|
||||||
REPLAY_LIBS="${REPLAY_LIBS} -lrt"
|
|
||||||
else
|
|
||||||
case " $LIBOBJS " in
|
|
||||||
*" nanosleep.$ac_objext "* ) ;;
|
|
||||||
*) LIBOBJS="$LIBOBJS nanosleep.$ac_objext"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
for ac_func in getopt_long
|
for ac_func in getopt_long
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
|
ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long"
|
||||||
|
@@ -2370,10 +2370,6 @@ SUDO_FUNC_FNMATCH([AC_DEFINE(HAVE_FNMATCH)], [AC_LIBOBJ(fnmatch)
|
|||||||
])
|
])
|
||||||
SUDO_FUNC_ISBLANK
|
SUDO_FUNC_ISBLANK
|
||||||
AC_REPLACE_FUNCS(memrchr memset_s pw_dup strlcpy strlcat)
|
AC_REPLACE_FUNCS(memrchr memset_s pw_dup strlcpy strlcat)
|
||||||
AC_CHECK_FUNCS(nanosleep, [], [
|
|
||||||
# On Solaris, nanosleep is in librt
|
|
||||||
AC_CHECK_LIB(rt, nanosleep, [REPLAY_LIBS="${REPLAY_LIBS} -lrt"], [AC_LIBOBJ(nanosleep)])
|
|
||||||
])
|
|
||||||
AC_CHECK_FUNCS(getopt_long, [], [AC_LIBOBJ(getopt_long)
|
AC_CHECK_FUNCS(getopt_long, [], [AC_LIBOBJ(getopt_long)
|
||||||
AC_MSG_CHECKING([for optreset])
|
AC_MSG_CHECKING([for optreset])
|
||||||
AC_CACHE_VAL(sudo_cv_optreset, [
|
AC_CACHE_VAL(sudo_cv_optreset, [
|
||||||
|
@@ -186,13 +186,6 @@
|
|||||||
#undef ISSET
|
#undef ISSET
|
||||||
#define ISSET(t, f) ((t) & (f))
|
#define ISSET(t, f) ((t) & (f))
|
||||||
|
|
||||||
/*
|
|
||||||
* Some systems define this in <sys/param.h> but we don't include that anymore.
|
|
||||||
*/
|
|
||||||
#ifndef howmany
|
|
||||||
# define howmany(x, y) (((x) + ((y) - 1)) / (y))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Older systems may be missing stddef.h and/or offsetof macro
|
* Older systems may be missing stddef.h and/or offsetof macro
|
||||||
*/
|
*/
|
||||||
@@ -413,9 +406,6 @@ char *mkdtemp(char *);
|
|||||||
#ifndef HAVE_MKSTEMPS
|
#ifndef HAVE_MKSTEMPS
|
||||||
int mkstemps(char *, int);
|
int mkstemps(char *, int);
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_NANOSLEEP
|
|
||||||
int nanosleep(const struct timespec *, struct timespec *);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_PW_DUP
|
#ifndef HAVE_PW_DUP
|
||||||
struct passwd *pw_dup(const struct passwd *);
|
struct passwd *pw_dup(const struct passwd *);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -20,9 +20,10 @@
|
|||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
/* Event types */
|
/* Event types */
|
||||||
#define SUDO_EV_READ 0x01 /* fire when readable */
|
#define SUDO_EV_TIMEOUT 0x01 /* fire after timeout */
|
||||||
#define SUDO_EV_WRITE 0x02 /* fire when writable */
|
#define SUDO_EV_READ 0x02 /* fire when readable */
|
||||||
#define SUDO_EV_PERSIST 0x04 /* persist until deleted */
|
#define SUDO_EV_WRITE 0x04 /* fire when writable */
|
||||||
|
#define SUDO_EV_PERSIST 0x08 /* persist until deleted */
|
||||||
|
|
||||||
/* Event flags (internal) */
|
/* Event flags (internal) */
|
||||||
#define SUDO_EV_ACTIVE 0x01 /* event is on the active queue */
|
#define SUDO_EV_ACTIVE 0x01 /* event is on the active queue */
|
||||||
@@ -46,6 +47,7 @@ typedef void (*sudo_ev_callback_t)(int fd, int what, void *closure);
|
|||||||
struct sudo_event {
|
struct sudo_event {
|
||||||
TAILQ_ENTRY(sudo_event) entries;
|
TAILQ_ENTRY(sudo_event) entries;
|
||||||
TAILQ_ENTRY(sudo_event) active_entries;
|
TAILQ_ENTRY(sudo_event) active_entries;
|
||||||
|
TAILQ_ENTRY(sudo_event) timeouts_entries;
|
||||||
struct sudo_event_base *base; /* base this event belongs to */
|
struct sudo_event_base *base; /* base this event belongs to */
|
||||||
int fd; /* fd we are interested in */
|
int fd; /* fd we are interested in */
|
||||||
short events; /* SUDO_EV_* flags (in) */
|
short events; /* SUDO_EV_* flags (in) */
|
||||||
@@ -53,6 +55,7 @@ struct sudo_event {
|
|||||||
short flags; /* internal event flags */
|
short flags; /* internal event flags */
|
||||||
short pfd_idx; /* index into pfds array (XXX) */
|
short pfd_idx; /* index into pfds array (XXX) */
|
||||||
sudo_ev_callback_t callback;/* user-provided callback */
|
sudo_ev_callback_t callback;/* user-provided callback */
|
||||||
|
struct timeval timeout; /* for SUDO_EV_TIMEOUT */
|
||||||
void *closure; /* user-provided data pointer */
|
void *closure; /* user-provided data pointer */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -61,6 +64,7 @@ TAILQ_HEAD(sudo_event_list, sudo_event);
|
|||||||
struct sudo_event_base {
|
struct sudo_event_base {
|
||||||
struct sudo_event_list events; /* tail queue of all events */
|
struct sudo_event_list events; /* tail queue of all events */
|
||||||
struct sudo_event_list active; /* tail queue of active events */
|
struct sudo_event_list active; /* tail queue of active events */
|
||||||
|
struct sudo_event_list timeouts; /* tail queue of timeout events */
|
||||||
struct sudo_event *cur; /* current active event being serviced */
|
struct sudo_event *cur; /* current active event being serviced */
|
||||||
struct sudo_event *pending; /* next active event to be serviced */
|
struct sudo_event *pending; /* next active event to be serviced */
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
@@ -89,7 +93,7 @@ struct sudo_event *sudo_ev_alloc(int fd, short events, sudo_ev_callback_t callba
|
|||||||
void sudo_ev_free(struct sudo_event *ev);
|
void sudo_ev_free(struct sudo_event *ev);
|
||||||
|
|
||||||
/* Add an event, returns 0 on success, -1 on error */
|
/* Add an event, returns 0 on success, -1 on error */
|
||||||
int sudo_ev_add(struct sudo_event_base *head, struct sudo_event *ev, bool tohead);
|
int sudo_ev_add(struct sudo_event_base *head, struct sudo_event *ev, struct timeval *timo, bool tohead);
|
||||||
|
|
||||||
/* Delete an event, returns 0 on success, -1 on error */
|
/* Delete an event, returns 0 on success, -1 on error */
|
||||||
int sudo_ev_del(struct sudo_event_base *head, struct sudo_event *ev);
|
int sudo_ev_del(struct sudo_event_base *head, struct sudo_event *ev);
|
||||||
@@ -115,9 +119,16 @@ bool sudo_ev_got_break(struct sudo_event_base *base);
|
|||||||
/* Return the fd associated with an event. */
|
/* Return the fd associated with an event. */
|
||||||
#define sudo_ev_get_fd(_ev) ((_ev) ? (_ev)->fd : -1)
|
#define sudo_ev_get_fd(_ev) ((_ev) ? (_ev)->fd : -1)
|
||||||
|
|
||||||
|
/* Return the (absolute) timeout associated with an event or NULL. */
|
||||||
|
#define sudo_ev_get_timeout(_ev) \
|
||||||
|
(((_ev) && timevalisset(&(_ev)->timeout)) ? &(_ev)->timeout : NULL)
|
||||||
|
|
||||||
/* Return the base an event is associated with or NULL. */
|
/* Return the base an event is associated with or NULL. */
|
||||||
#define sudo_ev_get_base(_ev) ((_ev) ? (_ev)->base : NULL)
|
#define sudo_ev_get_base(_ev) ((_ev) ? (_ev)->base : NULL)
|
||||||
|
|
||||||
|
/* Magic pointer value to use self pointer as callback arg. */
|
||||||
|
#define sudo_ev_self_cbarg() ((void *)-1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Backend implementation.
|
* Backend implementation.
|
||||||
*/
|
*/
|
||||||
@@ -125,6 +136,6 @@ int sudo_ev_base_alloc_impl(struct sudo_event_base *base);
|
|||||||
void sudo_ev_base_free_impl(struct sudo_event_base *base);
|
void sudo_ev_base_free_impl(struct sudo_event_base *base);
|
||||||
int sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev);
|
int sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev);
|
||||||
int sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev);
|
int sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev);
|
||||||
int sudo_ev_loop_impl(struct sudo_event_base *base, int flags);
|
int sudo_ev_scan_impl(struct sudo_event_base *base, int flags);
|
||||||
|
|
||||||
#endif /* _SUDO_EVENT_H */
|
#endif /* _SUDO_EVENT_H */
|
||||||
|
2
mkdep.pl
2
mkdep.pl
@@ -70,7 +70,7 @@ sub mkdep {
|
|||||||
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo sssd.lo:;
|
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo sssd.lo:;
|
||||||
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
||||||
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
||||||
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo getopt_long.lo glob.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
|
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo getopt_long.lo glob.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
|
||||||
|
|
||||||
# Parse OBJS lines
|
# Parse OBJS lines
|
||||||
my %objs;
|
my %objs;
|
||||||
|
@@ -840,7 +840,8 @@ sudoreplay.o: $(srcdir)/sudoreplay.c $(top_builddir)/config.h \
|
|||||||
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/fatal.h \
|
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/fatal.h \
|
||||||
$(incdir)/gettext.h $(srcdir)/logging.h $(srcdir)/iolog.h \
|
$(incdir)/gettext.h $(srcdir)/logging.h $(srcdir)/iolog.h \
|
||||||
$(incdir)/queue.h $(incdir)/sudo_plugin.h $(incdir)/sudo_conf.h \
|
$(incdir)/queue.h $(incdir)/sudo_plugin.h $(incdir)/sudo_conf.h \
|
||||||
$(incdir)/queue.h $(incdir)/sudo_debug.h
|
$(incdir)/queue.h $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \
|
||||||
|
$(incdir)/queue.h
|
||||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudoreplay.c
|
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudoreplay.c
|
||||||
testsudoers.o: $(srcdir)/testsudoers.c $(top_builddir)/config.h \
|
testsudoers.o: $(srcdir)/testsudoers.c $(top_builddir)/config.h \
|
||||||
$(top_srcdir)/compat/fnmatch.h $(srcdir)/tsgetgrpw.h \
|
$(top_srcdir)/compat/fnmatch.h $(srcdir)/tsgetgrpw.h \
|
||||||
|
@@ -18,16 +18,10 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#ifdef HAVE_SYS_SYSMACROS_H
|
|
||||||
# include <sys/sysmacros.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif /* HAVE_SYS_SELECT_H */
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
@@ -105,6 +99,7 @@
|
|||||||
#include "sudo_plugin.h"
|
#include "sudo_plugin.h"
|
||||||
#include "sudo_conf.h"
|
#include "sudo_conf.h"
|
||||||
#include "sudo_debug.h"
|
#include "sudo_debug.h"
|
||||||
|
#include "sudo_event.h"
|
||||||
|
|
||||||
#ifndef LINE_MAX
|
#ifndef LINE_MAX
|
||||||
# define LINE_MAX 2048
|
# define LINE_MAX 2048
|
||||||
@@ -125,6 +120,14 @@ struct log_info {
|
|||||||
int cols;
|
int cols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Closure for write_output */
|
||||||
|
struct write_closure {
|
||||||
|
struct sudo_event *wevent;
|
||||||
|
struct iovec *iov;
|
||||||
|
unsigned int iovcnt;
|
||||||
|
size_t nbytes;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle expressions like:
|
* Handle expressions like:
|
||||||
* ( user millert or user root ) and tty console and command /bin/sh
|
* ( user millert or user root ) and tty console and command /bin/sh
|
||||||
@@ -162,7 +165,9 @@ struct search_node {
|
|||||||
|
|
||||||
static struct search_node_list search_expr = STAILQ_HEAD_INITIALIZER(search_expr);
|
static struct search_node_list search_expr = STAILQ_HEAD_INITIALIZER(search_expr);
|
||||||
|
|
||||||
static int timing_idx_adj = 0;
|
static int timing_idx_adj;
|
||||||
|
|
||||||
|
static double speed_factor = 1.0;
|
||||||
|
|
||||||
static const char *session_dir = _PATH_SUDO_IO_LOGDIR;
|
static const char *session_dir = _PATH_SUDO_IO_LOGDIR;
|
||||||
|
|
||||||
@@ -186,17 +191,16 @@ extern void get_ttysize(int *rowp, int *colp);
|
|||||||
|
|
||||||
static int list_sessions(int, char **, const char *, const char *, const char *);
|
static int list_sessions(int, char **, const char *, const char *, const char *);
|
||||||
static int parse_expr(struct search_node_list *, char **, bool);
|
static int parse_expr(struct search_node_list *, char **, bool);
|
||||||
static void check_input(int, double *);
|
static void check_input(int fd, int what, void *v);
|
||||||
static void delay(double);
|
|
||||||
static void help(void) __attribute__((__noreturn__));
|
static void help(void) __attribute__((__noreturn__));
|
||||||
static void usage(int);
|
static void usage(int);
|
||||||
static int open_io_fd(char *path, int len, struct io_log_file *iol);
|
static int open_io_fd(char *path, int len, struct io_log_file *iol);
|
||||||
static int parse_timing(const char *buf, const char *decimal, int *idx, double *seconds, size_t *nbytes);
|
static int parse_timing(const char *buf, const char *decimal, int *idx, double *seconds, size_t *nbytes);
|
||||||
static struct log_info *parse_logfile(char *logfile);
|
static struct log_info *parse_logfile(char *logfile);
|
||||||
static void free_log_info(struct log_info *li);
|
static void free_log_info(struct log_info *li);
|
||||||
static ssize_t atomic_writev(int fd, struct iovec *iov, int iovcnt);
|
|
||||||
static void sudoreplay_handler(int);
|
static void sudoreplay_handler(int);
|
||||||
static void sudoreplay_cleanup(void);
|
static void sudoreplay_cleanup(void);
|
||||||
|
static void write_output(int fd, int what, void *v);
|
||||||
|
|
||||||
#ifdef HAVE_REGCOMP
|
#ifdef HAVE_REGCOMP
|
||||||
# define REGEX_T regex_t
|
# define REGEX_T regex_t
|
||||||
@@ -228,12 +232,16 @@ main(int argc, char *argv[])
|
|||||||
bool def_filter = true;
|
bool def_filter = true;
|
||||||
const char *decimal, *id, *user = NULL, *pattern = NULL, *tty = NULL;
|
const char *decimal, *id, *user = NULL, *pattern = NULL, *tty = NULL;
|
||||||
char path[PATH_MAX], buf[LINE_MAX], *cp, *ep;
|
char path[PATH_MAX], buf[LINE_MAX], *cp, *ep;
|
||||||
double seconds, to_wait, speed = 1.0, max_wait = 0;
|
double seconds, to_wait, max_wait = 0;
|
||||||
|
struct sudo_event_base *evbase;
|
||||||
|
struct sudo_event *input_ev, *output_ev;
|
||||||
|
struct timeval timeout;
|
||||||
sigaction_t sa;
|
sigaction_t sa;
|
||||||
size_t len, nbytes, nread;
|
size_t len, nbytes, nread;
|
||||||
struct log_info *li;
|
struct log_info *li;
|
||||||
struct iovec *iov = NULL;
|
struct iovec *iov = NULL;
|
||||||
int iovcnt = 0, iovmax = 0;
|
unsigned int i, iovcnt = 0, iovmax = 0;
|
||||||
|
struct write_closure wc;
|
||||||
debug_decl(main, SUDO_DEBUG_MAIN)
|
debug_decl(main, SUDO_DEBUG_MAIN)
|
||||||
|
|
||||||
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
|
||||||
@@ -291,7 +299,7 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
errno = 0;
|
errno = 0;
|
||||||
speed = strtod(optarg, &ep);
|
speed_factor = strtod(optarg, &ep);
|
||||||
if (*ep != '\0' || errno != 0)
|
if (*ep != '\0' || errno != 0)
|
||||||
fatalx(_("invalid speed factor: %s"), optarg);
|
fatalx(_("invalid speed factor: %s"), optarg);
|
||||||
break;
|
break;
|
||||||
@@ -392,6 +400,18 @@ main(int argc, char *argv[])
|
|||||||
iov = ecalloc(iovmax, sizeof(*iov));
|
iov = ecalloc(iovmax, sizeof(*iov));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Setup event base and input/output events. */
|
||||||
|
evbase = sudo_ev_base_alloc();
|
||||||
|
if (evbase == NULL)
|
||||||
|
fatal(NULL);
|
||||||
|
input_ev = sudo_ev_alloc(STDIN_FILENO, interactive ? SUDO_EV_READ :
|
||||||
|
SUDO_EV_TIMEOUT, check_input, sudo_ev_self_cbarg());
|
||||||
|
if (input_ev == NULL)
|
||||||
|
fatal(NULL);
|
||||||
|
output_ev = sudo_ev_alloc(STDIN_FILENO, SUDO_EV_WRITE, write_output, &wc);
|
||||||
|
if (output_ev == NULL)
|
||||||
|
fatal(NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timing file consists of line of the format: "%f %d\n"
|
* Timing file consists of line of the format: "%f %d\n"
|
||||||
*/
|
*/
|
||||||
@@ -405,14 +425,18 @@ main(int argc, char *argv[])
|
|||||||
if (!parse_timing(buf, decimal, &idx, &seconds, &nbytes))
|
if (!parse_timing(buf, decimal, &idx, &seconds, &nbytes))
|
||||||
fatalx(_("invalid timing file line: %s"), buf);
|
fatalx(_("invalid timing file line: %s"), buf);
|
||||||
|
|
||||||
if (interactive)
|
|
||||||
check_input(STDIN_FILENO, &speed);
|
|
||||||
|
|
||||||
/* Adjust delay using speed factor and clamp to max_wait */
|
/* Adjust delay using speed factor and clamp to max_wait */
|
||||||
to_wait = seconds / speed;
|
to_wait = seconds / speed_factor;
|
||||||
if (max_wait && to_wait > max_wait)
|
if (max_wait && to_wait > max_wait)
|
||||||
to_wait = max_wait;
|
to_wait = max_wait;
|
||||||
delay(to_wait);
|
|
||||||
|
/* Convert delay to a timeval. */
|
||||||
|
timeout.tv_sec = to_wait;
|
||||||
|
timeout.tv_usec = (to_wait - timeout.tv_sec) * 1000000.0;
|
||||||
|
|
||||||
|
/* Run event event loop to delay and get keyboard input. */
|
||||||
|
sudo_ev_add(evbase, input_ev, &timeout, false);
|
||||||
|
sudo_ev_loop(evbase, 0);
|
||||||
|
|
||||||
/* Even if we are not replaying, we still have to delay. */
|
/* Even if we are not replaying, we still have to delay. */
|
||||||
if (io_log_files[idx].fd.v == NULL)
|
if (io_log_files[idx].fd.v == NULL)
|
||||||
@@ -423,6 +447,7 @@ main(int argc, char *argv[])
|
|||||||
need_nlcr = (idx == IOFD_STDOUT || idx == IOFD_STDERR);
|
need_nlcr = (idx == IOFD_STDOUT || idx == IOFD_STDERR);
|
||||||
|
|
||||||
/* All output is sent to stdout. */
|
/* All output is sent to stdout. */
|
||||||
|
/* XXX - assumes no wall clock time spent writing output. */
|
||||||
while (nbytes != 0) {
|
while (nbytes != 0) {
|
||||||
if (nbytes > sizeof(buf))
|
if (nbytes > sizeof(buf))
|
||||||
len = sizeof(buf);
|
len = sizeof(buf);
|
||||||
@@ -485,8 +510,19 @@ main(int argc, char *argv[])
|
|||||||
iov[0].iov_len = nread;
|
iov[0].iov_len = nread;
|
||||||
iovcnt = 1;
|
iovcnt = 1;
|
||||||
}
|
}
|
||||||
if (atomic_writev(STDOUT_FILENO, iov, iovcnt) == -1)
|
|
||||||
fatal(_("writing to standard output"));
|
/* Setup closure for write_output. */
|
||||||
|
memset(&wc, 0, sizeof(wc));
|
||||||
|
wc.wevent = output_ev;
|
||||||
|
wc.iov = iov;
|
||||||
|
wc.iovcnt = iovcnt;
|
||||||
|
for (i = 0; i < iovcnt; i++)
|
||||||
|
wc.nbytes += iov[i].iov_len;
|
||||||
|
|
||||||
|
/* Run event event loop to write output. */
|
||||||
|
/* XXX - should use a single event loop with a circular buffer. */
|
||||||
|
sudo_ev_add(evbase, output_ev, NULL, false);
|
||||||
|
sudo_ev_loop(evbase, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
term_restore(STDIN_FILENO, 1);
|
term_restore(STDIN_FILENO, 1);
|
||||||
@@ -495,31 +531,6 @@ done:
|
|||||||
exit(exitcode);
|
exit(exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
delay(double secs)
|
|
||||||
{
|
|
||||||
struct timespec ts, rts;
|
|
||||||
int rval;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Typical max resolution is 1/HZ but we can't portably check that.
|
|
||||||
* If the interval is small enough, just ignore it.
|
|
||||||
*/
|
|
||||||
if (secs < 0.0001)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rts.tv_sec = secs;
|
|
||||||
rts.tv_nsec = (secs - (double) rts.tv_sec) * 1000000000.0;
|
|
||||||
do {
|
|
||||||
memcpy(&ts, &rts, sizeof(ts));
|
|
||||||
rval = nanosleep(&ts, &rts);
|
|
||||||
} while (rval == -1 && errno == EINTR);
|
|
||||||
if (rval == -1) {
|
|
||||||
fatal_nodebug("nanosleep: tv_sec %lld, tv_nsec %ld",
|
|
||||||
(long long)ts.tv_sec, (long)ts.tv_nsec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
open_io_fd(char *path, int len, struct io_log_file *iol)
|
open_io_fd(char *path, int len, struct io_log_file *iol)
|
||||||
{
|
{
|
||||||
@@ -538,67 +549,55 @@ open_io_fd(char *path, int len, struct io_log_file *iol)
|
|||||||
debug_return_int(iol->fd.v ? 0 : -1);
|
debug_return_int(iol->fd.v ? 0 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void
|
||||||
* Call writev(), restarting as needed and handling EAGAIN since
|
write_output(int fd, int what, void *v)
|
||||||
* fd may be in non-blocking mode.
|
|
||||||
*/
|
|
||||||
static ssize_t
|
|
||||||
atomic_writev(int fd, struct iovec *iov, int iovcnt)
|
|
||||||
{
|
{
|
||||||
ssize_t n, nwritten = 0;
|
struct write_closure *wc = v;
|
||||||
size_t count, remainder, nbytes = 0;
|
ssize_t nwritten;
|
||||||
int i;
|
size_t count, remainder;
|
||||||
debug_decl(atomic_writev, SUDO_DEBUG_UTIL)
|
unsigned int i;
|
||||||
|
debug_decl(write_output, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
for (i = 0; i < iovcnt; i++)
|
nwritten = writev(STDOUT_FILENO, wc->iov, wc->iovcnt);
|
||||||
nbytes += iov[i].iov_len;
|
switch (nwritten) {
|
||||||
|
case -1:
|
||||||
for (;;) {
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
n = writev(STDOUT_FILENO, iov, iovcnt);
|
fatal(_("unable to write to %s"), "stdout");
|
||||||
if (n > 0) {
|
|
||||||
nwritten += n;
|
|
||||||
remainder = nbytes - nwritten;
|
|
||||||
if (remainder == 0)
|
|
||||||
break;
|
break;
|
||||||
/* short writev, adjust iov and do the rest. */
|
case 0:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
remainder = wc->nbytes - nwritten;
|
||||||
|
if (remainder == 0) {
|
||||||
|
/* writev completed */
|
||||||
|
debug_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* short writev, adjust iov so we can write the remainder. */
|
||||||
count = 0;
|
count = 0;
|
||||||
i = iovcnt;
|
i = wc->iovcnt;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
count += iov[i].iov_len;
|
count += wc->iov[i].iov_len;
|
||||||
if (count == remainder) {
|
if (count == remainder) {
|
||||||
iov += i;
|
wc->iov += i;
|
||||||
iovcnt -= i;
|
wc->iovcnt -= i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (count > remainder) {
|
if (count > remainder) {
|
||||||
size_t off = (count - remainder);
|
size_t off = (count - remainder);
|
||||||
/* XXX - side effect prevents iov from being const */
|
wc->iov[i].iov_base = (char *)wc->iov[i].iov_base + off;
|
||||||
iov[i].iov_base = (char *)iov[i].iov_base + off;
|
wc->iov[i].iov_len -= off;
|
||||||
iov[i].iov_len -= off;
|
wc->iov += i;
|
||||||
iov += i;
|
wc->iovcnt -= i;
|
||||||
iovcnt -= i;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (n == 0 || errno == EAGAIN) {
|
|
||||||
int nready;
|
|
||||||
fd_set fdsw;
|
|
||||||
FD_ZERO(&fdsw);
|
|
||||||
FD_SET(STDOUT_FILENO, &fdsw);
|
|
||||||
do {
|
|
||||||
nready = select(STDOUT_FILENO + 1, NULL, &fdsw, NULL, NULL);
|
|
||||||
} while (nready == -1 && errno == EINTR);
|
|
||||||
if (nready == 1)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
nwritten = -1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
debug_return_size_t(nwritten);
|
|
||||||
|
/* Reschedule event to write remainder. */
|
||||||
|
sudo_ev_add(sudo_ev_get_base(wc->wevent), wc->wevent, NULL, false);
|
||||||
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1051,44 +1050,58 @@ list_sessions(int argc, char **argv, const char *pattern, const char *user,
|
|||||||
* pause, slow, fast
|
* pause, slow, fast
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
check_input(int ttyfd, double *speed)
|
check_input(int fd, int what, void *v)
|
||||||
{
|
{
|
||||||
fd_set *fdsr;
|
struct sudo_event *ev = v;
|
||||||
int nready, paused = 0;
|
struct sudo_event_base *evbase = sudo_ev_get_base(ev);
|
||||||
struct timeval tv;
|
struct timeval tv, *timeout = NULL;
|
||||||
|
static bool paused = 0;
|
||||||
char ch;
|
char ch;
|
||||||
ssize_t n;
|
|
||||||
debug_decl(check_input, SUDO_DEBUG_UTIL)
|
debug_decl(check_input, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
fdsr = ecalloc(howmany(ttyfd + 1, NFDBITS), sizeof(fd_mask));
|
if (ISSET(what, SUDO_EV_READ)) {
|
||||||
for (;;) {
|
switch (read(fd, &ch, 1)) {
|
||||||
FD_SET(ttyfd, fdsr);
|
case -1:
|
||||||
tv.tv_sec = 0;
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
tv.tv_usec = 0;
|
fatal(_("unable to read %s"), "stdin");
|
||||||
|
|
||||||
nready = select(ttyfd + 1, fdsr, NULL, NULL, paused ? NULL : &tv);
|
|
||||||
if (nready != 1)
|
|
||||||
break;
|
break;
|
||||||
n = read(ttyfd, &ch, 1);
|
case 0:
|
||||||
if (n == 1) {
|
/* Ignore EOF. */
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
if (paused) {
|
if (paused) {
|
||||||
paused = 0;
|
/* Any key will unpause, event is finished. */
|
||||||
continue;
|
/* XXX - pause time could be less than timeout */
|
||||||
|
paused = false;
|
||||||
|
debug_return;
|
||||||
}
|
}
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
paused = 1;
|
paused = true;
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
*speed /= 2;
|
speed_factor /= 2;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
*speed *= 2;
|
speed_factor *= 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
timeout = &tv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(fdsr);
|
/* Re-enable event. */
|
||||||
|
sudo_ev_add(evbase, ev, timeout, false);
|
||||||
|
}
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -305,7 +305,7 @@ exec_event_setup(int backchannel, struct exec_closure *ec)
|
|||||||
SUDO_EV_READ|SUDO_EV_PERSIST, signal_pipe_cb, ec);
|
SUDO_EV_READ|SUDO_EV_PERSIST, signal_pipe_cb, ec);
|
||||||
if (signal_event == NULL)
|
if (signal_event == NULL)
|
||||||
fatal(NULL);
|
fatal(NULL);
|
||||||
if (sudo_ev_add(evbase, signal_event, false) == -1)
|
if (sudo_ev_add(evbase, signal_event, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
|
|
||||||
/* Event for command status via backchannel. */
|
/* Event for command status via backchannel. */
|
||||||
@@ -313,7 +313,7 @@ exec_event_setup(int backchannel, struct exec_closure *ec)
|
|||||||
SUDO_EV_READ|SUDO_EV_PERSIST, backchannel_cb, ec);
|
SUDO_EV_READ|SUDO_EV_PERSIST, backchannel_cb, ec);
|
||||||
if (backchannel_event == NULL)
|
if (backchannel_event == NULL)
|
||||||
fatal(NULL);
|
fatal(NULL);
|
||||||
if (sudo_ev_add(evbase, backchannel_event, false) == -1)
|
if (sudo_ev_add(evbase, backchannel_event, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
|
|
||||||
/* The signal forwarding event gets added on demand. */
|
/* The signal forwarding event gets added on demand. */
|
||||||
@@ -837,7 +837,7 @@ schedule_signal(struct sudo_event_base *evbase, int signo)
|
|||||||
sigfwd->signo = signo;
|
sigfwd->signo = signo;
|
||||||
TAILQ_INSERT_TAIL(&sigfwd_list, sigfwd, entries);
|
TAILQ_INSERT_TAIL(&sigfwd_list, sigfwd, entries);
|
||||||
|
|
||||||
if (sudo_ev_add(evbase, sigfwd_event, true) == -1)
|
if (sudo_ev_add(evbase, sigfwd_event, NULL, true) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
|
@@ -503,12 +503,12 @@ io_callback(int fd, int what, void *v)
|
|||||||
/* Enable writer if not /dev/tty or we are foreground pgrp. */
|
/* Enable writer if not /dev/tty or we are foreground pgrp. */
|
||||||
if (iob->wevent != NULL &&
|
if (iob->wevent != NULL &&
|
||||||
(foreground || !USERTTY_EVENT(iob->wevent))) {
|
(foreground || !USERTTY_EVENT(iob->wevent))) {
|
||||||
if (sudo_ev_add(evbase, iob->wevent, false) == -1)
|
if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
/* Re-enable reader if buffer is not full. */
|
/* Re-enable reader if buffer is not full. */
|
||||||
if (iob->len != sizeof(iob->buf)) {
|
if (iob->len != sizeof(iob->buf)) {
|
||||||
if (sudo_ev_add(evbase, iob->revent, false) == -1)
|
if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -566,14 +566,14 @@ io_callback(int fd, int what, void *v)
|
|||||||
}
|
}
|
||||||
/* Re-enable writer if buffer is not empty. */
|
/* Re-enable writer if buffer is not empty. */
|
||||||
if (iob->len > iob->off) {
|
if (iob->len > iob->off) {
|
||||||
if (sudo_ev_add(evbase, iob->wevent, false) == -1)
|
if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
/* Enable reader if buffer is not full. */
|
/* Enable reader if buffer is not full. */
|
||||||
if (iob->revent != NULL &&
|
if (iob->revent != NULL &&
|
||||||
(ttymode == TERM_RAW || !USERTTY_EVENT(iob->revent))) {
|
(ttymode == TERM_RAW || !USERTTY_EVENT(iob->revent))) {
|
||||||
if (iob->len != sizeof(iob->buf)) {
|
if (iob->len != sizeof(iob->buf)) {
|
||||||
if (sudo_ev_add(evbase, iob->revent, false) == -1)
|
if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -866,7 +866,7 @@ add_io_events(struct sudo_event_base *evbase)
|
|||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"added I/O revent %p, fd %d, events %d",
|
"added I/O revent %p, fd %d, events %d",
|
||||||
iob->revent, iob->revent->fd, iob->revent->events);
|
iob->revent, iob->revent->fd, iob->revent->events);
|
||||||
if (sudo_ev_add(evbase, iob->revent, false) == -1)
|
if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -876,7 +876,7 @@ add_io_events(struct sudo_event_base *evbase)
|
|||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"added I/O wevent %p, fd %d, events %d",
|
"added I/O wevent %p, fd %d, events %d",
|
||||||
iob->wevent, iob->wevent->fd, iob->wevent->events);
|
iob->wevent, iob->wevent->fd, iob->wevent->events);
|
||||||
if (sudo_ev_add(evbase, iob->wevent, false) == -1)
|
if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -921,14 +921,14 @@ del_io_events(void)
|
|||||||
/* Don't read from /dev/tty while flushing. */
|
/* Don't read from /dev/tty while flushing. */
|
||||||
if (iob->revent != NULL && !USERTTY_EVENT(iob->revent)) {
|
if (iob->revent != NULL && !USERTTY_EVENT(iob->revent)) {
|
||||||
if (iob->len != sizeof(iob->buf)) {
|
if (iob->len != sizeof(iob->buf)) {
|
||||||
if (sudo_ev_add(evbase, iob->revent, false) == -1)
|
if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Flush any write buffers with data in them. */
|
/* Flush any write buffers with data in them. */
|
||||||
if (iob->wevent != NULL) {
|
if (iob->wevent != NULL) {
|
||||||
if (iob->len > iob->off) {
|
if (iob->len > iob->off) {
|
||||||
if (sudo_ev_add(evbase, iob->wevent, false) == -1)
|
if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1330,21 +1330,21 @@ exec_monitor(struct command_details *details, int backchannel)
|
|||||||
SUDO_EV_READ|SUDO_EV_PERSIST, mon_signal_pipe_cb, &mc);
|
SUDO_EV_READ|SUDO_EV_PERSIST, mon_signal_pipe_cb, &mc);
|
||||||
if (mc.signal_pipe_event == NULL)
|
if (mc.signal_pipe_event == NULL)
|
||||||
fatal(NULL);
|
fatal(NULL);
|
||||||
if (sudo_ev_add(evbase, mc.signal_pipe_event, false) == -1)
|
if (sudo_ev_add(evbase, mc.signal_pipe_event, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
|
|
||||||
mc.errpipe_event = sudo_ev_alloc(errpipe[0],
|
mc.errpipe_event = sudo_ev_alloc(errpipe[0],
|
||||||
SUDO_EV_READ|SUDO_EV_PERSIST, mon_errpipe_cb, &mc);
|
SUDO_EV_READ|SUDO_EV_PERSIST, mon_errpipe_cb, &mc);
|
||||||
if (mc.errpipe_event == NULL)
|
if (mc.errpipe_event == NULL)
|
||||||
fatal(NULL);
|
fatal(NULL);
|
||||||
if (sudo_ev_add(evbase, mc.errpipe_event, false) == -1)
|
if (sudo_ev_add(evbase, mc.errpipe_event, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
|
|
||||||
mc.backchannel_event = sudo_ev_alloc(backchannel,
|
mc.backchannel_event = sudo_ev_alloc(backchannel,
|
||||||
SUDO_EV_READ|SUDO_EV_PERSIST, mon_backchannel_cb, &mc);
|
SUDO_EV_READ|SUDO_EV_PERSIST, mon_backchannel_cb, &mc);
|
||||||
if (mc.backchannel_event == NULL)
|
if (mc.backchannel_event == NULL)
|
||||||
fatal(NULL);
|
fatal(NULL);
|
||||||
if (sudo_ev_add(evbase, mc.backchannel_event, false) == -1)
|
if (sudo_ev_add(evbase, mc.backchannel_event, NULL, false) == -1)
|
||||||
fatal(_("unable to add event to queue"));
|
fatal(_("unable to add event to queue"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user