#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(); }