]>
sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/poll.cc
1 /* poll.cc. Implements poll(2) via usage of select(2) call.
3 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 #define __INSIDE_CYGWIN_NET__
14 #define FD_SETSIZE 16384 // lots of fds
18 #define USE_SYS_TYPES_FD_SET
28 poll (struct pollfd
*fds
, nfds_t nfds
, int timeout
)
32 fd_set
*read_fds
, *write_fds
, *except_fds
;
33 struct timeval tv
= { timeout
/ 1000, (timeout
% 1000) * 1000 };
35 for (unsigned int i
= 0; i
< nfds
; ++i
)
36 if (fds
[i
].fd
> max_fd
)
39 size_t fds_size
= howmany (max_fd
+ 1, NFDBITS
) * sizeof (fd_mask
);
41 read_fds
= (fd_set
*) alloca (fds_size
);
42 write_fds
= (fd_set
*) alloca (fds_size
);
43 except_fds
= (fd_set
*) alloca (fds_size
);
45 if (!read_fds
|| !write_fds
|| !except_fds
)
47 set_errno (EINVAL
); /* According to SUSv3. */
51 memset (read_fds
, 0, fds_size
);
52 memset (write_fds
, 0, fds_size
);
53 memset (except_fds
, 0, fds_size
);
55 for (unsigned int i
= 0; i
< nfds
; ++i
)
58 if (!cygheap
->fdtab
.not_open (fds
[i
].fd
))
60 if (fds
[i
].events
& POLLIN
)
61 FD_SET(fds
[i
].fd
, read_fds
);
62 if (fds
[i
].events
& POLLOUT
)
63 FD_SET(fds
[i
].fd
, write_fds
);
64 if (fds
[i
].events
& POLLPRI
)
65 FD_SET(fds
[i
].fd
, except_fds
);
67 else if (fds
[i
].fd
>= 0)
70 fds
[i
].revents
= POLLNVAL
;
77 /* Only invalid fds? Return. */
78 if ((nfds_t
) invalid_fds
== nfds
)
80 /* POSIX doesn't explicitely define this behaviour, but on Linux,
81 the timeout is set to 0 if an error occurs, and POLLNVAL is one
82 of these errors. So, for Linux-compatibility's sake... */
83 tv
.tv_sec
= tv
.tv_usec
= 0;
86 int ret
= cygwin_select (max_fd
+ 1, read_fds
, write_fds
, except_fds
,
87 timeout
< 0 ? NULL
: &tv
);
88 /* timeout, signal, whatever? Return. If invalid fds exist, return with
91 return invalid_fds
?: ret
;
93 /* Set revents fields and count fds with non-zero revents fields for
96 for (unsigned int i
= 0; i
< nfds
; ++i
)
98 if (fds
[i
].fd
>= 0 && fds
[i
].revents
!= POLLNVAL
)
100 fhandler_socket
*sock
;
102 /* Check if the descriptor has been closed, or if shutdown for the
103 read side has been called on a socket. */
104 if (cygheap
->fdtab
.not_open (fds
[i
].fd
)
105 || ((sock
= cygheap
->fdtab
[fds
[i
].fd
]->is_socket ())
106 && sock
->saw_shutdown_read ()))
107 fds
[i
].revents
= POLLHUP
;
110 if (FD_ISSET(fds
[i
].fd
, read_fds
))
111 /* This should be sufficient for sockets, too. Using
112 MSG_PEEK, as before, can be considered dangerous at
113 best. Quote from W. Richard Stevens: "The presence
114 of an error can be considered either normal data or
115 an error (POLLERR). In either case, a subsequent read
116 will return -1 with errno set to the appropriate value."
117 So it looks like there's actually no good reason to
119 fds
[i
].revents
|= POLLIN
;
120 /* Handle failed connect. */
121 if (FD_ISSET(fds
[i
].fd
, write_fds
)
122 && (sock
= cygheap
->fdtab
[fds
[i
].fd
]->is_socket ())
123 && sock
->connect_state () == connect_failed
)
124 fds
[i
].revents
|= (POLLIN
| POLLERR
);
127 if (FD_ISSET(fds
[i
].fd
, write_fds
))
128 fds
[i
].revents
|= POLLOUT
;
129 if (FD_ISSET(fds
[i
].fd
, except_fds
))
130 fds
[i
].revents
|= POLLPRI
;
137 /* Number of fds with event includes the invalid fds. */
138 return ret
+ invalid_fds
;
142 ppoll (struct pollfd
*fds
, nfds_t nfds
, const struct timespec
*timeout_ts
,
143 const sigset_t
*sigmask
)
146 sigset_t oldset
= _my_tls
.sigmask
;
149 if (efault
.faulted (EFAULT
))
151 timeout
= (timeout_ts
== NULL
)
153 : (timeout_ts
->tv_sec
* 1000 + timeout_ts
->tv_nsec
/ 1000000);
155 set_signal_mask (_my_tls
.sigmask
, *sigmask
);
156 int ret
= poll (fds
, nfds
, timeout
);
158 set_signal_mask (_my_tls
.sigmask
, oldset
);
This page took 0.037889 seconds and 5 git commands to generate.