skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

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 }