watcher.c (1878B)
1 #include "watcher.h" 2 3 #include <errno.h> 4 #include <poll.h> 5 #include <stdbool.h> 6 #include <stdio.h> 7 8 #include "block.h" 9 #include "util.h" 10 11 static bool watcher_fd_is_readable(const watcher_fd* const watcher_fd) { 12 return (watcher_fd->revents & POLLIN) != 0; 13 } 14 15 int watcher_init(watcher* const watcher, const block* const blocks, 16 const unsigned short block_count, const int signal_fd) { 17 if (signal_fd == -1) { 18 (void)fprintf( 19 stderr, 20 "error: invalid signal file descriptor passed to watcher\n"); 21 return 1; 22 } 23 24 watcher_fd* const fd = &watcher->fds[SIGNAL_FD]; 25 fd->fd = signal_fd; 26 fd->events = POLLIN; 27 28 for (unsigned short i = 0; i < block_count; ++i) { 29 const int block_fd = blocks[i].pipe[READ_END]; 30 if (block_fd == -1) { 31 (void)fprintf( 32 stderr, 33 "error: invalid block file descriptors passed to watcher\n"); 34 return 1; 35 } 36 37 watcher_fd* const fd = &watcher->fds[i]; 38 fd->fd = block_fd; 39 fd->events = POLLIN; 40 } 41 42 return 0; 43 } 44 45 int watcher_poll(watcher* watcher, const int timeout_ms) { 46 int event_count = poll(watcher->fds, LEN(watcher->fds), timeout_ms); 47 48 // Don't return non-zero status for signal interruptions. 49 if (event_count == -1 && errno != EINTR) { 50 (void)fprintf(stderr, "error: watcher could not poll blocks\n"); 51 return 1; 52 } 53 54 watcher->got_signal = watcher_fd_is_readable(&watcher->fds[SIGNAL_FD]); 55 56 watcher->active_block_count = event_count - (int)watcher->got_signal; 57 unsigned short i = 0; 58 unsigned short j = 0; 59 while (i < event_count && j < LEN(watcher->active_blocks)) { 60 if (watcher_fd_is_readable(&watcher->fds[j])) { 61 watcher->active_blocks[i] = j; 62 ++i; 63 } 64 65 ++j; 66 } 67 68 return 0; 69 }