112 lines
2.4 KiB
C
112 lines
2.4 KiB
C
|
|
/* Unix serial I/O class poll() emulation. */
|
|
|
|
/*
|
|
* Argyll Color Management System
|
|
*
|
|
* Author: Graeme W. Gill
|
|
* Date: 12/9/2004
|
|
*
|
|
* Copyright 2004, 2010 Graeme W. Gill
|
|
* All rights reserved.
|
|
*
|
|
* This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
|
|
* see the License2.txt file for licencing details.
|
|
*/
|
|
|
|
#ifdef UNIX
|
|
|
|
/* Fake up poll() support on systems that only support select() */
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <errno.h>
|
|
#include <memory.h>
|
|
|
|
/* select() defined, but not poll(), so emulate poll() */
|
|
#if defined(FD_CLR) && !defined(POLLIN)
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include "pollem.h"
|
|
|
|
int pollem(struct pollfd *fds, unsigned long nfds, int timeout) {
|
|
int i, nfd;
|
|
fd_set rd_ary; /* Select array for read file descriptors */
|
|
fd_set wr_ary; /* Select array for write file descriptors */
|
|
fd_set ex_ary; /* Select array for exception file descriptors */
|
|
struct timeval tv; /* Timeout value */
|
|
struct timeval *ptv = &tv; /* Pointer to above */
|
|
int result; /* Select return value */
|
|
|
|
/* Translate files and events */
|
|
FD_ZERO(&rd_ary);
|
|
FD_ZERO(&wr_ary);
|
|
FD_ZERO(&ex_ary);
|
|
|
|
for (i = nfd = 0; i < nfds; i++) {
|
|
fds[i].revents = 0;
|
|
|
|
if (fds[i].events & POLLIN) {
|
|
FD_SET(fds[i].fd, &rd_ary);
|
|
if (fds[i].fd > nfd)
|
|
nfd = fds[i].fd;
|
|
}
|
|
|
|
if (fds[i].events & POLLPRI) {
|
|
FD_SET(fds[i].fd, &ex_ary);
|
|
if (fds[i].fd > nfd)
|
|
nfd = fds[i].fd;
|
|
}
|
|
|
|
if (fds[i].events & POLLOUT) {
|
|
FD_SET(fds[i].fd, &wr_ary);
|
|
if (fds[i].fd > nfd)
|
|
nfd = fds[i].fd;
|
|
}
|
|
}
|
|
nfd++; /* Maximum file desciptor index + 1 */
|
|
|
|
/* Translate timeout */
|
|
if (timeout == -1) {
|
|
ptv = NULL; /* Wait forever */
|
|
|
|
} else if (timeout == 0) {
|
|
tv.tv_sec = 0; /* Return imediately */
|
|
tv.tv_usec = 0;
|
|
|
|
} else { /* Convert milliseconds to seconds and useconds */
|
|
tv.tv_sec = timeout / 1000;
|
|
tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
|
|
}
|
|
|
|
/* Do the select */
|
|
if ((result = select(nfd, &rd_ary, &wr_ary, &ex_ary, ptv)) > 0) {
|
|
|
|
for (i = 0; i < nfds; i++) {
|
|
fds[i].revents = 0;
|
|
|
|
if (FD_ISSET(fds[i].fd, &ex_ary))
|
|
fds[i].revents |= POLLPRI;
|
|
|
|
if (FD_ISSET(fds[i].fd, &rd_ary))
|
|
fds[i].revents |= POLLIN;
|
|
|
|
if (FD_ISSET(fds[i].fd, &wr_ary))
|
|
fds[i].revents |= POLLOUT;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endif /* FD_CLR */
|
|
|
|
#endif /* UNIX */
|