]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/poll.cc
Remove unneeded header files from source files throughout.
[newlib-cygwin.git] / winsup / cygwin / poll.cc
CommitLineData
afb7e719
CV
1/* poll.cc. Implements poll(2) via usage of select(2) call.
2
d1f36688 3 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
afb7e719
CV
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
03b65245
CV
11#define __INSIDE_CYGWIN_NET__
12
42a737d0 13#define FD_SETSIZE 16384 // lots of fds
b2007749 14#include "winsup.h"
4c8d72de 15#include <sys/poll.h>
7382e593 16#include <sys/socket.h>
e2b3dc25 17#include <stdlib.h>
03b65245 18#define USE_SYS_TYPES_FD_SET
169c465a 19#include "cygerrno.h"
6b91b8d5 20#include "security.h"
47063f00 21#include "path.h"
7ac61736 22#include "fhandler.h"
e2ebe117 23#include "dtable.h"
df63bd49 24#include "cygheap.h"
afb7e719 25
c367dfd0 26extern "C" int
b23bc8c3 27poll (struct pollfd *fds, nfds_t nfds, int timeout)
afb7e719
CV
28{
29 int max_fd = 0;
6ea9c716 30 fd_set *read_fds, *write_fds, *except_fds;
afb7e719
CV
31 struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };
32
427b6d03
CV
33 for (unsigned int i = 0; i < nfds; ++i)
34 if (fds[i].fd > max_fd)
35 max_fd = fds[i].fd;
36
c90e1cf1 37 size_t fds_size = howmany (max_fd + 1, NFDBITS) * sizeof (fd_mask);
427b6d03 38
427b6d03
CV
39 read_fds = (fd_set *) alloca (fds_size);
40 write_fds = (fd_set *) alloca (fds_size);
41 except_fds = (fd_set *) alloca (fds_size);
42
6ea9c716 43 if (!read_fds || !write_fds || !except_fds)
427b6d03 44 {
04843bf4 45 set_errno (EINVAL); /* According to SUSv3. */
427b6d03
CV
46 return -1;
47 }
48
427b6d03
CV
49 memset (read_fds, 0, fds_size);
50 memset (write_fds, 0, fds_size);
51 memset (except_fds, 0, fds_size);
afb7e719 52
2402700d
CF
53 int invalid_fds = 0;
54 for (unsigned int i = 0; i < nfds; ++i)
55 {
56 fds[i].revents = 0;
c90e1cf1 57 if (!cygheap->fdtab.not_open (fds[i].fd))
2402700d
CF
58 {
59 if (fds[i].events & POLLIN)
60 FD_SET(fds[i].fd, read_fds);
61 if (fds[i].events & POLLOUT)
62 FD_SET(fds[i].fd, write_fds);
fd5879c1 63 if (fds[i].events & POLLPRI)
2402700d
CF
64 FD_SET(fds[i].fd, except_fds);
65 }
66 else if (fds[i].fd >= 0)
67 {
68 ++invalid_fds;
69 fds[i].revents = POLLNVAL;
70 }
71 }
afb7e719 72
2402700d
CF
73 if (invalid_fds)
74 return invalid_fds;
99dbafac 75
d1f36688
CV
76 int ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds,
77 timeout < 0 ? NULL : &tv);
78 if (ret <= 0)
79 return ret;
80
81 /* Set revents fields and count fds with non-zero revents fields for
82 return value. */
83 ret = 0;
84 for (unsigned int i = 0; i < nfds; ++i)
85 {
86 if (fds[i].fd >= 0)
87 {
88 if (cygheap->fdtab.not_open (fds[i].fd))
89 fds[i].revents = POLLHUP;
90 else
91 {
92 fhandler_socket *sock;
93
94 if (FD_ISSET(fds[i].fd, read_fds))
95 /* This should be sufficient for sockets, too. Using
96 MSG_PEEK, as before, can be considered dangerous at
97 best. Quote from W. Richard Stevens: "The presence
98 of an error can be considered either normal data or
99 an error (POLLERR). In either case, a subsequent read
100 will return -1 with errno set to the appropriate value."
101 So it looks like there's actually no good reason to
102 return POLLERR. */
103 fds[i].revents |= POLLIN;
104 /* Handle failed connect. */
105 if (FD_ISSET(fds[i].fd, write_fds)
106 && (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
107 && sock->connect_state () == connect_failed)
108 fds[i].revents |= (POLLIN | POLLERR);
109 else
110 {
111 if (FD_ISSET(fds[i].fd, write_fds))
112 fds[i].revents |= POLLOUT;
113 if (FD_ISSET(fds[i].fd, except_fds))
114 fds[i].revents |= POLLPRI;
115 }
116 }
117 if (fds[i].revents)
118 ++ret;
119 }
120 }
afb7e719 121
2402700d
CF
122 return ret;
123}
This page took 0.293923 seconds and 5 git commands to generate.