* fhandler.h (enum conn_state): Add connect_failed state.
* fhandler_socket.cc (fhandler_socket::connect): Set connect_state to connect_failed when connect failed. * poll.cc (poll): Change errno to EINVAL if allocating memory fails, according to SUSv3. Add socket descriptors always to except_fds. Test for failed connect and set revents flags appropriately. * select.cc (set_bits): Set connect_state to connect_failed when select indicates failed nonblocking connect. (fhandler_dev_null::select_except): Set except_ready to false so that /dev/null is not always in except state. (peek_socket): Fix bogus conditional. (fhandler_socket::select_write): Treat all connect_states except unconnected equivalent to return consistent results. (fhandler_windows::select_except): Set except_ready to false so that /dev/windows is not always in except state.
This commit is contained in:
		| @@ -1,3 +1,21 @@ | |||||||
|  | 2005-04-18  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* fhandler.h (enum conn_state): Add connect_failed state. | ||||||
|  | 	* fhandler_socket.cc (fhandler_socket::connect): Set connect_state to | ||||||
|  | 	connect_failed when connect failed. | ||||||
|  | 	* poll.cc (poll): Change errno to EINVAL if allocating memory fails, | ||||||
|  | 	according to SUSv3. Add socket descriptors always to except_fds. Test | ||||||
|  | 	for failed connect and set revents flags appropriately. | ||||||
|  | 	* select.cc (set_bits): Set connect_state to connect_failed when | ||||||
|  | 	select indicates failed nonblocking connect. | ||||||
|  | 	(fhandler_dev_null::select_except): Set except_ready to false so that | ||||||
|  | 	/dev/null is not always in except state. | ||||||
|  | 	(peek_socket): Fix bogus conditional. | ||||||
|  | 	(fhandler_socket::select_write): Treat all connect_states except | ||||||
|  | 	unconnected equivalent to return consistent results. | ||||||
|  | 	(fhandler_windows::select_except): Set except_ready to false so that | ||||||
|  | 	/dev/windows is not always in except state. | ||||||
|  |  | ||||||
| 2005-04-18  Christopher Faylor  <cgf@timesys.com> | 2005-04-18  Christopher Faylor  <cgf@timesys.com> | ||||||
|  |  | ||||||
| 	* include/cygwin/version.h: Bump DLL minor number to 16. | 	* include/cygwin/version.h: Bump DLL minor number to 16. | ||||||
|   | |||||||
| @@ -50,7 +50,8 @@ enum conn_state | |||||||
| { | { | ||||||
|   unconnected = 0, |   unconnected = 0, | ||||||
|   connect_pending = 1, |   connect_pending = 1, | ||||||
|   connected = 2 |   connected = 2, | ||||||
|  |   connect_failed = 3 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum line_edit_status | enum line_edit_status | ||||||
|   | |||||||
| @@ -706,7 +706,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) | |||||||
|       err = WSAGetLastError (); |       err = WSAGetLastError (); | ||||||
|       /* Special handling for connect to return the correct error code |       /* Special handling for connect to return the correct error code | ||||||
| 	 when called on a non-blocking socket. */ | 	 when called on a non-blocking socket. */ | ||||||
|       if (is_nonblocking () || connect_state () == connect_pending) |       if (is_nonblocking ()) | ||||||
| 	{ | 	{ | ||||||
| 	  if (err == WSAEWOULDBLOCK || err == WSAEALREADY) | 	  if (err == WSAEWOULDBLOCK || err == WSAEALREADY) | ||||||
| 	    in_progress = true; | 	    in_progress = true; | ||||||
| @@ -736,6 +736,8 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) | |||||||
|  |  | ||||||
|   if (err == WSAEINPROGRESS || err == WSAEALREADY) |   if (err == WSAEINPROGRESS || err == WSAEALREADY) | ||||||
|     connect_state (connect_pending); |     connect_state (connect_pending); | ||||||
|  |   else if (err) | ||||||
|  |     connect_state (connect_failed); | ||||||
|   else |   else | ||||||
|     connect_state (connected); |     connect_state (connected); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) | |||||||
|  |  | ||||||
|   if (!read_fds || !write_fds || !except_fds) |   if (!read_fds || !write_fds || !except_fds) | ||||||
|     { |     { | ||||||
|       set_errno (ENOMEM); |       set_errno (EINVAL);	/* According to SUSv3. */ | ||||||
|       return -1; |       return -1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -63,7 +63,9 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) | |||||||
| 	    FD_SET(fds[i].fd, read_fds); | 	    FD_SET(fds[i].fd, read_fds); | ||||||
| 	  if (fds[i].events & POLLOUT) | 	  if (fds[i].events & POLLOUT) | ||||||
| 	    FD_SET(fds[i].fd, write_fds); | 	    FD_SET(fds[i].fd, write_fds); | ||||||
| 	  if (fds[i].events & POLLPRI) | 	  /* On sockets, except_fds is needed to catch failed connects. */ | ||||||
|  | 	  if ((fds[i].events & POLLPRI) | ||||||
|  | 	      || cygheap->fdtab[fds[i].fd]->is_socket ()) | ||||||
| 	    FD_SET(fds[i].fd, except_fds); | 	    FD_SET(fds[i].fd, except_fds); | ||||||
| 	} | 	} | ||||||
|       else if (fds[i].fd >= 0) |       else if (fds[i].fd >= 0) | ||||||
| @@ -87,11 +89,12 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) | |||||||
| 	      fds[i].revents = POLLHUP; | 	      fds[i].revents = POLLHUP; | ||||||
| 	    else | 	    else | ||||||
| 	      { | 	      { | ||||||
|  | 		fhandler_socket *sock; | ||||||
|  |  | ||||||
| 		if (FD_ISSET(fds[i].fd, read_fds)) | 		if (FD_ISSET(fds[i].fd, read_fds)) | ||||||
| 		  { | 		  { | ||||||
| 		    char peek[1]; | 		    char peek[1]; | ||||||
| 		    fhandler_socket *sock = | 		    sock = cygheap->fdtab[fds[i].fd]->is_socket (); | ||||||
| 				      cygheap->fdtab[fds[i].fd]->is_socket (); |  | ||||||
| 		    if (!sock) | 		    if (!sock) | ||||||
| 		      fds[i].revents |= POLLIN; | 		      fds[i].revents |= POLLIN; | ||||||
| 		    else | 		    else | ||||||
| @@ -125,6 +128,14 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) | |||||||
| 			set_errno (old_errno); | 			set_errno (old_errno); | ||||||
| 		      } | 		      } | ||||||
| 		  } | 		  } | ||||||
|  | 		/* Handle failed connect. */ | ||||||
|  | 		if (FD_ISSET(fds[i].fd, write_fds) | ||||||
|  | 		    && FD_ISSET(fds[i].fd, except_fds) | ||||||
|  | 		    && (sock = cygheap->fdtab[fds[i].fd]->is_socket ()) | ||||||
|  | 		    && sock->connect_state () == connect_failed) | ||||||
|  | 		  fds[i].revents |= (POLLIN | POLLERR); | ||||||
|  | 		else  | ||||||
|  | 		  { | ||||||
| 		    if (FD_ISSET(fds[i].fd, write_fds)) | 		    if (FD_ISSET(fds[i].fd, write_fds)) | ||||||
| 		      fds[i].revents |= POLLOUT; | 		      fds[i].revents |= POLLOUT; | ||||||
| 		    if (FD_ISSET(fds[i].fd, except_fds)) | 		    if (FD_ISSET(fds[i].fd, except_fds)) | ||||||
| @@ -132,6 +143,7 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) | |||||||
| 		  } | 		  } | ||||||
| 	      } | 	      } | ||||||
| 	  } | 	  } | ||||||
|  |       } | ||||||
|  |  | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -352,7 +352,7 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds, | |||||||
| 	{ | 	{ | ||||||
| 	  UNIX_FD_SET (me->fd, writefds); | 	  UNIX_FD_SET (me->fd, writefds); | ||||||
| 	  if ((sock = me->fh->is_socket ())) | 	  if ((sock = me->fh->is_socket ())) | ||||||
| 	    sock->connect_state (connected); | 	    sock->connect_state (connect_failed); | ||||||
| 	} | 	} | ||||||
|       if (me->except_selected) |       if (me->except_selected) | ||||||
| 	UNIX_FD_SET (me->fd, exceptfds); | 	UNIX_FD_SET (me->fd, exceptfds); | ||||||
| @@ -915,7 +915,7 @@ fhandler_dev_null::select_except (select_record *s) | |||||||
|     } |     } | ||||||
|   s->h = get_handle (); |   s->h = get_handle (); | ||||||
|   s->except_selected = true; |   s->except_selected = true; | ||||||
|   s->except_ready = true; |   s->except_ready = false; | ||||||
|   return s; |   return s; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1271,11 +1271,11 @@ peek_socket (select_record *me, bool) | |||||||
| 	  set_winsock_errno (); | 	  set_winsock_errno (); | ||||||
| 	  return 0; | 	  return 0; | ||||||
| 	} | 	} | ||||||
|       if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready)) |       if (WINSOCK_FD_ISSET (h, &ws_readfds)) | ||||||
| 	me->read_ready = true; | 	me->read_ready = true; | ||||||
|       if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready)) |       if (WINSOCK_FD_ISSET (h, &ws_writefds)) | ||||||
| 	me->write_ready = true; | 	me->write_ready = true; | ||||||
|       if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || ((me->except_selected || me->except_on_write) && me->except_ready)) |       if (WINSOCK_FD_ISSET (h, &ws_exceptfds)) | ||||||
| 	me->except_ready = true; | 	me->except_ready = true; | ||||||
|     } |     } | ||||||
|   return me->read_ready || me->write_ready || me->except_ready; |   return me->read_ready || me->write_ready || me->except_ready; | ||||||
| @@ -1460,7 +1460,7 @@ fhandler_socket::select_write (select_record *s) | |||||||
|   s->peek = peek_socket; |   s->peek = peek_socket; | ||||||
|   s->write_ready = saw_shutdown_write () || connect_state () == unconnected; |   s->write_ready = saw_shutdown_write () || connect_state () == unconnected; | ||||||
|   s->write_selected = true; |   s->write_selected = true; | ||||||
|   if (connect_state () == connect_pending) |   if (connect_state () != unconnected) | ||||||
|     { |     { | ||||||
|       s->except_ready = saw_shutdown_write () || saw_shutdown_read (); |       s->except_ready = saw_shutdown_write () || saw_shutdown_read (); | ||||||
|       s->except_on_write = true; |       s->except_on_write = true; | ||||||
| @@ -1559,7 +1559,7 @@ fhandler_windows::select_except (select_record *s) | |||||||
|   s->peek = peek_windows; |   s->peek = peek_windows; | ||||||
|   s->h = get_handle (); |   s->h = get_handle (); | ||||||
|   s->except_selected = true; |   s->except_selected = true; | ||||||
|   s->except_ready = true; |   s->except_ready = false; | ||||||
|   s->windows_handle = true; |   s->windows_handle = true; | ||||||
|   return s; |   return s; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user