aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorBrent Cook <bcook@openbsd.org>2015-03-08 16:39:48 -0500
committerBrent Cook <bcook@openbsd.org>2015-03-08 20:47:03 -0500
commit148aebdbb1613d250caf378f3484cb4e1c47f3aa (patch)
treeb936102f6b7b081eca88a1280bdcb6ea73e98fbb /apps
parent213eb9465e64c1d0d74ab93b9d94a88c03f2ca43 (diff)
downloadportable-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.c39
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)
44static int 44static int
45is_socket(int fd) 45is_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 }