X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c8921892b5c951af710815b29cca522ff31eb712..ff699386b9b709c069ecc3c24acd6f7f4644d23e:/src/msw/gsocket.c?ds=sidebyside diff --git a/src/msw/gsocket.c b/src/msw/gsocket.c index ed9f746283..9ea70c328e 100644 --- a/src/msw/gsocket.c +++ b/src/msw/gsocket.c @@ -3,6 +3,7 @@ * Name: gsocket.c * Author: Guillermo Rodriguez Garcia * Purpose: GSocket main MSW file + * Licence: The wxWindows licence * CVSID: $Id$ * ------------------------------------------------------------------------- */ @@ -26,6 +27,8 @@ # pragma warning(disable:4100) #endif /* _MSC_VER */ +#include + #ifndef __GSOCKET_STANDALONE__ # include "wx/defs.h" # include "wx/setup.h" @@ -56,8 +59,6 @@ #include #include -#include - /* if we use configure for MSW SOCKLEN_T will be already defined */ #ifndef SOCKLEN_T # define SOCKLEN_T int @@ -712,22 +713,51 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) FD_SET(socket->m_fd, &writefds); FD_SET(socket->m_fd, &exceptfds); - /* Check known state first */ - result |= (GSOCK_CONNECTION_FLAG & socket->m_detected & flags); - result |= (GSOCK_LOST_FLAG & socket->m_detected & flags); + /* Check 'sticky' CONNECTION flag first */ + result |= (GSOCK_CONNECTION_FLAG & socket->m_detected); + + /* If we have already detected a LOST event, then don't try + * to do any further processing. + */ + if ((socket->m_detected & GSOCK_LOST_FLAG) != 0) + { + socket->m_establishing = FALSE; + + return (GSOCK_LOST_FLAG & flags); + } /* Try select now */ if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0) - return result; + { + /* What to do here? */ + return (result & flags); + } /* Check for readability */ if (FD_ISSET(socket->m_fd, &readfds)) { - /* Assume that closure of the socket is always reported via exceptfds */ - if (socket->m_server && socket->m_stream) - result |= (GSOCK_CONNECTION_FLAG & flags); + char c; + + if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0) + { + result |= GSOCK_INPUT_FLAG; + } else - result |= (GSOCK_INPUT_FLAG & flags); + { + if (socket->m_server && socket->m_stream) + { + result |= GSOCK_CONNECTION_FLAG; + socket->m_detected |= GSOCK_CONNECTION_FLAG; + } + else + { + socket->m_detected = GSOCK_LOST_FLAG; + socket->m_establishing = FALSE; + + /* LOST event: Abort any further processing */ + return (GSOCK_LOST_FLAG & flags); + } + } } /* Check for writability */ @@ -735,23 +765,43 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) { if (socket->m_establishing && !socket->m_server) { - result |= (GSOCK_CONNECTION_FLAG & flags); + int error; + SOCKLEN_T len = sizeof(error); + socket->m_establishing = FALSE; - socket->m_detected |= GSOCK_CONNECTION_FLAG; + + getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len); + + if (error) + { + socket->m_detected = GSOCK_LOST_FLAG; + + /* LOST event: Abort any further processing */ + return (GSOCK_LOST_FLAG & flags); + } + else + { + result |= GSOCK_CONNECTION_FLAG; + socket->m_detected |= GSOCK_CONNECTION_FLAG; + } } else - result |= (GSOCK_OUTPUT_FLAG & flags); + { + result |= GSOCK_OUTPUT_FLAG; + } } - /* Check for exceptions and errors */ + /* Check for exceptions and errors (is this useful in Unices?) */ if (FD_ISSET(socket->m_fd, &exceptfds)) { - result |= (GSOCK_LOST_FLAG & flags); socket->m_establishing = FALSE; socket->m_detected = GSOCK_LOST_FLAG; + + /* LOST event: Abort any further processing */ + return (GSOCK_LOST_FLAG & flags); } - return result; + return (result & flags); #else