{
gs_gui_functions = guifunc;
}
-
+
int GSocket_Init(void)
{
if (gs_gui_functions)
* Sets up this socket as a server. The local address must have been
* set with GSocket_SetLocal() before GSocket_SetServer() is called.
* Returns GSOCK_NOERROR on success, one of the following otherwise:
- *
+ *
* Error codes:
* GSOCK_INVSOCK - the socket is in use.
* GSOCK_INVADDR - the local address has not been set.
- * GSOCK_IOERR - low-level error.
+ * GSOCK_IOERR - low-level error.
*/
GSocketError GSocket_SetServer(GSocket *sck)
{
#endif
_GSocket_Enable_Events(sck);
+ /* allow a socket to re-bind if the socket is in the TIME_WAIT
+ state after being previously closed.
+ */
+ if (sck->m_reusable)
+ setsockopt(socket->m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long));
+
/* Bind to the local address,
* retrieve the actual address bound,
* and listen up to 5 connections.
* 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.
+ * GSOCK_IOERR - low-level error.
*/
GSocket *GSocket_WaitConnection(GSocket *socket)
{
return connection;
}
+int GSocket_SetReusable(GSocket *socket)
+{
+ /* socket must not be null, and must not be in use/already bound */
+ if (NULL != socket && socket->m_fd == INVALID_SOCKET) {
+ socket->m_reusable = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
/* Client specific parts */
/* GSocket_Connect:
* GSOCK_TIMEDOUT - timeout, the connection failed.
* GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
* GSOCK_MEMERR - couldn't allocate memory.
- * GSOCK_IOERR - low-level error.
+ * GSOCK_IOERR - low-level error.
*/
GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
{
/* Disable events during query of socket status */
_GSocket_Disable(socket, GSOCK_INPUT);
-
+
/* If the socket is blocking, wait for data (with a timeout) */
if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
/* We no longer return here immediately, otherwise socket events would not be re-enabled! */
else
ret = _GSocket_Recv_Dgram(socket, buffer, size);
}
-
+
if (ret == -1)
{
if (errno == EWOULDBLOCK)
else
socket->m_error = GSOCK_IOERR;
}
-
+
/* Enable events again now that we are done processing */
_GSocket_Enable(socket, GSOCK_INPUT);
-
+
return ret;
}
int GSocket_Write(GSocket *socket, const char *buffer, int size)
-{
+{
int ret;
assert(socket != NULL);
-
+
GSocket_Debug(( "GSocket_Write #1, size %d\n", size ));
if (socket->m_fd == INVALID_SOCKET || socket->m_server)
ret = _GSocket_Send_Stream(socket, buffer, size);
else
ret = _GSocket_Send_Dgram(socket, buffer, size);
-
+
GSocket_Debug(( "GSocket_Write #4, size %d\n", size ));
if (ret == -1)
_GSocket_Enable(socket, GSOCK_OUTPUT);
return -1;
}
-
+
GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret ));
return ret;
{
socket->m_detected = GSOCK_LOST_FLAG;
socket->m_establishing = FALSE;
-
+
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
* operation, there is still data available, the callback function will
* be called again.
* GSOCK_OUTPUT:
- * The socket is available for writing. That is, the next write call
+ * The socket is available for writing. That is, the next write call
* won't block. This event is generated only once, when the connection is
* first established, and then only if a call failed with GSOCK_WOULDBLOCK,
* when the output buffer empties again. This means that the app should
return GSOCK_OPTERR;
}
-GSocketError GSocket_SetSockOpt(GSocket *socket, int level, int optname,
+GSocketError GSocket_SetSockOpt(GSocket *socket, int level, int optname,
const void *optval, int optlen)
{
if (setsockopt(socket->m_fd, level, optname, optval, optlen) == 0)
{
- return GSOCK_NOERROR;
+ return GSOCK_NOERROR;
}
return GSOCK_OPTERR;
}
-GSocketError GSocket_SetReuseAddr(GSocket *socket)
-{
- /* allow a socket to re-bind if the socket is in the TIME_WAIT
- state after being previously closed.
- */
- u_long arg = 1;
- setsockopt(socket->m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long));
-}
-
void GSocket_Streamed(GSocket *socket)
{
socket->m_stream = TRUE;
address->m_error = GSOCK_INVPORT;
return GSOCK_INVPORT;
}
-
+
se = getservbyname(port, protocol);
if (!se)
{
assert(address != NULL);
CHECK_ADDRESS(address, INET);
-
+
addr = (struct sockaddr_in *)address->m_addr;
addr->sin_port = htons(port);
char *addr_buf;
struct sockaddr_in *addr;
- assert(address != NULL);
+ assert(address != NULL);
CHECK_ADDRESS(address, INET);
addr = (struct sockaddr_in *)address->m_addr;
{
struct sockaddr_in *addr;
- assert(address != NULL);
- CHECK_ADDRESS_RETVAL(address, INET, 0);
+ assert(address != NULL);
+ CHECK_ADDRESS_RETVAL(address, INET, 0);
addr = (struct sockaddr_in *)address->m_addr;
{
struct sockaddr_in *addr;
- assert(address != NULL);
- CHECK_ADDRESS_RETVAL(address, INET, 0);
+ assert(address != NULL);
+ CHECK_ADDRESS_RETVAL(address, INET, 0);
addr = (struct sockaddr_in *)address->m_addr;
return ntohs(addr->sin_port);
{
struct sockaddr_un *addr;
- assert(address != NULL);
+ assert(address != NULL);
- CHECK_ADDRESS(address, UNIX);
+ CHECK_ADDRESS(address, UNIX);
addr = ((struct sockaddr_un *)address->m_addr);
strncpy(addr->sun_path, path, UNIX_SOCK_PATHLEN);