+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+ FD_SET(socket->m_fd, &readfds);
+ 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);
+
+ /* Try select now */
+ if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
+ return result;
+
+ /* Check for readability */
+ if (FD_ISSET(socket->m_fd, &readfds))
+ {
+ char c;
+
+ if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
+ {
+ result |= (GSOCK_INPUT_FLAG & flags);
+ }
+ else
+ {
+ if (socket->m_server && socket->m_stream)
+ {
+ result |= (GSOCK_CONNECTION_FLAG & flags);
+ socket->m_detected |= GSOCK_CONNECTION_FLAG;
+ }
+ else
+ {
+ result |= (GSOCK_LOST_FLAG & flags);
+ socket->m_detected = GSOCK_LOST_FLAG;
+ }
+ }
+ }
+
+ /* Check for writability */
+ if (FD_ISSET(socket->m_fd, &writefds))
+ {
+ if (socket->m_establishing && !socket->m_server)
+ {
+ int error;
+ SOCKLEN_T len = sizeof(error);
+
+ socket->m_establishing = FALSE;
+
+ getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len);
+
+ if (error)
+ {
+ result |= (GSOCK_LOST_FLAG & flags);
+ socket->m_detected = GSOCK_LOST_FLAG;
+ }
+ else
+ {
+ result |= (GSOCK_CONNECTION_FLAG & flags);
+ socket->m_detected |= GSOCK_CONNECTION_FLAG;
+ }
+ }
+ else
+ {
+ result |= (GSOCK_OUTPUT_FLAG & flags);
+ }
+ }
+
+ /* 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;