diff options
author | Brent Cook <bcook@openbsd.org> | 2015-03-08 16:39:48 -0500 |
---|---|---|
committer | Brent Cook <bcook@openbsd.org> | 2015-03-08 20:47:03 -0500 |
commit | 148aebdbb1613d250caf378f3484cb4e1c47f3aa (patch) | |
tree | b936102f6b7b081eca88a1280bdcb6ea73e98fbb /apps | |
parent | 213eb9465e64c1d0d74ab93b9d94a88c03f2ca43 (diff) | |
download | portable-148aebdbb1613d250caf378f3484cb4e1c47f3aa.tar.gz portable-148aebdbb1613d250caf378f3484cb4e1c47f3aa.tar.bz2 portable-148aebdbb1613d250caf378f3484cb4e1c47f3aa.zip |
fix hangs reading stdin on Windows
Diffstat (limited to 'apps')
-rw-r--r-- | apps/poll_win.c | 39 |
1 files changed, 16 insertions, 23 deletions
diff --git a/apps/poll_win.c b/apps/poll_win.c index bf30ccf..ce47b01 100644 --- a/apps/poll_win.c +++ b/apps/poll_win.c | |||
@@ -44,6 +44,8 @@ conn_has_oob_data(int fd) | |||
44 | static int | 44 | static int |
45 | is_socket(int fd) | 45 | is_socket(int fd) |
46 | { | 46 | { |
47 | if (fd < 3) | ||
48 | return 0; | ||
47 | WSANETWORKEVENTS events; | 49 | WSANETWORKEVENTS events; |
48 | return (WSAEnumNetworkEvents((SOCKET)fd, NULL, &events) == 0); | 50 | return (WSAEnumNetworkEvents((SOCKET)fd, NULL, &events) == 0); |
49 | } | 51 | } |
@@ -160,10 +162,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
160 | nfds_t i; | 162 | nfds_t i; |
161 | int timespent_ms, looptime_ms; | 163 | int timespent_ms, looptime_ms; |
162 | 164 | ||
163 | #define FD_IS_SOCKET (1 << 0) | ||
164 | int fd_state[FD_SETSIZE]; | ||
165 | int num_fds; | ||
166 | |||
167 | /* | 165 | /* |
168 | * select machinery | 166 | * select machinery |
169 | */ | 167 | */ |
@@ -190,14 +188,12 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
190 | FD_ZERO(&rfds); | 188 | FD_ZERO(&rfds); |
191 | FD_ZERO(&wfds); | 189 | FD_ZERO(&wfds); |
192 | FD_ZERO(&efds); | 190 | FD_ZERO(&efds); |
193 | num_fds = 0; | ||
194 | num_sockets = 0; | 191 | num_sockets = 0; |
195 | num_handles = 0; | 192 | num_handles = 0; |
196 | 193 | ||
197 | for (i = 0; i < nfds; i++) { | 194 | for (i = 0; i < nfds; i++) { |
198 | if ((int)pfds[i].fd < 0) { | 195 | if ((int)pfds[i].fd < 0) |
199 | continue; | 196 | continue; |
200 | } | ||
201 | 197 | ||
202 | if (is_socket(pfds[i].fd)) { | 198 | if (is_socket(pfds[i].fd)) { |
203 | if (num_sockets >= FD_SETSIZE) { | 199 | if (num_sockets >= FD_SETSIZE) { |
@@ -205,8 +201,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
205 | return -1; | 201 | return -1; |
206 | } | 202 | } |
207 | 203 | ||
208 | fd_state[num_fds] = FD_IS_SOCKET; | ||
209 | |||
210 | FD_SET(pfds[i].fd, &efds); | 204 | FD_SET(pfds[i].fd, &efds); |
211 | 205 | ||
212 | if (pfds[i].events & | 206 | if (pfds[i].events & |
@@ -229,8 +223,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
229 | handles[num_handles++] = | 223 | handles[num_handles++] = |
230 | (HANDLE)_get_osfhandle(pfds[i].fd); | 224 | (HANDLE)_get_osfhandle(pfds[i].fd); |
231 | } | 225 | } |
232 | |||
233 | num_fds++; | ||
234 | } | 226 | } |
235 | 227 | ||
236 | /* | 228 | /* |
@@ -254,21 +246,22 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
254 | * than simply triggering if there is space available. | 246 | * than simply triggering if there is space available. |
255 | */ | 247 | */ |
256 | timespent_ms = 0; | 248 | timespent_ms = 0; |
257 | wait_rc = 0; | 249 | wait_rc = WAIT_FAILED; |
258 | 250 | ||
259 | if (timeout_ms < 0) { | 251 | if (timeout_ms < 0) |
260 | timeout_ms = INFINITE; | 252 | timeout_ms = INFINITE; |
261 | } | ||
262 | looptime_ms = timeout_ms > 100 ? 100 : timeout_ms; | 253 | looptime_ms = timeout_ms > 100 ? 100 : timeout_ms; |
263 | 254 | ||
264 | do { | 255 | do { |
265 | struct timeval tv = {0, looptime_ms * 1000}; | 256 | struct timeval tv = {0, looptime_ms * 1000}; |
257 | int handle_signaled = 0; | ||
266 | 258 | ||
267 | /* | 259 | /* |
268 | * Check if any file handles have signaled | 260 | * Check if any file handles have signaled |
269 | */ | 261 | */ |
270 | if (num_handles) { | 262 | if (num_handles) { |
271 | wait_rc = WaitForMultipleObjects(num_handles, handles, FALSE, 0); | 263 | wait_rc = WaitForMultipleObjects(num_handles, handles, |
264 | FALSE, 0); | ||
272 | if (wait_rc == WAIT_FAILED) { | 265 | if (wait_rc == WAIT_FAILED) { |
273 | /* | 266 | /* |
274 | * The documentation for WaitForMultipleObjects | 267 | * The documentation for WaitForMultipleObjects |
@@ -285,18 +278,20 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
285 | /* | 278 | /* |
286 | * If we signaled on a file handle, don't wait on the sockets. | 279 | * If we signaled on a file handle, don't wait on the sockets. |
287 | */ | 280 | */ |
288 | if (wait_rc >= WAIT_OBJECT_0) | 281 | if (wait_rc >= WAIT_OBJECT_0 && |
282 | (wait_rc <= WAIT_OBJECT_0 + num_handles - 1)) { | ||
289 | tv.tv_usec = 0; | 283 | tv.tv_usec = 0; |
284 | handle_signaled = 1; | ||
285 | } | ||
290 | 286 | ||
291 | /* | 287 | /* |
292 | * Check if any sockets have signaled | 288 | * Check if any sockets have signaled |
293 | */ | 289 | */ |
294 | rc = select(0, &rfds, &wfds, &efds, &tv); | 290 | rc = select(0, &rfds, &wfds, &efds, &tv); |
295 | if (rc == SOCKET_ERROR) { | 291 | if (!handle_signaled && rc == SOCKET_ERROR) |
296 | return wsa_select_errno(WSAGetLastError()); | 292 | return wsa_select_errno(WSAGetLastError()); |
297 | } | ||
298 | 293 | ||
299 | if (wait_rc >= WAIT_OBJECT_0 || (num_sockets && rc > 0)) | 294 | if (handle_signaled || (num_sockets && rc > 0)) |
300 | break; | 295 | break; |
301 | 296 | ||
302 | timespent_ms += looptime_ms; | 297 | timespent_ms += looptime_ms; |
@@ -305,14 +300,14 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
305 | 300 | ||
306 | rc = 0; | 301 | rc = 0; |
307 | num_handles = 0; | 302 | num_handles = 0; |
308 | num_fds = 0; | ||
309 | for (i = 0; i < nfds; i++) { | 303 | for (i = 0; i < nfds; i++) { |
310 | pfds[i].revents = 0; | 304 | pfds[i].revents = 0; |
311 | 305 | ||
312 | if ((int)pfds[i].fd < 0) | 306 | if ((int)pfds[i].fd < 0) |
313 | continue; | 307 | continue; |
314 | 308 | ||
315 | if (fd_state[num_fds] & FD_IS_SOCKET) { | 309 | if (is_socket(pfds[i].fd)) { |
310 | |||
316 | pfds[i].revents = compute_select_revents(pfds[i].fd, | 311 | pfds[i].revents = compute_select_revents(pfds[i].fd, |
317 | pfds[i].events, &rfds, &wfds, &efds); | 312 | pfds[i].events, &rfds, &wfds, &efds); |
318 | 313 | ||
@@ -323,8 +318,6 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
323 | num_handles++; | 318 | num_handles++; |
324 | } | 319 | } |
325 | 320 | ||
326 | num_fds++; | ||
327 | |||
328 | if (pfds[i].revents) | 321 | if (pfds[i].revents) |
329 | rc++; | 322 | rc++; |
330 | } | 323 | } |