diff options
-rw-r--r-- | winsup/cygwin/release/2.12.0 | 2 | ||||
-rw-r--r-- | winsup/cygwin/select.cc | 15 |
2 files changed, 11 insertions, 6 deletions
diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 15f07e021..dbda7886e 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -65,3 +65,5 @@ Bug Fixes even if file has been deleted. Addresses: https://cygwin.com/ml/cygwin/2018-12/msg00125.html https://cygwin.com/ml/cygwin/2018-12/msg00028.html + +- Fix a bug in select(2) when polling HANDLE-less descriptors. diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 0d82a5914..6ce679acf 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -164,17 +164,20 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select_stuff sel; sel.return_on_signal = 0; - /* Allocate some fd_set structures using the number of fds as a guide. */ - fd_set *r = allocfd_set (maxfds); - fd_set *w = allocfd_set (maxfds); - fd_set *e = allocfd_set (maxfds); + /* Allocate fd_set structures to store incoming fd sets. */ + fd_set *readfds_in = allocfd_set (maxfds); + fd_set *writefds_in = allocfd_set (maxfds); + fd_set *exceptfds_in = allocfd_set (maxfds); + memcpy (readfds_in, readfds, sizeof_fd_set (maxfds)); + memcpy (writefds_in, writefds, sizeof_fd_set (maxfds)); + memcpy (exceptfds_in, exceptfds, sizeof_fd_set (maxfds)); do { /* Build the select record per fd linked list and set state as needed. */ for (int i = 0; i < maxfds; i++) - if (!sel.test_and_set (i, readfds, writefds, exceptfds)) + if (!sel.test_and_set (i, readfds_in, writefds_in, exceptfds_in)) { select_printf ("aborting due to test_and_set error"); return -1; /* Invalid fd, maybe? */ @@ -186,7 +189,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, wait_state = select_stuff::select_ok; else /* wait for an fd to become active or time out */ - wait_state = sel.wait (r, w, e, us); + wait_state = sel.wait (readfds, writefds, exceptfds, us); select_printf ("sel.wait returns %d", wait_state); |