diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2000-08-11 20:34:24 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2000-08-11 20:34:24 +0000 |
commit | 427b6d036e1351981b66950f10c8cfee69112e84 (patch) | |
tree | 5b4c218633c9c36b11aad661a78f9653c5731ecf /winsup/cygwin/poll.cc | |
parent | bbda7ca0787c3c03e64d29d39aa288051aff6676 (diff) | |
download | newlib-427b6d036e1351981b66950f10c8cfee69112e84.zip newlib-427b6d036e1351981b66950f10c8cfee69112e84.tar.gz newlib-427b6d036e1351981b66950f10c8cfee69112e84.tar.bz2 |
* poll.cc: Allow any descriptor and any number of descriptors.
Allocate fd_set struct sdynamically.
Diffstat (limited to 'winsup/cygwin/poll.cc')
-rw-r--r-- | winsup/cygwin/poll.cc | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc index 2e28516..b0a5ebd 100644 --- a/winsup/cygwin/poll.cc +++ b/winsup/cygwin/poll.cc @@ -8,44 +8,58 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#include "winsup.h" #include <sys/poll.h> +#include <errno.h> +#include "winsup.h" extern "C" int poll (struct pollfd *fds, unsigned int nfds, int timeout) { int max_fd = 0; - fd_set open_fds, read_fds, write_fds, except_fds; + fd_set *open_fds, *read_fds, *write_fds, *except_fds; struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 }; - FD_ZERO (&open_fds); - FD_ZERO (&read_fds); - FD_ZERO (&write_fds); - FD_ZERO (&except_fds); + for (unsigned int i = 0; i < nfds; ++i) + if (fds[i].fd > max_fd) + max_fd = fds[i].fd; + + size_t fds_size = howmany(max_fd + 1, NFDBITS) * sizeof (fd_mask); + + open_fds = (fd_set *) alloca (fds_size); + read_fds = (fd_set *) alloca (fds_size); + write_fds = (fd_set *) alloca (fds_size); + except_fds = (fd_set *) alloca (fds_size); + + if (!open_fds || !read_fds || !write_fds || !except_fds) + { + set_errno (ENOMEM); + return -1; + } + + memset (open_fds, 0, fds_size); + memset (read_fds, 0, fds_size); + memset (write_fds, 0, fds_size); + memset (except_fds, 0, fds_size); for (unsigned int i = 0; i < nfds; ++i) - if (fds[i].fd < FD_SETSIZE - && !dtable.not_open (fds[i].fd)) + if (!dtable.not_open (fds[i].fd)) { - FD_SET (fds[i].fd, &open_fds); + FD_SET (fds[i].fd, open_fds); if (fds[i].events & POLLIN) - FD_SET (fds[i].fd, &read_fds); + FD_SET (fds[i].fd, read_fds); if (fds[i].events & POLLOUT) - FD_SET (fds[i].fd, &write_fds); + FD_SET (fds[i].fd, write_fds); if (fds[i].events & POLLPRI) - FD_SET (fds[i].fd, &except_fds); - if (fds[i].fd > max_fd) - max_fd = fds[i].fd; + FD_SET (fds[i].fd, except_fds); } - int ret = cygwin_select (max_fd + 1, &read_fds, &write_fds, &except_fds, + int ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds, timeout < 0 ? NULL : &tv); for (unsigned int i = 0; i < nfds; ++i) { - if (fds[i].fd >= FD_SETSIZE - || !FD_ISSET (fds[i].fd, &open_fds)) + if (!FD_ISSET (fds[i].fd, open_fds)) fds[i].revents = POLLNVAL; else if (dtable.not_open(fds[i].fd)) fds[i].revents = POLLHUP; @@ -54,11 +68,11 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) else { fds[i].revents = 0; - if (FD_ISSET (fds[i].fd, &read_fds)) + if (FD_ISSET (fds[i].fd, read_fds)) fds[i].revents |= POLLIN; - if (FD_ISSET (fds[i].fd, &write_fds)) + if (FD_ISSET (fds[i].fd, write_fds)) fds[i].revents |= POLLOUT; - if (FD_ISSET (fds[i].fd, &except_fds)) + if (FD_ISSET (fds[i].fd, except_fds)) fds[i].revents |= POLLPRI; } } |