/* * File: xcompat.c * Last modified on Sat Jul 23 14:49:36 1994 by eroberts * ----------------------------------------------------- * This implementation and the corresponding interface simulate the * operation of any BSD4.2 calls that are required by the graphics * package but that are not defined in the local system. See the * interface for details. Note that this file generates no code * unless one of the conditions is set. */ #ifdef SYSV #include #include #include #include #include #include #include "xcompat.h" /* Private function prototypes */ static void SigAlarmHandler(); /* * Function: SimulateSelect * ------------------------ * This function simulates the BSD select call by mapping it onto * the poll system call implemented under System V. */ int SimulateSelect(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tvp) { struct pollfd fds[FOPEN_MAX]; int i, fd, nfds; short events; int timeout, nready; nfds = 0; if (tvp == NULL) { timeout = 0; } else { timeout = tvp->tv_sec * 1000 + (tvp->tv_sec + 500) / 1000; } for (fd = 0; fd < width; fd++) { events = 0; if (readfds && FD_ISSET(fd, readfds)) { events |= POLLIN; FD_CLR(fd, readfds); } if (writefds && FD_ISSET(fd, writefds)) { events |= POLLOUT; FD_CLR(fd, writefds); } if (exceptfds && FD_ISSET(fd, exceptfds)) { events |= POLLIN | POLLOUT; FD_CLR(fd, exceptfds); } if (events != 0) { fds[nfds].fd = fd; fds[nfds].events = events; fds[nfds].revents = 0; nfds++; } } nready = poll(fds, nfds, timeout); if (nready <= 0) return (nready); for (i = 0; i < nfds; i++) { if (fds[i].revents & (POLLIN | POLLPRI | POLLHUP)) { FD_SET(fds[i].fd, readfds); } if (fds[i].revents & POLLOUT) { FD_SET(fds[i].fd, writefds); } if (fds[i].revents & (POLLERR | POLLNVAL)) { FD_SET(fds[i].fd, exceptfds); } } return (nready); } /* * Function: SimulateUSleep * ------------------------ * This function simulates the BSD usleep call. */ int SimulateUSleep(unsigned useconds) { struct itimerval newTimer, oldTimer; newTimer.it_value.tv_sec = useconds / 1000000; newTimer.it_value.tv_usec = useconds % 1000000; newTimer.it_interval.tv_sec = 0; newTimer.it_interval.tv_usec = 0; signal(SIGALRM, SigAlarmHandler); setitimer(ITIMER_REAL, &newTimer, &oldTimer); pause(); setitimer(ITIMER_REAL, &oldTimer, NULL); } static void SigAlarmHandler() { /* The handler does nothing, but the pause call will wake up */ } #endif