From 77dc79afe5fd909fb1fe0a3cc668db2763b82fb8 Mon Sep 17 00:00:00 2001 From: rubin Date: Fri, 22 May 2026 13:42:51 +0200 Subject: import repository Signed-off-by: rubinowy blask --- fdwatcher.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 fdwatcher.c (limited to 'fdwatcher.c') diff --git a/fdwatcher.c b/fdwatcher.c new file mode 100644 index 0000000..8e0cb97 --- /dev/null +++ b/fdwatcher.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include + +#include + +int +fdwatcher_initialise(struct FDWatchHandle *handle, int maxWatchedFds) +{ + size_t pollfdSize = maxWatchedFds * sizeof(handle->watchedFds); + size_t pointersSize = maxWatchedFds * sizeof(void *); + + handle->watchedFds = malloc(pollfdSize); + if (errno != 0) { + perror("fdwatcher_initialise: malloc(3)"); + return -errno; + } + + handle->arbitraryData = malloc(pointersSize); + if (errno != 0) { + perror("fdwatcher_initialise: malloc(3)"); + return -errno; + } + + memset(handle->watchedFds, 0, pollfdSize); + handle->maxWatchedFds = maxWatchedFds; + return 0; +} + +int +fdwatcher_add(struct FDWatchHandle *handle, int fd, void *arbitrary) +{ + struct pollfd *watchedFd = NULL; + + if (handle->maxWatchedFds == handle->watchedFdCount) { + printf("meow\n"); + return -EMFILE; + } + + handle->arbitraryData[handle->watchedFdCount] = arbitrary; + watchedFd = &(handle->watchedFds[handle->watchedFdCount]); + watchedFd->events = POLLIN | POLLHUP | POLLRDHUP; + watchedFd->revents = 0; + watchedFd->fd = fd; + + handle->watchedFdCount = handle->watchedFdCount + 1; + return 0; +} + +static int +_fdwatcher_handleEvents_revents(struct pollfd *pollie, struct FDWatchHandle *handle, + int (*meow)(struct FDWatchHandle *, enum FDWatch_EventType, int, void *), + size_t elementNumber) +{ + int ret = 0; + + if (pollie->revents & POLLHUP || pollie->revents & POLLRDHUP) { + ret = meow(handle, FDWATCH_EVENT_HUP, pollie->fd, handle->arbitraryData[elementNumber]); + if (ret == 0) { + return 1; + } + } + + if (pollie->revents & POLLIN) { + meow(handle, FDWATCH_EVENT_INP, pollie->fd, handle->arbitraryData[elementNumber]); + } + return 0; +} + +static int +_fdwatcher_handleEvents(struct FDWatchHandle *handle, int (*meow)(struct FDWatchHandle *handle, enum FDWatch_EventType, int, void *)) +{ + size_t i = 0; + int ret = 0; + + while (1) { + if (i == handle->watchedFdCount) break; + + struct pollfd *watchedFdEntry = NULL; + watchedFdEntry = &handle->watchedFds[i]; + + if (watchedFdEntry->revents != 0) { + ret = _fdwatcher_handleEvents_revents(watchedFdEntry, handle, meow, i); + watchedFdEntry->revents = 0; + + if (ret != 0) { + return 1; + } + } + i++; + } + + return 0; +} + +int +fdwatcher_watch(struct FDWatchHandle *handle, int (*meow)(struct FDWatchHandle *handle, enum FDWatch_EventType, int, void *)) +{ + int ret = 0; + + while (1) { + ret = poll(handle->watchedFds, handle->watchedFdCount, INT_MAX); + if (errno != 0) { + ret = meow(handle, FDWATCH_EVENT_ERR, 0, NULL); + + if (ret == 1) break; + errno = 0; + continue; + } + + ret = _fdwatcher_handleEvents(handle, meow); + if (ret == 1) { + return 1; + } + } + + return 0; +} + +/* TODO */ +int +fdwatcher_remove(struct FDWatchHandle *handle, int fd) +{ + abort(); +} -- cgit 1.4.1