|
|
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.