* 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:
Corinna Vinschen
2005-04-18 18:56:52 +00:00
parent 2180b9627d
commit 04843bf4a0
5 changed files with 50 additions and 17 deletions

View File

@@ -45,7 +45,7 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
if (!read_fds || !write_fds || !except_fds)
{
set_errno (ENOMEM);
set_errno (EINVAL); /* According to SUSv3. */
return -1;
}
@@ -63,7 +63,9 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
FD_SET(fds[i].fd, read_fds);
if (fds[i].events & POLLOUT)
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);
}
else if (fds[i].fd >= 0)
@@ -87,11 +89,12 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
fds[i].revents = POLLHUP;
else
{
fhandler_socket *sock;
if (FD_ISSET(fds[i].fd, read_fds))
{
char peek[1];
fhandler_socket *sock =
cygheap->fdtab[fds[i].fd]->is_socket ();
sock = cygheap->fdtab[fds[i].fd]->is_socket ();
if (!sock)
fds[i].revents |= POLLIN;
else
@@ -125,10 +128,19 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
set_errno (old_errno);
}
}
if (FD_ISSET(fds[i].fd, write_fds))
fds[i].revents |= POLLOUT;
if (FD_ISSET(fds[i].fd, except_fds))
fds[i].revents |= POLLPRI;
/* 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))
fds[i].revents |= POLLOUT;
if (FD_ISSET(fds[i].fd, except_fds))
fds[i].revents |= POLLPRI;
}
}
}
}