iopause_select.c (1695B)
1 /* ISC license. */ 2 3 #include <skalibs/bsdsnowflake.h> 4 5 #include <string.h> /* Solaris... */ 6 #include <errno.h> 7 #include <sys/time.h> /* MacOS... */ 8 #include <sys/select.h> 9 10 #include <skalibs/tai.h> 11 #include <skalibs/iopause.h> 12 13 int iopause_select (iopause_fd *x, unsigned int len, tain const *deadline, tain const *stamp) 14 { 15 struct timeval tv = { .tv_sec = 0, .tv_usec = 0 } ; 16 int nfds = 0 ; 17 fd_set rfds, wfds, xfds ; 18 int r ; 19 20 FD_ZERO(&rfds) ; 21 FD_ZERO(&wfds) ; 22 FD_ZERO(&xfds) ; 23 if (deadline && tain_less(stamp, deadline)) 24 { 25 tain delta ; 26 tain_sub(&delta, deadline, stamp) ; 27 if (!timeval_from_tain_relative(&tv, &delta)) 28 { 29 if (errno != EOVERFLOW) return -1 ; 30 else deadline = 0 ; 31 } 32 } 33 34 { 35 unsigned int i = 0 ; 36 for (; i < len ; i++) 37 { 38 x[i].revents = 0 ; 39 if (x[i].fd >= 0) 40 { 41 if (x[i].fd >= FD_SETSIZE) return (errno = EMFILE, -1) ; 42 if (x[i].fd >= nfds) nfds = x[i].fd + 1 ; 43 if (x[i].events & IOPAUSE_READ) FD_SET(x[i].fd, &rfds) ; 44 if (x[i].events & IOPAUSE_WRITE) FD_SET(x[i].fd, &wfds) ; 45 if (x[i].events & IOPAUSE_EXCEPT) FD_SET(x[i].fd, &xfds) ; 46 } 47 } 48 } 49 50 r = select(nfds, &rfds, &wfds, &xfds, deadline ? &tv : 0) ; 51 52 if (r > 0) 53 { 54 unsigned int i = 0 ; 55 for (; i < len ; i++) if (x[i].fd >= 0) 56 { 57 if ((x[i].events & IOPAUSE_READ) && FD_ISSET(x[i].fd, &rfds)) 58 x[i].revents |= IOPAUSE_READ ; 59 if ((x[i].events & IOPAUSE_WRITE) && FD_ISSET(x[i].fd, &wfds)) 60 x[i].revents |= IOPAUSE_WRITE ; 61 if ((x[i].events & IOPAUSE_EXCEPT) && FD_ISSET(x[i].fd, &xfds)) 62 x[i].revents |= IOPAUSE_EXCEPT ; 63 } 64 } 65 66 return r ; 67 }