Files
Arquivotheca.SunOS-4.1.4/usr.lib/libcurses/screen/select.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

103 lines
2.5 KiB
C

#ifndef lint
static char sccsid[] = "@(#)select.c 1.1 94/10/31 SMI"; /* from S5R2 1.1 */
#endif
/*
* Code for various kinds of delays. Most of this is nonportable and
* requires various enhancements to the operating system, so it won't
* work on all systems. It is included in curses to provide a portable
* interface, and so curses itself can use it for function keys.
*/
#include "curses.ext"
#include <signal.h>
#define NAPINTERVAL 100
/* From early specs - this may change by 4.2BSD */
struct _timeval {
long tv_sec;
long tv_usec;
};
#ifdef FIONREAD
# ifndef TIOCREMOTE
/*
* Decide if we can emulate select but don't have it. This is
* intended to be true only on 4.1BSD, not 4.2BSD or USG.
*/
# define NEEDSELECT
# endif
#endif
#ifdef NEEDSELECT
/*
* Emulation of 4.2BSD select system call. This is somewhat crude but
* better than nothing. We do FIONREAD on each fd, and if we have to
* wait we use nap to avoid a busy wait. The resolution of the nap
* will hurt response - so will the fact that we ignore the write fds.
* If we are simulating nap with a 1 second sleep, this will be very poor.
*
* nfds is the number of fds to check - this is usually 20.
* prfds is a pointer to a bit vector of file descriptors - in the case
* where nfds < 32, prfds points to an integer, where bit 1<<fd
* is 1 if we are supposed to check file descriptor fd.
* pwfds is like prfds but for write checks instead of read checks.
* ms is the max number of milliseconds to wait before returning failure.
* The value returned is the number of file descriptors ready for input.
* The bit vectors are updated in place.
*/
int
select(nfds, prfds, pwfds, pefds, timeout)
register int nfds;
int *prfds, *pwfds, *pefds;
struct _timeval *timeout;
{
register int fd;
register int rfds = *prfds;
register int n;
int nwaiting, rv = 0;
long ms = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
for (;;) {
/* check the fds */
for (fd=0; fd<nfds; fd++)
if (1<<fd & rfds) {
ioctl(fd, FIONREAD, &nwaiting);
if (nwaiting > 0) {
rv++;
} else
*prfds &= ~(1<<fd);
}
if (rv)
return rv;
/* Nothing ready. Should we give up? */
if (ms <= 0)
return 0;
*prfds = rfds; /* we clobbered it, so restore. */
/* Wait a bit */
n = NAPINTERVAL;
if (ms < NAPINTERVAL)
n = ms;
ms -= n;
napms(n);
}
}
#else
#ifndef FIONREAD
int
select(nfds, prfds, pwfds, pefds, ms)
register int nfds;
int *prfds, *pwfds, *pefds;
struct _timeval *ms;
{
/* Can't do it, but at least compile right */
return ERR;
}
#endif FIONREAD
#endif NEEDSELECT