home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-19.28-src.tgz / tar.out / fsf / emacs / unixlib / src / select.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  2KB  |  73 lines

  1. #include "amiga.h"
  2. #include "files.h"
  3. #include "signals.h"
  4. #include "timers.h"
  5. #include <sys/time.h>
  6.  
  7. int select(int nfds, int *rfds, int *wfds, int *efds, struct timeval *timeout)
  8. {
  9.   int fdmask, i, fdcount;
  10.   int poll = timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0;
  11.   ULONG eventmask, sigs;
  12.   int orfds = rfds ? *rfds : 0, owfds = wfds ? *wfds : 0, oefds = efds ? *efds : 0;
  13.   
  14.   for (i = 0, fdmask = 1; i < nfds; i++, fdmask <<= 1)
  15.     {
  16.       int rd = orfds & fdmask, wr = owfds & fdmask;
  17.  
  18.   chkabort();
  19.       if (rd || wr)
  20.     {
  21.       struct fileinfo *fi = _find_fd(i);
  22.  
  23.       if (!fi) return -1;
  24.       if (rd && !(fi->flags & FI_READ) || wr && !(fi->flags & FI_WRITE))
  25.         {
  26.           errno = EACCES;
  27.           return -1;
  28.         }
  29.     }
  30.     }
  31.  
  32.   if (timeout) _timer_start(_odd_timer, timeout->tv_sec, timeout->tv_usec);
  33.   else _timer_abort(_odd_timer);
  34.   fdcount = 0;
  35.   do
  36.     {
  37.       eventmask = 0;
  38.       for (i = 0, fdmask = 1; i < nfds; i++, fdmask <<= 1)
  39.     {
  40.       int rd = orfds & fdmask, wr = owfds & fdmask;
  41.  
  42.       if (rd || wr)
  43.         {
  44.           struct fileinfo *fi = _find_fd(i);
  45.  
  46.           eventmask |= fi->select_start(fi->userinfo, rd, wr);
  47.         }
  48.     }
  49.  
  50.       if (eventmask == -1 || poll) /* Don't wait */ sigs = _check_signals(0);
  51.       else /* Wait*/ sigs = _wait_signals(_odd_sig | eventmask);
  52.  
  53.       for (i = 0, fdmask = 1; i < nfds; i++, fdmask <<= 1)
  54.     {
  55.       int rd = orfds & fdmask, wr = owfds & fdmask;
  56.  
  57.       if (rd || wr)
  58.         {
  59.           struct fileinfo *fi = _find_fd(i);
  60.  
  61.           fi->select_poll(fi->userinfo, &rd, &wr);
  62.           if (!rd && rfds) *rfds &= ~fdmask;
  63.           if (!wr && wfds) *wfds &= ~fdmask;
  64.           if (rd || wr) fdcount++;
  65.         }
  66.     }
  67.       _handle_signals(sigs);
  68.     }
  69.   while (fdcount == 0 && !_timer_expired(_odd_timer) && !poll);
  70.  
  71.   return fdcount;
  72. }
  73.