X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4056c8fe0c3d72a1c2df3d28222b261b6a5987b2..441b46ac5e09a531b4a64180fa6ec9f4777d23a0:/src/unix/gsocket.c?ds=inline diff --git a/src/unix/gsocket.c b/src/unix/gsocket.c index dd8bfc5a92..fd8824ce95 100644 --- a/src/unix/gsocket.c +++ b/src/unix/gsocket.c @@ -4,7 +4,7 @@ * Authors: Guilhem Lavaux, * Guillermo Rodriguez Garcia (maintainer) * Purpose: GSocket main Unix and OS/2 file - * Licence: The wxWindows licence + * Licence: The wxWidgets licence * CVSID: $Id$ * ------------------------------------------------------------------------- */ @@ -197,7 +197,7 @@ void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *guifunc) { gs_gui_functions = guifunc; } - + int GSocket_Init(void) { if (gs_gui_functions) @@ -437,11 +437,11 @@ GAddress *GSocket_GetPeer(GSocket *socket) * 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) { @@ -466,7 +466,6 @@ GSocketError GSocket_SetServer(GSocket *sck) /* Initialize all fields */ sck->m_stream = TRUE; sck->m_server = TRUE; - sck->m_oriented = TRUE; /* Create the socket */ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0); @@ -486,7 +485,8 @@ GSocketError GSocket_SetServer(GSocket *sck) /* allow a socket to re-bind if the socket is in the TIME_WAIT state after being previously closed. */ - setsockopt(sck->m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long)); + if (sck->m_reusable) + setsockopt(sck->m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long)); /* Bind to the local address, * retrieve the actual address bound, @@ -516,7 +516,7 @@ GSocketError GSocket_SetServer(GSocket *sck) * 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) { @@ -571,7 +571,6 @@ GSocket *GSocket_WaitConnection(GSocket *socket) /* Initialize all fields */ connection->m_server = FALSE; connection->m_stream = TRUE; - connection->m_oriented = TRUE; /* Setup the peer address field */ connection->m_peer = GAddress_new(); @@ -599,6 +598,16 @@ 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: @@ -622,7 +631,7 @@ GSocket *GSocket_WaitConnection(GSocket *socket) * 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) { @@ -648,7 +657,6 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) /* Streamed or dgram socket? */ sck->m_stream = (stream == GSOCK_STREAMED); - sck->m_oriented = TRUE; sck->m_server = FALSE; sck->m_establishing = FALSE; @@ -758,7 +766,6 @@ GSocketError GSocket_SetNonOriented(GSocket *sck) /* Initialize all fields */ sck->m_stream = FALSE; sck->m_server = FALSE; - sck->m_oriented = FALSE; /* Create the socket */ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0); @@ -808,7 +815,7 @@ int GSocket_Read(GSocket *socket, char *buffer, int size) /* 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! */ @@ -820,7 +827,7 @@ int GSocket_Read(GSocket *socket, char *buffer, int size) else ret = _GSocket_Recv_Dgram(socket, buffer, size); } - + if (ret == -1) { if (errno == EWOULDBLOCK) @@ -828,19 +835,19 @@ int GSocket_Read(GSocket *socket, char *buffer, int size) 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) @@ -862,7 +869,7 @@ int GSocket_Write(GSocket *socket, const char *buffer, int size) 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) @@ -886,7 +893,7 @@ int GSocket_Write(GSocket *socket, const char *buffer, int size) _GSocket_Enable(socket, GSOCK_OUTPUT); return -1; } - + GSocket_Debug(( "GSocket_Write #5, size %d ret %d\n", size, ret )); return ret; @@ -964,7 +971,7 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) { socket->m_detected = GSOCK_LOST_FLAG; socket->m_establishing = FALSE; - + /* LOST event: Abort any further processing */ return (GSOCK_LOST_FLAG & flags); } @@ -1069,7 +1076,7 @@ GSocketError GSocket_GetError(GSocket *socket) * 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 @@ -1129,6 +1136,25 @@ void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags) } } +GSocketError GSocket_GetSockOpt(GSocket *socket, int level, int optname, + void *optval, int *optlen) +{ + if (getsockopt(socket->m_fd, level, optname, optval, optlen) == 0) + { + return GSOCK_NOERROR; + } + return GSOCK_OPTERR; +} + +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_OPTERR; +} #define CALL_CALLBACK(socket, event) { \ _GSocket_Disable(socket, event); \ @@ -1669,7 +1695,7 @@ GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port, address->m_error = GSOCK_INVPORT; return GSOCK_INVPORT; } - + se = getservbyname(port, protocol); if (!se) { @@ -1701,7 +1727,7 @@ GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port) assert(address != NULL); CHECK_ADDRESS(address, INET); - + addr = (struct sockaddr_in *)address->m_addr; addr->sin_port = htons(port); @@ -1714,7 +1740,7 @@ GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t char *addr_buf; struct sockaddr_in *addr; - assert(address != NULL); + assert(address != NULL); CHECK_ADDRESS(address, INET); addr = (struct sockaddr_in *)address->m_addr; @@ -1736,8 +1762,8 @@ unsigned long GAddress_INET_GetHostAddress(GAddress *address) { 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; @@ -1748,8 +1774,8 @@ unsigned short GAddress_INET_GetPort(GAddress *address) { 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); @@ -1786,9 +1812,9 @@ GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path) { 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);