Home | History | Annotate | Line # | Download | only in src
      1 /* SPDX-License-Identifier: BSD-2-Clause */
      2 /*
      3  * eloop - portable event based main loop.
      4  * Copyright (c) 2006-2025 Roy Marples <roy (at) marples.name>
      5  * All rights reserved.
      6 
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #if (defined(__unix__) || defined(unix)) && !defined(USG)
     30 #include <sys/param.h>
     31 #endif
     32 #include <sys/time.h>
     33 
     34 /*
     35  * On BSD use kqueue(2)
     36  * On Linux use epoll(7)
     37  * Everywhere else use ppoll(2)
     38  */
     39 #ifdef BSD
     40 #include <sys/event.h>
     41 #define USE_KQUEUE
     42 #if defined(__NetBSD__)
     43 #define HAVE_KQUEUE1
     44 #define KEVENT_N size_t
     45 #else
     46 #define KEVENT_N int
     47 #endif
     48 #elif defined(__linux__)
     49 #include <sys/epoll.h>
     50 #define USE_EPOLL
     51 /* musl does not support epoll_wait2 and some distros
     52  * mismatch headers vs actual kernel so it's too problematic. */
     53 #else
     54 #define USE_PPOLL
     55 #endif
     56 
     57 #include <errno.h>
     58 #include <fcntl.h>
     59 #include <limits.h>
     60 #include <poll.h>
     61 #include <signal.h>
     62 #include <stdbool.h>
     63 #include <stdint.h>
     64 #include <stdlib.h>
     65 #include <string.h>
     66 #include <unistd.h>
     67 
     68 #include "eloop.h"
     69 #include "queue.h"
     70 
     71 /*
     72  * Allow a backlog of signals.
     73  * If you use many eloops in the same process, they should all
     74  * use the same signal handler or have the signal handler unset.
     75  * Otherwise the signal might not behave as expected.
     76  */
     77 #define ELOOP_NSIGNALS 5
     78 
     79 /*
     80  * time_t is a signed integer of an unspecified size.
     81  * To adjust for time_t wrapping, we need to work the maximum signed
     82  * value and use that as a maximum.
     83  */
     84 #ifndef TIME_MAX
     85 #define TIME_MAX ((1ULL << (sizeof(time_t) * NBBY - 1)) - 1)
     86 #endif
     87 /* The unsigned maximum is then simple - multiply by two and add one. */
     88 #ifndef UTIME_MAX
     89 #define UTIME_MAX (TIME_MAX * 2) + 1
     90 #endif
     91 
     92 #ifndef UNUSED
     93 #define UNUSED(a) (void)(a)
     94 #endif
     95 
     96 struct eloop_event {
     97 	TAILQ_ENTRY(eloop_event) next;
     98 	int fd;
     99 	void (*cb)(void *, unsigned short);
    100 	void *cb_arg;
    101 	unsigned short events;
    102 #ifdef USE_PPOLL
    103 	struct pollfd *pollfd;
    104 #endif
    105 };
    106 
    107 struct eloop_timeout {
    108 	TAILQ_ENTRY(eloop_timeout) next;
    109 	unsigned int seconds;
    110 	unsigned int nseconds;
    111 	void (*callback)(void *);
    112 	void *arg;
    113 	int queue;
    114 };
    115 
    116 struct eloop {
    117 	TAILQ_ENTRY(eloop) next;
    118 	TAILQ_HEAD(event_head, eloop_event) events;
    119 	size_t nevents;
    120 	struct event_head free_events;
    121 
    122 	struct timespec now;
    123 	TAILQ_HEAD(timeout_head, eloop_timeout) timeouts;
    124 	struct timeout_head free_timeouts;
    125 
    126 	const int *signals;
    127 	size_t nsignals;
    128 	sigset_t sigset;
    129 	void (*signal_cb)(int, void *);
    130 	void *signal_cb_ctx;
    131 
    132 #if defined(USE_KQUEUE) || defined(USE_EPOLL)
    133 	int fd;
    134 #endif
    135 #if defined(USE_KQUEUE)
    136 	struct kevent *fds;
    137 #elif defined(USE_EPOLL)
    138 	struct epoll_event *fds;
    139 #elif defined(USE_PPOLL)
    140 	struct pollfd *fds;
    141 #endif
    142 	size_t nfds;
    143 
    144 	int exitcode;
    145 	bool exitnow;
    146 	bool events_need_setup;
    147 	bool events_invalid;
    148 };
    149 
    150 #ifdef HAVE_REALLOCARRAY
    151 #define eloop_realloca reallocarray
    152 #else
    153 /* Handy routing to check for potential overflow.
    154  * reallocarray(3) and reallocarr(3) are not portable. */
    155 #define SQRT_SIZE_MAX (((size_t)1) << (sizeof(size_t) * CHAR_BIT / 2))
    156 static void *
    157 eloop_realloca(void *ptr, size_t n, size_t size)
    158 {
    159 	if ((n | size) >= SQRT_SIZE_MAX && n > SIZE_MAX / size) {
    160 		errno = EOVERFLOW;
    161 		return NULL;
    162 	}
    163 	return realloc(ptr, n * size);
    164 }
    165 #endif
    166 
    167 static int
    168 eloop_event_setup_fds(struct eloop *eloop)
    169 {
    170 	struct eloop_event *e, *ne;
    171 #ifdef USE_PPOLL
    172 	struct pollfd *pfd;
    173 
    174 	if (eloop->nevents > eloop->nfds) {
    175 		pfd = eloop_realloca(eloop->fds, eloop->nevents, sizeof(*pfd));
    176 		if (pfd == NULL)
    177 			return -1;
    178 		eloop->fds = pfd;
    179 		eloop->nfds = eloop->nevents;
    180 	} else
    181 		pfd = eloop->fds;
    182 #endif
    183 
    184 	TAILQ_FOREACH_SAFE(e, &eloop->events, next, ne) {
    185 		if (e->fd == -1) {
    186 			TAILQ_REMOVE(&eloop->events, e, next);
    187 			TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
    188 			continue;
    189 		}
    190 #ifdef USE_PPOLL
    191 		e->pollfd = pfd;
    192 		pfd->fd = e->fd;
    193 		pfd->events = 0;
    194 		if (e->events & ELE_READ)
    195 			pfd->events |= POLLIN;
    196 		if (e->events & ELE_WRITE)
    197 			pfd->events |= POLLOUT;
    198 		pfd->revents = 0;
    199 		pfd++;
    200 #endif
    201 	}
    202 
    203 	eloop->events_need_setup = false;
    204 	return 0;
    205 }
    206 
    207 #ifndef USE_PPOLL
    208 static int
    209 eloop_grow_events(struct eloop *eloop)
    210 {
    211 #if defined(USE_KQUEUE)
    212 	struct kevent *pfd;
    213 #elif defined(USE_EPOLL)
    214 	struct epoll_event *pfd;
    215 #endif
    216 	size_t nfds = eloop->nfds == 0 ? 4 : eloop->nfds * 2;
    217 
    218 	pfd = eloop_realloca(eloop->fds, nfds, sizeof(*pfd));
    219 	if (pfd == NULL)
    220 		return -1;
    221 	eloop->fds = pfd;
    222 	eloop->nfds = nfds;
    223 	return 0;
    224 }
    225 #endif
    226 
    227 size_t
    228 eloop_event_count(const struct eloop *eloop)
    229 {
    230 	return eloop->nevents;
    231 }
    232 
    233 #if defined(USE_KQUEUE)
    234 
    235 static int
    236 eloop_signal_kqueue(struct eloop *eloop, const int *signals, size_t nsignals)
    237 {
    238 	unsigned int cmd = nsignals == 0 ? EV_DELETE : EV_ADD;
    239 	struct kevent *ke, *kep;
    240 	size_t i;
    241 	int err;
    242 
    243 	if (nsignals == 0) {
    244 		signals = eloop->signals;
    245 		nsignals = eloop->nsignals;
    246 	}
    247 	if (nsignals == 0)
    248 		return 0;
    249 
    250 	ke = kep = eloop_realloca(NULL, nsignals, sizeof(*ke));
    251 	if (ke == NULL)
    252 		return -1;
    253 
    254 	for (i = 0; i < nsignals; i++)
    255 		EV_SET(kep++, (uintptr_t)signals[i], EVFILT_SIGNAL, cmd, 0, 0,
    256 		    NULL);
    257 
    258 	err = kevent(eloop->fd, ke, (KEVENT_N)nsignals, NULL, 0, NULL);
    259 	free(ke);
    260 	return err;
    261 }
    262 
    263 static int
    264 eloop_event_kqueue(struct eloop *eloop, struct eloop_event *e,
    265     unsigned short events)
    266 {
    267 #ifdef EVFILT_PROCDESC
    268 #define NKE 3
    269 #else
    270 #define NKE 2
    271 #endif
    272 	struct kevent ke[NKE], *kep = ke;
    273 	int fd = e->fd;
    274 
    275 	if (events & ELE_READ && !(e->events & ELE_READ))
    276 		EV_SET(kep++, (uintptr_t)fd, EVFILT_READ, EV_ADD, 0, 0, e);
    277 	else if (!(events & ELE_READ) && e->events & ELE_READ)
    278 		EV_SET(kep++, (uintptr_t)fd, EVFILT_READ, EV_DELETE, 0, 0, e);
    279 	if (events & ELE_WRITE && !(e->events & ELE_WRITE))
    280 		EV_SET(kep++, (uintptr_t)fd, EVFILT_WRITE, EV_ADD, 0, 0, e);
    281 	else if (!(events & ELE_WRITE) && e->events & ELE_WRITE)
    282 		EV_SET(kep++, (uintptr_t)fd, EVFILT_WRITE, EV_DELETE, 0, 0, e);
    283 #ifdef EVFILT_PROCDESC
    284 	if (events & ELE_HANGUP && !(e->events & ELE_HANGUP))
    285 		EV_SET(kep++, (uintptr_t)fd, EVFILT_PROCDESC, EV_ADD, NOTE_EXIT,
    286 		    0, e);
    287 	else if (!(events & ELE_HANGUP) && e->events & ELE_HANGUP)
    288 		EV_SET(kep++, (uintptr_t)fd, EVFILT_PROCDESC, EV_DELETE,
    289 		    NOTE_EXIT, 0, e);
    290 #endif
    291 	if (kep == ke)
    292 		return 0;
    293 	if (kevent(eloop->fd, ke, (KEVENT_N)(kep - ke), NULL, 0, NULL) == -1)
    294 		return -1;
    295 	return 1;
    296 }
    297 
    298 #elif defined(USE_EPOLL)
    299 
    300 static int
    301 eloop_event_epoll(struct eloop *eloop, struct eloop_event *e,
    302     unsigned short events)
    303 {
    304 	struct epoll_event epe;
    305 	int op;
    306 
    307 	memset(&epe, 0, sizeof(epe));
    308 	epe.data.ptr = e;
    309 	if (events & ELE_READ)
    310 		epe.events |= EPOLLIN;
    311 	if (events & ELE_WRITE)
    312 		epe.events |= EPOLLOUT;
    313 	op = e->events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
    314 	if (epe.events == 0)
    315 		return 0;
    316 	if (epoll_ctl(eloop->fd, op, e->fd, &epe) == -1)
    317 		return -1;
    318 	return 1;
    319 }
    320 #endif
    321 
    322 int
    323 eloop_event_add(struct eloop *eloop, int fd, unsigned short events,
    324     void (*cb)(void *, unsigned short), void *cb_arg)
    325 {
    326 	struct eloop_event *e;
    327 	bool added;
    328 	int kadded;
    329 
    330 	if (fd == -1 || !(events & (ELE_READ | ELE_WRITE | ELE_HANGUP))) {
    331 		errno = EINVAL;
    332 		return -1;
    333 	}
    334 
    335 	TAILQ_FOREACH(e, &eloop->events, next) {
    336 		if (e->fd == fd)
    337 			break;
    338 	}
    339 
    340 	if (e == NULL) {
    341 		added = true;
    342 		e = TAILQ_FIRST(&eloop->free_events);
    343 		if (e != NULL)
    344 			TAILQ_REMOVE(&eloop->free_events, e, next);
    345 		else {
    346 			e = malloc(sizeof(*e));
    347 			if (e == NULL) {
    348 				return -1;
    349 			}
    350 		}
    351 		TAILQ_INSERT_HEAD(&eloop->events, e, next);
    352 		eloop->nevents++;
    353 		e->fd = fd;
    354 		e->events = 0;
    355 	} else
    356 		added = false;
    357 
    358 	e->cb = cb;
    359 	e->cb_arg = cb_arg;
    360 
    361 #if defined(USE_KQUEUE)
    362 	kadded = eloop_event_kqueue(eloop, e, events);
    363 #elif defined(USE_EPOLL)
    364 	kadded = eloop_event_epoll(eloop, e, events);
    365 #elif defined(USE_PPOLL)
    366 	e->pollfd = NULL;
    367 	kadded = 1;
    368 #endif
    369 
    370 	if (kadded != 1 && added) {
    371 		TAILQ_REMOVE(&eloop->events, e, next);
    372 		TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
    373 	}
    374 
    375 	e->events = events;
    376 	eloop->events_need_setup = true;
    377 	return kadded;
    378 }
    379 
    380 int
    381 eloop_event_delete(struct eloop *eloop, int fd)
    382 {
    383 	struct eloop_event *e;
    384 #if defined(USE_KQUEUE)
    385 	struct kevent ke[2], *kep = &ke[0];
    386 	size_t n;
    387 #endif
    388 
    389 	if (fd == -1) {
    390 		errno = EINVAL;
    391 		return -1;
    392 	}
    393 
    394 	TAILQ_FOREACH(e, &eloop->events, next) {
    395 		if (e->fd == fd)
    396 			break;
    397 	}
    398 	if (e == NULL) {
    399 		errno = ENOENT;
    400 		return -1;
    401 	}
    402 
    403 #if defined(USE_KQUEUE)
    404 	n = 0;
    405 	if (e->events & ELE_READ) {
    406 		EV_SET(kep++, (uintptr_t)fd, EVFILT_READ, EV_DELETE, 0, 0, e);
    407 		n++;
    408 	}
    409 	if (e->events & ELE_WRITE) {
    410 		EV_SET(kep++, (uintptr_t)fd, EVFILT_WRITE, EV_DELETE, 0, 0, e);
    411 		n++;
    412 	}
    413 	if (n != 0 && kevent(eloop->fd, ke, (KEVENT_N)n, NULL, 0, NULL) == -1)
    414 		return -1;
    415 #elif defined(USE_EPOLL)
    416 	if (epoll_ctl(eloop->fd, EPOLL_CTL_DEL, fd, NULL) == -1)
    417 		return -1;
    418 #endif
    419 
    420 	e->fd = -1;
    421 	eloop->nevents--;
    422 	eloop->events_need_setup = true;
    423 	return 1;
    424 }
    425 
    426 unsigned long long
    427 eloop_timespec_diff(const struct timespec *tsp, const struct timespec *usp,
    428     unsigned int *nsp)
    429 {
    430 	unsigned long long tsecs, usecs, secs;
    431 	long nsecs;
    432 
    433 	if (tsp->tv_sec < 0) /* time wrapped */
    434 		tsecs = UTIME_MAX - (unsigned long long)(-tsp->tv_sec);
    435 	else
    436 		tsecs = (unsigned long long)tsp->tv_sec;
    437 	if (usp->tv_sec < 0) /* time wrapped */
    438 		usecs = UTIME_MAX - (unsigned long long)(-usp->tv_sec);
    439 	else
    440 		usecs = (unsigned long long)usp->tv_sec;
    441 
    442 	if (usecs > tsecs) /* time wrapped */
    443 		secs = (UTIME_MAX - usecs) + tsecs;
    444 	else
    445 		secs = tsecs - usecs;
    446 
    447 	nsecs = tsp->tv_nsec - usp->tv_nsec;
    448 	if (nsecs < 0) {
    449 		if (secs == 0)
    450 			nsecs = 0;
    451 		else {
    452 			secs--;
    453 			nsecs += NSEC_PER_SEC;
    454 		}
    455 	}
    456 	if (nsp != NULL)
    457 		*nsp = (unsigned int)nsecs;
    458 	return secs;
    459 }
    460 
    461 static int
    462 eloop_reduce_timers(struct eloop *eloop)
    463 {
    464 	struct timespec now;
    465 	unsigned long long secs;
    466 	unsigned int nsecs;
    467 	struct eloop_timeout *t;
    468 
    469 	if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
    470 		return -1;
    471 	secs = eloop_timespec_diff(&now, &eloop->now, &nsecs);
    472 
    473 	TAILQ_FOREACH(t, &eloop->timeouts, next) {
    474 		if (secs > t->seconds) {
    475 			t->seconds = 0;
    476 			t->nseconds = 0;
    477 		} else {
    478 			t->seconds -= (unsigned int)secs;
    479 			if (nsecs > t->nseconds) {
    480 				if (t->seconds == 0)
    481 					t->nseconds = 0;
    482 				else {
    483 					t->seconds--;
    484 					t->nseconds = NSEC_PER_SEC -
    485 					    (nsecs - t->nseconds);
    486 				}
    487 			} else
    488 				t->nseconds -= nsecs;
    489 		}
    490 	}
    491 
    492 	eloop->now = now;
    493 	return 0;
    494 }
    495 
    496 /*
    497  * This implementation should cope with UINT_MAX seconds on a system
    498  * where time_t is INT32_MAX. It should also cope with the monotonic timer
    499  * wrapping, although this is highly unlikely.
    500  * unsigned int should match or be greater than any on wire specified timeout.
    501  */
    502 static int
    503 eloop_q_timeout_add(struct eloop *eloop, int queue, unsigned int seconds,
    504     unsigned int nseconds, void (*callback)(void *), void *arg)
    505 {
    506 	struct eloop_timeout *t, *tt = NULL;
    507 
    508 	/* Remove existing timeout if present. */
    509 	TAILQ_FOREACH(t, &eloop->timeouts, next) {
    510 		if (t->callback == callback && t->arg == arg) {
    511 			TAILQ_REMOVE(&eloop->timeouts, t, next);
    512 			break;
    513 		}
    514 	}
    515 
    516 	if (eloop_reduce_timers(eloop) == -1) {
    517 		if (t != NULL)
    518 			free(t);
    519 		return -1;
    520 	}
    521 
    522 	if (t == NULL) {
    523 		/* No existing, so allocate or grab one from the free pool. */
    524 		if ((t = TAILQ_FIRST(&eloop->free_timeouts))) {
    525 			TAILQ_REMOVE(&eloop->free_timeouts, t, next);
    526 		} else {
    527 			if ((t = malloc(sizeof(*t))) == NULL)
    528 				return -1;
    529 		}
    530 	}
    531 
    532 	t->seconds = seconds;
    533 	t->nseconds = nseconds;
    534 	t->callback = callback;
    535 	t->arg = arg;
    536 	t->queue = queue;
    537 
    538 	/* The timeout list should be in chronological order,
    539 	 * soonest first. */
    540 	TAILQ_FOREACH(tt, &eloop->timeouts, next) {
    541 		if (t->seconds < tt->seconds ||
    542 		    (t->seconds == tt->seconds && t->nseconds < tt->nseconds)) {
    543 			TAILQ_INSERT_BEFORE(tt, t, next);
    544 			return 0;
    545 		}
    546 	}
    547 	TAILQ_INSERT_TAIL(&eloop->timeouts, t, next);
    548 	return 0;
    549 }
    550 
    551 int
    552 eloop_q_timeout_add_tv(struct eloop *eloop, int queue,
    553     const struct timespec *when, void (*callback)(void *), void *arg)
    554 {
    555 	if (when->tv_sec < 0 || (unsigned long)when->tv_sec > UINT_MAX) {
    556 		errno = EINVAL;
    557 		return -1;
    558 	}
    559 	if (when->tv_nsec < 0 || when->tv_nsec > NSEC_PER_SEC) {
    560 		errno = EINVAL;
    561 		return -1;
    562 	}
    563 
    564 	return eloop_q_timeout_add(eloop, queue, (unsigned int)when->tv_sec,
    565 	    (unsigned int)when->tv_sec, callback, arg);
    566 }
    567 
    568 int
    569 eloop_q_timeout_add_sec(struct eloop *eloop, int queue, unsigned int seconds,
    570     void (*callback)(void *), void *arg)
    571 {
    572 	return eloop_q_timeout_add(eloop, queue, seconds, 0, callback, arg);
    573 }
    574 
    575 int
    576 eloop_q_timeout_add_msec(struct eloop *eloop, int queue, unsigned long when,
    577     void (*callback)(void *), void *arg)
    578 {
    579 	unsigned long seconds, nseconds;
    580 
    581 	seconds = when / MSEC_PER_SEC;
    582 	if (seconds > UINT_MAX) {
    583 		errno = EINVAL;
    584 		return -1;
    585 	}
    586 
    587 	nseconds = (when % MSEC_PER_SEC) * NSEC_PER_MSEC;
    588 	return eloop_q_timeout_add(eloop, queue, (unsigned int)seconds,
    589 	    (unsigned int)nseconds, callback, arg);
    590 }
    591 
    592 int
    593 eloop_q_timeout_delete(struct eloop *eloop, int queue, void (*callback)(void *),
    594     void *arg)
    595 {
    596 	struct eloop_timeout *t, *tt;
    597 	int n;
    598 
    599 	n = 0;
    600 	TAILQ_FOREACH_SAFE(t, &eloop->timeouts, next, tt) {
    601 		if ((queue == 0 || t->queue == queue) && t->arg == arg &&
    602 		    (!callback || t->callback == callback)) {
    603 			TAILQ_REMOVE(&eloop->timeouts, t, next);
    604 			TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
    605 			n++;
    606 		}
    607 	}
    608 	return n;
    609 }
    610 
    611 void
    612 eloop_exit(struct eloop *eloop, int code)
    613 {
    614 	eloop->exitcode = code;
    615 	eloop->exitnow = true;
    616 }
    617 
    618 #if defined(USE_KQUEUE) || defined(USE_EPOLL)
    619 static int
    620 eloop_open(struct eloop *eloop)
    621 {
    622 	int fd;
    623 
    624 #if defined(HAVE_KQUEUE1)
    625 	fd = kqueue1(O_CLOEXEC);
    626 #elif defined(KQUEUE_CLOEXEC)
    627 	fd = kqueuex(KQUEUE_CLOEXEC);
    628 #elif defined(USE_KQUEUE)
    629 	int flags;
    630 
    631 	fd = kqueue();
    632 	flags = fcntl(fd, F_GETFD, 0);
    633 	if (!(flags != -1 && !(flags & FD_CLOEXEC) &&
    634 		fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0)) {
    635 		close(fd);
    636 		return -1;
    637 	}
    638 #elif defined(USE_EPOLL)
    639 	fd = epoll_create1(EPOLL_CLOEXEC);
    640 #endif
    641 
    642 	eloop->fd = fd;
    643 	return fd;
    644 }
    645 #endif
    646 
    647 static void
    648 eloop_clear(struct eloop *eloop, unsigned short flags)
    649 {
    650 	if (eloop == NULL)
    651 		return;
    652 
    653 	if (!(flags & ELF_KEEP_SIGNALS)) {
    654 		eloop->signals = NULL;
    655 		eloop->nsignals = 0;
    656 		eloop->signal_cb = NULL;
    657 		eloop->signal_cb_ctx = NULL;
    658 	}
    659 
    660 	if (!(flags & ELF_KEEP_EVENTS)) {
    661 		struct eloop_event *e, *en;
    662 
    663 		TAILQ_FOREACH_SAFE(e, &eloop->events, next, en)
    664 			free(e);
    665 		TAILQ_INIT(&eloop->events);
    666 
    667 		TAILQ_FOREACH_SAFE(e, &eloop->free_events, next, en)
    668 			free(e);
    669 		TAILQ_INIT(&eloop->free_events);
    670 
    671 		eloop->nevents = 0;
    672 		eloop->events_invalid = true;
    673 	}
    674 
    675 	if (!(flags & ELF_KEEP_TIMEOUTS)) {
    676 		struct eloop_timeout *t, *tn;
    677 
    678 		TAILQ_FOREACH_SAFE(t, &eloop->timeouts, next, tn)
    679 			free(t);
    680 		TAILQ_INIT(&eloop->timeouts);
    681 
    682 		TAILQ_FOREACH_SAFE(t, &eloop->free_timeouts, next, tn)
    683 			free(t);
    684 		TAILQ_INIT(&eloop->free_timeouts);
    685 	}
    686 }
    687 
    688 /* Must be called after fork(2) */
    689 int
    690 eloop_forked(struct eloop *eloop, unsigned short flags)
    691 {
    692 #if defined(USE_KQUEUE) || defined(USE_EPOLL)
    693 	struct eloop_event *e;
    694 	unsigned short events;
    695 	int err;
    696 
    697 	/* The fd is invalid after a fork, no need to close it. */
    698 	eloop->fd = -1;
    699 	if (flags && eloop_open(eloop) == -1)
    700 		return -1;
    701 
    702 	eloop_clear(eloop, flags);
    703 	if (!flags)
    704 		return 0;
    705 
    706 #ifdef USE_KQUEUE
    707 	if (eloop_signal_kqueue(eloop, eloop->signals, eloop->nsignals) == -1)
    708 		return -1;
    709 #endif
    710 
    711 	TAILQ_FOREACH(e, &eloop->events, next) {
    712 		if (e->fd == -1)
    713 			continue;
    714 		events = e->events;
    715 		e->events = 0;
    716 #if defined(USE_KQUEUE)
    717 		err = eloop_event_kqueue(eloop, e, events);
    718 #elif defined(USE_EPOLL)
    719 		err = eloop_event_epoll(eloop, e, events);
    720 #endif
    721 		if (err == -1)
    722 			return -1;
    723 	}
    724 	return 0;
    725 #else
    726 	eloop_clear(eloop, flags);
    727 	return 0;
    728 #endif
    729 }
    730 
    731 int
    732 eloop_signal_set_cb(struct eloop *eloop, const int *signals, size_t nsignals,
    733     void (*signal_cb)(int, void *), void *signal_cb_ctx)
    734 {
    735 #ifdef USE_KQUEUE
    736 	if (eloop_signal_kqueue(eloop, NULL, 0) == -1)
    737 		return -1;
    738 #endif
    739 
    740 	eloop->signals = signals;
    741 	eloop->nsignals = nsignals;
    742 	eloop->signal_cb = signal_cb;
    743 	eloop->signal_cb_ctx = signal_cb_ctx;
    744 
    745 #ifdef USE_KQUEUE
    746 	if (eloop_signal_kqueue(eloop, signals, nsignals) == -1)
    747 		return -1;
    748 #endif
    749 
    750 	return 0;
    751 }
    752 
    753 #ifndef USE_KQUEUE
    754 static volatile int eloop_sig[ELOOP_NSIGNALS];
    755 static volatile size_t eloop_nsig;
    756 
    757 static void
    758 eloop_signal3(int sig, siginfo_t *siginfo, void *arg)
    759 {
    760 	(void)(siginfo);
    761 	(void)(arg);
    762 
    763 	if (eloop_nsig == sizeof(eloop_sig) / sizeof(eloop_sig[0])) {
    764 #ifdef ELOOP_DEBUG
    765 		fprintf(stderr, "%s: signal storm, discarding signal %d\n",
    766 		    __func__, sig);
    767 #endif
    768 		return;
    769 	}
    770 	eloop_sig[eloop_nsig++] = sig;
    771 }
    772 #endif
    773 
    774 int
    775 eloop_signal_mask(struct eloop *eloop)
    776 {
    777 	sigset_t newset;
    778 	size_t i;
    779 #ifndef USE_KQUEUE
    780 	struct sigaction sa = {
    781 		.sa_sigaction = eloop_signal3,
    782 		.sa_flags = SA_SIGINFO,
    783 	};
    784 #endif
    785 
    786 	sigemptyset(&newset);
    787 	for (i = 0; i < eloop->nsignals; i++)
    788 		sigaddset(&newset, eloop->signals[i]);
    789 	if (sigprocmask(SIG_SETMASK, &newset, &eloop->sigset) == -1)
    790 		return -1;
    791 
    792 #ifndef USE_KQUEUE
    793 	sigemptyset(&sa.sa_mask);
    794 
    795 	for (i = 0; i < eloop->nsignals; i++) {
    796 		if (sigaction(eloop->signals[i], &sa, NULL) == -1)
    797 			return -1;
    798 	}
    799 #endif
    800 
    801 	return 0;
    802 }
    803 
    804 struct eloop *
    805 eloop_new(void)
    806 {
    807 	struct eloop *eloop;
    808 
    809 	eloop = calloc(1, sizeof(*eloop));
    810 	if (eloop == NULL)
    811 		return NULL;
    812 
    813 	/* Check we have a working monotonic clock. */
    814 	if (clock_gettime(CLOCK_MONOTONIC, &eloop->now) == -1) {
    815 		free(eloop);
    816 		return NULL;
    817 	}
    818 
    819 	TAILQ_INIT(&eloop->events);
    820 	TAILQ_INIT(&eloop->free_events);
    821 	TAILQ_INIT(&eloop->timeouts);
    822 	TAILQ_INIT(&eloop->free_timeouts);
    823 	eloop->exitcode = EXIT_FAILURE;
    824 
    825 #if defined(USE_KQUEUE) || defined(USE_EPOLL)
    826 	if (eloop_open(eloop) == -1 || eloop_grow_events(eloop) == -1) {
    827 		eloop_free(eloop);
    828 		return NULL;
    829 	}
    830 #endif
    831 
    832 	return eloop;
    833 }
    834 
    835 void
    836 eloop_free(struct eloop *eloop)
    837 {
    838 	if (eloop == NULL)
    839 		return;
    840 
    841 	eloop_clear(eloop, 0);
    842 #if defined(USE_KQUEUE) || defined(USE_EPOLL)
    843 	if (eloop->fd != -1)
    844 		close(eloop->fd);
    845 #endif
    846 	free(eloop->fds);
    847 	free(eloop);
    848 }
    849 
    850 static unsigned short
    851 eloop_pollevents(struct pollfd *pfd)
    852 {
    853 	unsigned short events = 0;
    854 
    855 	if (pfd->revents & POLLIN)
    856 		events |= ELE_READ;
    857 	if (pfd->revents & POLLOUT)
    858 		events |= ELE_WRITE;
    859 	if (pfd->revents & POLLHUP)
    860 		events |= ELE_HANGUP;
    861 	if (pfd->revents & POLLERR)
    862 		events |= ELE_ERROR;
    863 	if (pfd->revents & POLLNVAL)
    864 		events |= ELE_NVAL;
    865 	return events;
    866 }
    867 
    868 int
    869 eloop_waitfd(int fd)
    870 {
    871 	struct pollfd pfd = { .fd = fd, .events = POLLIN };
    872 	int err;
    873 
    874 	err = ppoll(&pfd, 1, NULL, NULL);
    875 	if (err == -1 || err == 0)
    876 		return err;
    877 
    878 	return (int)eloop_pollevents(&pfd);
    879 }
    880 
    881 #if defined(USE_KQUEUE)
    882 
    883 static int
    884 eloop_run_kqueue(struct eloop *eloop, const struct timespec *ts)
    885 {
    886 	int n, nn;
    887 	struct kevent *ke;
    888 	struct eloop_event *e;
    889 	unsigned short events;
    890 
    891 	n = kevent(eloop->fd, NULL, 0, eloop->fds, (KEVENT_N)eloop->nfds, ts);
    892 	if (n == -1)
    893 		return -1;
    894 
    895 	for (nn = n, ke = eloop->fds; nn != 0; nn--, ke++) {
    896 		if (eloop->exitnow || eloop->events_invalid)
    897 			break;
    898 		if (ke->filter == EVFILT_SIGNAL) {
    899 			if (eloop->signal_cb != NULL)
    900 				eloop->signal_cb((int)ke->ident,
    901 				    eloop->signal_cb_ctx);
    902 			continue;
    903 		}
    904 		if (ke->filter == EVFILT_READ)
    905 			events = ELE_READ;
    906 		else if (ke->filter == EVFILT_WRITE)
    907 			events = ELE_WRITE;
    908 #ifdef EVFILT_PROCDESC
    909 		else if (ke->filter == EVFILT_PROCDESC &&
    910 		    ke->fflags & NOTE_EXIT)
    911 			/* exit status is in ke->data
    912 			 * should we do anything with it? */
    913 			events = ELE_HANGUP;
    914 #endif
    915 		else
    916 			continue; /* assert? */
    917 		if (ke->flags & EV_EOF)
    918 			events |= ELE_HANGUP;
    919 		if (ke->flags & EV_ERROR)
    920 			events |= ELE_ERROR;
    921 		e = (struct eloop_event *)ke->udata;
    922 		e->cb(e->cb_arg, events);
    923 	}
    924 
    925 	if ((size_t)n == eloop->nfds)
    926 		eloop_grow_events(eloop);
    927 	return n;
    928 }
    929 
    930 #elif defined(USE_EPOLL)
    931 
    932 static int
    933 eloop_run_epoll(struct eloop *eloop, const struct timespec *ts)
    934 {
    935 	int n, nn;
    936 	struct epoll_event *epe;
    937 	struct eloop_event *e;
    938 	unsigned short events;
    939 
    940 	/* epoll does not work with zero events */
    941 	if (eloop->nfds == 0)
    942 		n = ppoll(NULL, 0, ts, &eloop->sigset);
    943 	else {
    944 		int timeout;
    945 
    946 		if (ts != NULL) {
    947 			if (ts->tv_sec > INT_MAX / MSEC_PER_SEC ||
    948 			    (ts->tv_sec == INT_MAX / MSEC_PER_SEC &&
    949 				((ts->tv_nsec + (NSEC_PER_MSEC - 1)) /
    950 					NSEC_PER_MSEC >
    951 				    INT_MAX % NSEC_PER_MSEC)))
    952 				timeout = INT_MAX;
    953 			else
    954 				timeout = (int)(ts->tv_sec * MSEC_PER_SEC +
    955 				    (ts->tv_nsec + (NSEC_PER_MSEC - 1)) /
    956 					NSEC_PER_MSEC);
    957 		} else
    958 			timeout = -1;
    959 
    960 		n = epoll_pwait(eloop->fd, eloop->fds, (int)eloop->nfds,
    961 		    timeout, &eloop->sigset);
    962 	}
    963 	if (n == -1)
    964 		return -1;
    965 
    966 	for (nn = n, epe = eloop->fds; nn != 0; nn--, epe++) {
    967 		if (eloop->exitnow || eloop->events_invalid)
    968 			break;
    969 		e = (struct eloop_event *)epe->data.ptr;
    970 		if (e->fd == -1)
    971 			continue;
    972 		events = 0;
    973 		if (epe->events & EPOLLIN)
    974 			events |= ELE_READ;
    975 		if (epe->events & EPOLLOUT)
    976 			events |= ELE_WRITE;
    977 		if (epe->events & EPOLLHUP)
    978 			events |= ELE_HANGUP;
    979 		if (epe->events & EPOLLERR)
    980 			events |= ELE_ERROR;
    981 		e->cb(e->cb_arg, events);
    982 	}
    983 
    984 	if ((size_t)n == eloop->nfds)
    985 		eloop_grow_events(eloop);
    986 	return n;
    987 }
    988 
    989 #elif defined(USE_PPOLL)
    990 
    991 static int
    992 eloop_run_ppoll(struct eloop *eloop, const struct timespec *ts)
    993 {
    994 	int n, nn;
    995 	struct eloop_event *e;
    996 	struct pollfd *pfd;
    997 	unsigned short events;
    998 
    999 	n = ppoll(eloop->fds, (nfds_t)eloop->nevents, ts, &eloop->sigset);
   1000 	if (n == -1 || n == 0)
   1001 		return n;
   1002 
   1003 	nn = n;
   1004 	TAILQ_FOREACH(e, &eloop->events, next) {
   1005 		if (eloop->exitnow || eloop->events_invalid)
   1006 			break;
   1007 		/* Skip freshly added events */
   1008 		if ((pfd = e->pollfd) == NULL)
   1009 			continue;
   1010 		if (e->pollfd->revents) {
   1011 			nn--;
   1012 			events = eloop_pollevents(pfd);
   1013 			if (events)
   1014 				e->cb(e->cb_arg, events);
   1015 		}
   1016 		if (nn == 0)
   1017 			break;
   1018 	}
   1019 	return n;
   1020 }
   1021 
   1022 #endif
   1023 
   1024 int
   1025 eloop_start(struct eloop *eloop)
   1026 {
   1027 	int error;
   1028 	struct eloop_timeout *t;
   1029 	struct timespec ts, *tsp;
   1030 
   1031 	eloop->exitnow = false;
   1032 
   1033 	for (;;) {
   1034 		if (eloop->exitnow)
   1035 			break;
   1036 		if (eloop->events_invalid) {
   1037 			eloop->events_invalid = false;
   1038 			eloop->events_need_setup = true;
   1039 		}
   1040 
   1041 #ifndef USE_KQUEUE
   1042 		if (eloop_nsig != 0) {
   1043 			int sig = eloop_sig[--eloop_nsig];
   1044 
   1045 			if (eloop->signal_cb != NULL)
   1046 				eloop->signal_cb(sig, eloop->signal_cb_ctx);
   1047 			continue;
   1048 		}
   1049 #endif
   1050 
   1051 		t = TAILQ_FIRST(&eloop->timeouts);
   1052 		if (t == NULL && eloop->nevents == 0)
   1053 			break;
   1054 
   1055 		if (t != NULL)
   1056 			eloop_reduce_timers(eloop);
   1057 
   1058 		if (t != NULL && t->seconds == 0 && t->nseconds == 0) {
   1059 			TAILQ_REMOVE(&eloop->timeouts, t, next);
   1060 			t->callback(t->arg);
   1061 			TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
   1062 			continue;
   1063 		}
   1064 
   1065 		if (t != NULL) {
   1066 			if (t->seconds > INT_MAX) {
   1067 				ts.tv_sec = (time_t)INT_MAX;
   1068 				ts.tv_nsec = 0;
   1069 			} else {
   1070 				ts.tv_sec = (time_t)t->seconds;
   1071 				ts.tv_nsec = (long)t->nseconds;
   1072 			}
   1073 			tsp = &ts;
   1074 		} else
   1075 			tsp = NULL;
   1076 
   1077 		if (eloop->events_need_setup)
   1078 			eloop_event_setup_fds(eloop);
   1079 
   1080 #if defined(USE_KQUEUE)
   1081 		error = eloop_run_kqueue(eloop, tsp);
   1082 #elif defined(USE_EPOLL)
   1083 		error = eloop_run_epoll(eloop, tsp);
   1084 #elif defined(USE_PPOLL)
   1085 		error = eloop_run_ppoll(eloop, tsp);
   1086 #endif
   1087 		if (error == -1) {
   1088 			if (errno == EINTR)
   1089 				continue;
   1090 			return -errno;
   1091 		}
   1092 	}
   1093 
   1094 	return eloop->exitcode;
   1095 }
   1096