|
|
1.1 ! root 1: /* ! 2: * Code for various kinds of delays. Most of this is nonportable and ! 3: * requires various enhancements to the operating system, so it won't ! 4: * work on all systems. It is included in curses to provide a portable ! 5: * interface, and so curses itself can use it for function keys. ! 6: */ ! 7: ! 8: /* @(#) select.c: 1.1 10/15/83 (1.10 3/6/83) */ ! 9: ! 10: #include "curses.ext" ! 11: #include <signal.h> ! 12: ! 13: #define NAPINTERVAL 100 ! 14: ! 15: /* From early specs - this may change by 4.2BSD */ ! 16: struct _timeval { ! 17: long tv_sec; ! 18: long tv_usec; ! 19: }; ! 20: ! 21: #ifdef FIONREAD ! 22: # ifndef TIOCREMOTE ! 23: /* ! 24: * Decide if we can emulate select but don't have it. This is ! 25: * intended to be true only on 4.1BSD, not 4.2BSD or USG. ! 26: */ ! 27: # define NEEDSELECT ! 28: # endif ! 29: #endif ! 30: ! 31: #ifdef NEEDSELECT ! 32: /* ! 33: * Emulation of 4.2BSD select system call. This is somewhat crude but ! 34: * better than nothing. We do FIONREAD on each fd, and if we have to ! 35: * wait we use nap to avoid a busy wait. The resolution of the nap ! 36: * will hurt response - so will the fact that we ignore the write fds. ! 37: * If we are simulating nap with a 1 second sleep, this will be very poor. ! 38: * ! 39: * nfds is the number of fds to check - this is usually 20. ! 40: * prfds is a pointer to a bit vector of file descriptors - in the case ! 41: * where nfds < 32, prfds points to an integer, where bit 1<<fd ! 42: * is 1 if we are supposed to check file descriptor fd. ! 43: * pwfds is like prfds but for write checks instead of read checks. ! 44: * ms is the max number of milliseconds to wait before returning failure. ! 45: * The value returned is the number of file descriptors ready for input. ! 46: * The bit vectors are updated in place. ! 47: */ ! 48: ! 49: int ! 50: select(nfds, prfds, pwfds, pefds, timeout) ! 51: register int nfds; ! 52: int *prfds, *pwfds, *pefds; ! 53: struct _timeval *timeout; ! 54: { ! 55: register int fd; ! 56: register int rfds = *prfds; ! 57: register int n; ! 58: int nwaiting, rv = 0; ! 59: long ms = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; ! 60: ! 61: for (;;) { ! 62: /* check the fds */ ! 63: for (fd=0; fd<nfds; fd++) ! 64: if (1<<fd & rfds) { ! 65: ioctl(fd, FIONREAD, &nwaiting); ! 66: if (nwaiting > 0) { ! 67: rv++; ! 68: } else ! 69: *prfds &= ~(1<<fd); ! 70: } ! 71: if (rv) ! 72: return rv; ! 73: ! 74: /* Nothing ready. Should we give up? */ ! 75: if (ms <= 0) ! 76: return 0; ! 77: ! 78: *prfds = rfds; /* we clobbered it, so restore. */ ! 79: ! 80: /* Wait a bit */ ! 81: n = NAPINTERVAL; ! 82: if (ms < NAPINTERVAL) ! 83: n = ms; ! 84: ms -= n; ! 85: napms(n); ! 86: } ! 87: } ! 88: #else ! 89: #ifndef FIONREAD ! 90: int ! 91: select(nfds, prfds, pwfds, pefds, ms) ! 92: register int nfds; ! 93: int *prfds, *pwfds, *pefds; ! 94: struct _timeval *ms; ! 95: { ! 96: /* Can't do it, but at least compile right */ ! 97: return ERR; ! 98: } ! 99: #endif FIONREAD ! 100: #endif NEEDSELECT
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.