/* Like recv(), send(), ... */ int GSocket::Read(char *buffer, int size) { int ret; assert(this); if (m_fd == INVALID_SOCKET || m_server) { m_error = GSOCK_INVSOCK; return -1; } /* Disable events during query of socket status */ Disable(GSOCK_INPUT); /* If the socket is blocking, wait for data (with a timeout) */ if (Input_Timeout() == GSOCK_TIMEDOUT) /* We no longer return here immediately, otherwise socket events would not be re-enabled! */ ret = -1; else { /* Read the data */ if (m_stream) ret = Recv_Stream(buffer, size); else ret = Recv_Dgram(buffer, size); } if (ret == -1) { if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) m_error = GSOCK_WOULDBLOCK; else m_error = GSOCK_IOERR; } /* Enable events again now that we are done processing */ Enable(GSOCK_INPUT); return ret; }
/* Like recv(), send(), ... */ int GSocket::Read(char *buffer, int size) { int ret; assert(this); /* Reenable INPUT events */ m_detected &= ~GSOCK_INPUT_FLAG; if (m_fd == INVALID_SOCKET || m_server) { m_error = GSOCK_INVSOCK; return -1; } /* If the socket is blocking, wait for data (with a timeout) */ if (Input_Timeout() == GSOCK_TIMEDOUT) { m_error = GSOCK_TIMEDOUT; return -1; } /* Read the data */ if (m_stream) ret = Recv_Stream(buffer, size); else ret = Recv_Dgram(buffer, size); if (ret == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) m_error = GSOCK_IOERR; else m_error = GSOCK_WOULDBLOCK; return -1; } return ret; }
/* GSocket_WaitConnection: * Waits for an incoming client connection. Returns a pointer to * a GSocket object, or NULL if there was an error, in which case * the last error field will be updated for the calling GSocket. * * Error codes (set in the calling GSocket) * GSOCK_INVSOCK - the socket is not valid or not a server. * GSOCK_TIMEDOUT - timeout, no incoming connections. * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking. * GSOCK_MEMERR - couldn't allocate memory. * GSOCK_IOERR - low-level error. */ GSocket *GSocket::WaitConnection() { struct sockaddr from; SOCKLEN_T fromlen = sizeof(from); GSocket *connection; GSocketError err; int arg = 1; assert(this); /* If the socket has already been created, we exit immediately */ if (m_fd == INVALID_SOCKET || !m_server) { m_error = GSOCK_INVSOCK; return NULL; } /* Create a GSocket object for the new connection */ connection = GSocket_new(); if (!connection) { m_error = GSOCK_MEMERR; return NULL; } /* Wait for a connection (with timeout) */ if (Input_Timeout() == GSOCK_TIMEDOUT) { delete connection; /* m_error set by _GSocket_Input_Timeout */ return NULL; } connection->m_fd = accept(m_fd, &from, (SOCKLEN_T *) &fromlen); /* Reenable CONNECTION events */ Enable(GSOCK_CONNECTION); if (connection->m_fd == INVALID_SOCKET) { if (errno == EWOULDBLOCK) m_error = GSOCK_WOULDBLOCK; else m_error = GSOCK_IOERR; delete connection; return NULL; } /* Initialize all fields */ connection->m_server = false; connection->m_stream = true; /* Setup the peer address field */ connection->m_peer = GAddress_new(); if (!connection->m_peer) { delete connection; m_error = GSOCK_MEMERR; return NULL; } err = _GAddress_translate_from(connection->m_peer, &from, fromlen); if (err != GSOCK_NOERROR) { delete connection; m_error = err; return NULL; } #if defined(__EMX__) || defined(__VISAGECPP__) ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg)); #else ioctl(connection->m_fd, FIONBIO, &arg); #endif gs_gui_functions->Enable_Events(connection); return connection; }
/* GSocket_WaitConnection: * Waits for an incoming client connection. Returns a pointer to * a GSocket object, or NULL if there was an error, in which case * the last error field will be updated for the calling GSocket. * * Error codes (set in the calling GSocket) * GSOCK_INVSOCK - the socket is not valid or not a server. * GSOCK_TIMEDOUT - timeout, no incoming connections. * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking. * GSOCK_MEMERR - couldn't allocate memory. * GSOCK_IOERR - low-level error. */ GSocket *GSocket::WaitConnection() { GSocket *connection; struct sockaddr from; WX_SOCKLEN_T fromlen = sizeof(from); GSocketError err; u_long arg = 1; assert(this); /* Reenable CONNECTION events */ m_detected &= ~GSOCK_CONNECTION_FLAG; /* If the socket has already been created, we exit immediately */ if (m_fd == INVALID_SOCKET || !m_server) { m_error = GSOCK_INVSOCK; return NULL; } /* Create a GSocket object for the new connection */ connection = GSocket_new(); if (!connection) { m_error = GSOCK_MEMERR; return NULL; } /* Wait for a connection (with timeout) */ if (Input_Timeout() == GSOCK_TIMEDOUT) { delete connection; /* m_error set by _GSocket_Input_Timeout */ return NULL; } connection->m_fd = accept(m_fd, &from, &fromlen); if (connection->m_fd == INVALID_SOCKET) { if (WSAGetLastError() == WSAEWOULDBLOCK) m_error = GSOCK_WOULDBLOCK; else m_error = GSOCK_IOERR; delete connection; return NULL; } /* Initialize all fields */ connection->m_server = false; connection->m_stream = true; /* Setup the peer address field */ connection->m_peer = GAddress_new(); if (!connection->m_peer) { delete connection; m_error = GSOCK_MEMERR; return NULL; } err = _GAddress_translate_from(connection->m_peer, &from, fromlen); if (err != GSOCK_NOERROR) { GAddress_destroy(connection->m_peer); delete connection; m_error = err; return NULL; } ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg); gs_gui_functions->Enable_Events(connection); return connection; }