diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index bf7a29b19..3a98ee302 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +2002-07-05 Corinna Vinschen + + * fhandler.h (fhandler_socket::is_unconnected): Constify. + (fhandler_socket::is_connect_pending): Ditto. + (fhandler_socket::is_connected): Ditto. + (fhandler_socket::set_connect_state): New method. + (struct select_record): Add member `except_on_write'. + (select_record::select_record): Initialize all bool values to `false'. + * fhandler_socket.cc: Use set_connect_state() method throughout. + (fhandler_socket::connect): Set state always to connected if connection + isn't pending. + * net.cc (cygwin_getsockopt): Revert erroneous previous patch. + * select.cc (set_bits): Check for `except_on_write'. Set fd in + write_fds if set. Set connect state to connected if fd has been + returned by WINSOCK_SELECT. + (peek_socket): Check for `except_on_write'. + (start_thread_socket): Ditto. + (fhandler_socket::select_write): Don't set `write_ready' if connect + is pending. Set `except_on_write' if connect is pending. + 2002-07-05 Christopher Faylor * ntdll.h (_SYSTEM_PROCESSOR_TIMES): Force eight byte alignment. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 980957a67..164a892d1 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -385,9 +385,10 @@ class fhandler_socket: public fhandler_base void set_shutdown_read () {FHSETF (SHUTRD);} void set_shutdown_write () {FHSETF (SHUTWR);} - bool is_unconnected () {return had_connect_or_listen == UNCONNECTED;} - bool is_connect_pending () {return had_connect_or_listen == CONNECT_PENDING;} - bool is_connected () {return had_connect_or_listen == CONNECTED;} + bool is_unconnected () const {return had_connect_or_listen == UNCONNECTED;} + bool is_connect_pending () const {return had_connect_or_listen == CONNECT_PENDING;} + bool is_connected () const {return had_connect_or_listen == CONNECTED;} + void set_connect_state (int newstate) { had_connect_or_listen = newstate; } int bind (const struct sockaddr *name, int namelen); int connect (const struct sockaddr *name, int namelen); @@ -1185,6 +1186,7 @@ struct select_record bool windows_handle; bool read_ready, write_ready, except_ready; bool read_selected, write_selected, except_selected; + bool except_on_write; int (*startup) (select_record *me, class select_stuff *stuff); int (*peek) (select_record *, bool); int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds, @@ -1193,9 +1195,10 @@ struct select_record struct select_record *next; select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL), - fh (in_fh), saw_error (0), windows_handle (0), - read_ready (0), write_ready (0), except_ready (0), - read_selected (0), write_selected (0), except_selected (0), + fh (in_fh), saw_error (false), windows_handle (false), + read_ready (false), write_ready (false), except_ready (false), + read_selected (false), write_selected (false), + except_selected (false), except_on_write (false), startup (NULL), peek (NULL), verify (NULL), cleanup (NULL), next (NULL) {} }; diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index e95655510..aed61d780 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -455,10 +455,10 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) } } - if (!res) - had_connect_or_listen = CONNECTED; - else if (WSAGetLastError () == WSAEINPROGRESS) - had_connect_or_listen = CONNECT_PENDING; + if (WSAGetLastError () == WSAEINPROGRESS) + set_connect_state (CONNECT_PENDING); + else + set_connect_state (CONNECTED); return res; } @@ -469,7 +469,7 @@ fhandler_socket::listen (int backlog) if (res) set_winsock_errno (); else - had_connect_or_listen = CONNECTED; + set_connect_state (CONNECTED); return res; } diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 1445ae683..870bf7865 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -712,8 +712,6 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval, int *optlen) if (optname == SO_ERROR) { int *e = (int *) optval; - if (!*e && fh->is_connect_pending ()) - *e = WSAEINPROGRESS; *e = find_winsock_errno (*e); } diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 46f0c6963..30e082a2e 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -336,11 +336,20 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds, if (me->write_selected && me->write_ready) { UNIX_FD_SET (me->fd, writefds); + if (me->except_on_write && me->fh->get_device () == FH_SOCKET) + ((fhandler_socket *) me->fh)->set_connect_state (CONNECTED); ready++; } - if (me->except_selected && me->except_ready) + if ((me->except_selected || me->except_on_write) && me->except_ready) { - UNIX_FD_SET (me->fd, exceptfds); + if (me->except_on_write) /* Only on sockets */ + { + UNIX_FD_SET (me->fd, writefds); + if (me->fh->get_device () == FH_SOCKET) + ((fhandler_socket *) me->fh)->set_connect_state (CONNECTED); + } + if (me->except_selected) + UNIX_FD_SET (me->fd, exceptfds); ready++; } select_printf ("ready %d", ready); @@ -1192,7 +1201,7 @@ peek_socket (select_record *me, bool) me->fd); WINSOCK_FD_SET (h, &ws_writefds); } - if (me->except_selected && !me->except_ready) + if ((me->except_selected || me->except_on_write) && !me->except_ready) { select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (), me->fd); @@ -1201,7 +1210,7 @@ peek_socket (select_record *me, bool) int r; if ((me->read_selected && !me->read_ready) || (me->write_selected && !me->write_ready) - || (me->except_selected && !me->except_ready)) + || ((me->except_selected || me->except_on_write) && !me->except_ready)) { r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv); select_printf ("WINSOCK_SELECT returned %d", r); @@ -1215,7 +1224,7 @@ peek_socket (select_record *me, bool) me->read_ready = true; if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready)) me->write_ready = true; - if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || (me->except_selected && me->except_ready)) + if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || ((me->except_selected || me->except_on_write) && me->except_ready)) me->except_ready = true; } return me->read_ready || me->write_ready || me->except_ready; @@ -1295,7 +1304,7 @@ start_thread_socket (select_record *me, select_stuff *stuff) WINSOCK_FD_SET (h, &si->writefds); select_printf ("Added to writefds"); } - if (s->except_selected && !s->except_ready) + if ((s->except_selected || s->except_on_write) && !s->except_ready) { WINSOCK_FD_SET (h, &si->exceptfds); select_printf ("Added to exceptfds"); @@ -1415,8 +1424,13 @@ fhandler_socket::select_write (select_record *s) s->cleanup = socket_cleanup; } s->peek = peek_socket; - s->write_ready = saw_shutdown_write () || !is_connected (); + s->write_ready = saw_shutdown_write () || is_unconnected (); s->write_selected = true; + if (is_connect_pending ()) + { + s->except_ready = saw_shutdown_write () || saw_shutdown_read (); + s->except_on_write = true; + } return s; }