* 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:
parent
2180b9627d
commit
04843bf4a0
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue