X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/aa3981f2c66ba95a056a6d0dbf983b2d64bc0d84..18c98e42eeb75317f75c9ba20b09a5bd531a690c:/src/msw/gsocket.c?ds=inline diff --git a/src/msw/gsocket.c b/src/msw/gsocket.c index 0ea9f1fd8a..88e8c99a5c 100644 --- a/src/msw/gsocket.c +++ b/src/msw/gsocket.c @@ -6,14 +6,19 @@ * ------------------------------------------------------------------------- */ +#ifndef __GSOCKET_STANDALONE__ +#include "wx/setup.h" +#endif -#ifdef __WXMSW__ +#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) + + +#ifndef __GSOCKET_STANDALONE__ -#include "wx/setup.h" #include "wx/msw/gsockmsw.h" #include "wx/gsocket.h" -#define INSTANCE wxhInstance +#define INSTANCE wxGetInstance() #else @@ -24,13 +29,11 @@ * be available and it must containt the app's instance * handle. */ -#define INSTANCE hInst +#define INSTANCE hInst -#endif /* __WXMSW__ */ +#endif /* __GSOCKET_STANDALONE__ */ -#if !defined(__WXMSW__) || (defined(__WXMSW__) && wxUSE_SOCKETS) - #include #include #include @@ -138,7 +141,8 @@ GSocket *GSocket_new() socket->m_stream = TRUE; socket->m_non_blocking = FALSE; socket->m_timeout.tv_sec = 10 * 60; /* 10 minutes */ - socket->m_timeout.tv_usec = 0; + socket->m_timeout.tv_usec = 0; + socket->m_detected = 0; /* Allocate a new message number for this socket */ EnterCriticalSection(&critical); @@ -168,26 +172,23 @@ void GSocket_destroy(GSocket *socket) { assert(socket != NULL); - /* We don't want more event notifications; so first of all we - * remove the socket from the list (NOTE: we won't get a CLOSE - * event for this socket if it wasn't closed before). - */ + /* Remove the socket from the list */ EnterCriticalSection(&critical); socketList[(socket->m_msgnumber - WM_USER)] = NULL; LeaveCriticalSection(&critical); - /* We check that the socket is really shutdowned */ + /* Check that the socket is really shutdowned */ if (socket->m_fd != INVALID_SOCKET) GSocket_Shutdown(socket); - /* We destroy private addresses */ + /* Destroy private addresses */ if (socket->m_local) GAddress_destroy(socket->m_local); if (socket->m_peer) GAddress_destroy(socket->m_peer); - /* We destroy socket itself */ + /* Destroy socket itself */ free(socket); } @@ -197,22 +198,20 @@ void GSocket_Shutdown(GSocket *socket) assert(socket != NULL); - /* If socket has been created, we shutdown it */ + /* If socket has been created, shutdown it */ if (socket->m_fd != INVALID_SOCKET) { - /* TODO: Guilhem only does this for connection oriented sockets (?) */ shutdown(socket->m_fd, 2); closesocket(socket->m_fd); socket->m_fd = INVALID_SOCKET; } - /* We disable GUI callbacks */ + /* Disable GUI callbacks */ for (evt = 0; evt < GSOCK_MAX_EVENT; evt++) - { socket->m_cbacks[evt] = NULL; - } - _GSocket_Configure_Callbacks(socket); + socket->m_detected = 0; + _GSocket_Disable_Events(socket); } /* Address handling */ @@ -344,7 +343,6 @@ GSocketError GSocket_SetServer(GSocket *sck) /* Create the socket */ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0); - ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg); if (sck->m_fd == INVALID_SOCKET) { @@ -352,6 +350,9 @@ GSocketError GSocket_SetServer(GSocket *sck) return GSOCK_IOERR; } + ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg); + _GSocket_Enable_Events(sck); + /* Bind the socket to the LOCAL address */ if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) { @@ -371,7 +372,7 @@ GSocketError GSocket_SetServer(GSocket *sck) } return GSOCK_NOERROR; -} +} /* GSocket_WaitConnection: * Waits for an incoming client connection. @@ -383,7 +384,8 @@ GSocket *GSocket_WaitConnection(GSocket *sck) assert(sck != NULL); - /* If the socket has already been created, we exit immediately */ + sck->m_detected &= ~GSOCK_CONNECTION_FLAG; + if (sck->m_fd == INVALID_SOCKET || !sck->m_server) { sck->m_error = GSOCK_INVSOCK; @@ -420,13 +422,14 @@ GSocket *GSocket_WaitConnection(GSocket *sck) return NULL; } - ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg); - /* Initialize all fields */ connection->m_server = FALSE; connection->m_stream = TRUE; connection->m_oriented = TRUE; + ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg); + _GSocket_Enable_Events(connection); + return connection; } @@ -457,7 +460,6 @@ GSocketError GSocket_SetNonOriented(GSocket *sck) /* Create the socket */ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0); - ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg); if (sck->m_fd == INVALID_SOCKET) { @@ -465,6 +467,9 @@ GSocketError GSocket_SetNonOriented(GSocket *sck) return GSOCK_IOERR; } + ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg); + _GSocket_Enable_Events(sck); + /* Bind it to the LOCAL address */ if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) != 0) { @@ -479,15 +484,15 @@ GSocketError GSocket_SetNonOriented(GSocket *sck) GSocketError GSocket_SetBroadcast(GSocket *sck) { - BOOL b; + BOOL b = TRUE; assert(sck != NULL); if (GSocket_SetNonOriented(sck) != GSOCK_NOERROR) return sck->m_error; - b = TRUE; - setsockopt(sck->m_fd, SOL_SOCKET, SO_BROADCAST, (const char FAR *) &b, sizeof(b)); + setsockopt(sck->m_fd, SOL_SOCKET, SO_BROADCAST, + (const char FAR *) &b, sizeof(b)); return GSOCK_NOERROR; } @@ -497,9 +502,11 @@ GSocketError GSocket_SetBroadcast(GSocket *sck) /* GSocket_Connect: * Establishes a client connection to a server using the "Peer" * field of GSocket. "Peer" must be set by GSocket_SetPeer() before - * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK - * if the socket is alredy in use, GSOCK_INVADDR if the peer address - * has not been set, or GSOCK_IOERR for other internal errors. + * GSocket_Connect() is called. Possible error codes are GSOCK_INVSOCK, + * GSOCK_INVADDR, GSOCK_TIMEDOUT, GSOCK_WOULDBLOCK and GSOCK_IOERR. + * If a socket is nonblocking and Connect() returns GSOCK_WOULDBLOCK, + * the connection request can be completed later. Use GSocket_Select() + * to check or wait for a GSOCK_CONNECTION event. */ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) { @@ -508,6 +515,8 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) assert(sck != NULL); + sck->m_detected &= ~GSOCK_CONNECTION_FLAG; + if (sck->m_fd != INVALID_SOCKET) { sck->m_error = GSOCK_INVSOCK; @@ -532,7 +541,6 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) /* Create the socket */ sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0); - ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg); if (sck->m_fd == INVALID_SOCKET) { @@ -540,6 +548,9 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) return GSOCK_IOERR; } + ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg); + _GSocket_Enable_Events(sck); + /* Connect it to the PEER address, with a timeout (see below) */ ret = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len); @@ -552,13 +563,13 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) * checking for writability to see if the connection request * completes. */ - if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking == FALSE)) + if ((err == WSAEWOULDBLOCK) && (!sck->m_non_blocking)) { if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT) { closesocket(sck->m_fd); sck->m_fd = INVALID_SOCKET; - /* sck->m_error is set in _GSocket_Input_Timeout */ + /* sck->m_error is set in _GSocket_Output_Timeout */ return GSOCK_TIMEDOUT; } else @@ -571,7 +582,7 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) * this way if the connection completes, a GSOCK_CONNECTION * event will be generated, if enabled. */ - if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking == TRUE)) + if ((err == WSAEWOULDBLOCK) && (sck->m_non_blocking)) { sck->m_error = GSOCK_WOULDBLOCK; return GSOCK_WOULDBLOCK; @@ -594,25 +605,60 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) /* Like recv(), send(), ... */ int GSocket_Read(GSocket *socket, char *buffer, int size) { + int ret; + assert(socket != NULL); + socket->m_detected &= ~GSOCK_INPUT_FLAG; + if (socket->m_fd == INVALID_SOCKET || socket->m_server) { socket->m_error = GSOCK_INVSOCK; return -1; } + /* If the socket is blocking, wait for data (with a timeout) */ if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT) return -1; + /* Read the data */ if (socket->m_stream) - return _GSocket_Recv_Stream(socket, buffer, size); + ret = _GSocket_Recv_Stream(socket, buffer, size); else - return _GSocket_Recv_Dgram(socket, buffer, size); + ret = _GSocket_Recv_Dgram(socket, buffer, size); + + if (ret == SOCKET_ERROR) + { + /* NOTE: Window sockets exhibit a very strange property; + * if the socket is in non-blocking mode (which is always + * the case here, no matter the setting of GSocket itself) + * a call to send() can fail with EWOULDBLOCK even when + * select() says that the socket is readable. + * + * This can break several things because, usually, if + * select() says that the socket is writable, it is + * assumed that send() won't fail. To avoid this, we + * return 0 instead of -1 for this special case. + */ + if (WSAGetLastError() != WSAEWOULDBLOCK) + { + socket->m_error = GSOCK_IOERR; + return -1; + } + else + { + socket->m_error = GSOCK_WOULDBLOCK; + return 0; + } + } + + return ret; } int GSocket_Write(GSocket *socket, const char *buffer, int size) { + int ret; + assert(socket != NULL); if (socket->m_fd == INVALID_SOCKET || socket->m_server) @@ -621,43 +667,48 @@ int GSocket_Write(GSocket *socket, const char *buffer, int size) return -1; } + /* If the socket is blocking, wait for writability (with a timeout) */ if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT) return -1; + /* Read the data */ if (socket->m_stream) - return _GSocket_Send_Stream(socket, buffer, size); + ret = _GSocket_Send_Stream(socket, buffer, size); else - return _GSocket_Send_Dgram(socket, buffer, size); -} - -bool GSocket_DataAvailable(GSocket *socket) -{ - fd_set read_set; - struct timeval tv; - - assert(socket != NULL); + ret = _GSocket_Send_Dgram(socket, buffer, size); - if (socket->m_fd == INVALID_SOCKET || socket->m_server) + if (ret == SOCKET_ERROR) { - socket->m_error = GSOCK_INVSOCK; - return FALSE; - } + if (WSAGetLastError() != WSAEWOULDBLOCK) + socket->m_error = GSOCK_IOERR; + else + socket->m_error = GSOCK_WOULDBLOCK; - FD_ZERO(&read_set); - FD_SET(socket->m_fd, &read_set); + socket->m_detected &= ~GSOCK_OUTPUT_FLAG; + return -1; + } - tv.tv_sec = 0; - tv.tv_usec = 0; + return ret; +} - select(socket->m_fd + 1, &read_set, NULL, NULL, &tv); +/* GSocket_Select: + * Polls the socket to determine its status. This function will + * check for the events specified in the 'flags' parameter, and + * it will return a mask indicating which operations can be + * performed. This function won't block, regardless of the + * mode (blocking|nonblocking) of the socket. + */ +GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) +{ + assert(socket != NULL); - return FD_ISSET(socket->m_fd, &read_set); + return (flags & socket->m_detected); } /* Flags */ /* GSocket_SetNonBlocking: - * Sets the socket in non-blocking mode. This is useful if + * Sets the socket to non-blocking mode. This is useful if * we don't want to wait. */ void GSocket_SetNonBlocking(GSocket *socket, bool non_block) @@ -668,13 +719,15 @@ void GSocket_SetNonBlocking(GSocket *socket, bool non_block) } /* GSocket_SetTimeout: + * Sets the timeout for blocking calls. Time is + * expressed in milliseconds. */ -void GSocket_SetTimeout(GSocket *socket, unsigned long millisecs) +void GSocket_SetTimeout(GSocket *socket, unsigned long millis) { assert(socket != NULL); - socket->m_timeout.tv_sec = (millisecs / 1000); - socket->m_timeout.tv_usec = (millisecs % 1000) * 1000; + socket->m_timeout.tv_sec = (millis / 1000); + socket->m_timeout.tv_usec = (millis % 1000) * 1000; } /* GSocket_GetError: @@ -706,14 +759,14 @@ GSocketError GSocket_GetError(GSocket *socket) */ /* GSocket_SetCallback: - * Enables the callbacks specified by 'event'. Note that 'event' + * Enables the callbacks specified by 'flags'. Note that 'flags' * may be a combination of flags OR'ed toghether, so the same * callback function can be made to accept different events. * The callback function must have the following prototype: * * void function(GSocket *socket, GSocketEvent event, char *cdata) */ -void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event, +void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags, GSocketCallback callback, char *cdata) { int count; @@ -722,22 +775,19 @@ void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event, for (count = 0; count < GSOCK_MAX_EVENT; count++) { - /* We test each flag and enable the corresponding events */ - if ((event & (1 << count)) != 0) + if ((flags & (1 << count)) != 0) { socket->m_cbacks[count] = callback; socket->m_data[count] = cdata; } } - - _GSocket_Configure_Callbacks(socket); } /* GSocket_UnsetCallback: - * Disables all callbacks specified by 'event', which may be a + * Disables all callbacks specified by 'flags', which may be a * combination of flags OR'ed toghether. */ -void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event) +void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags) { int count = 0; @@ -745,41 +795,47 @@ void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event) for (count = 0; count < GSOCK_MAX_EVENT; count++) { - /* We test each flag and disable the corresponding events */ - if ((event & (1 << count)) != 0) + if ((flags & (1 << count)) != 0) { socket->m_cbacks[count] = NULL; + socket->m_data[count] = NULL; } } - - _GSocket_Configure_Callbacks(socket); } /* Internals */ -void _GSocket_Configure_Callbacks(GSocket *socket) +/* _GSocket_Enable_Events: + * We enable all event notifications here (we need to be notified + * of all events for internal processing) but we will only notify + * users when an appropiate callback function has been installed. + */ +void _GSocket_Enable_Events(GSocket *socket) { - long mask = 0; - int count; + assert (socket != NULL); - for (count = 0; count < GSOCK_MAX_EVENT; count++) + if (socket->m_fd != INVALID_SOCKET) { - if (socket->m_cbacks[count] != NULL) - { - switch (count) - { - case GSOCK_INPUT: mask |= FD_READ; break; - case GSOCK_OUTPUT: mask |= FD_WRITE; break; - case GSOCK_CONNECTION: mask |= (FD_ACCEPT | FD_CONNECT); break; - case GSOCK_LOST: mask |= FD_CLOSE; break; - } - } + WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, + FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE); } +} + +/* _GSocket_Disable_Events: + * Disable event notifications (when shutdowning the socket) + */ +void _GSocket_Disable_Events(GSocket *socket) +{ + assert (socket != NULL); - WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, mask); + if (socket->m_fd != INVALID_SOCKET) + { + WSAAsyncSelect(socket->m_fd, hWin, socket->m_msgnumber, 0); + } } + LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, @@ -788,6 +844,7 @@ LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, GSocket *socket; GSocketEvent event; GSocketCallback cback; + char *data; if (uMsg >= WM_USER && uMsg <= (WM_USER + MAXSOCKETS - 1)) { @@ -795,6 +852,7 @@ LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, socket = socketList[(uMsg - WM_USER)]; event = -1; cback = NULL; + data = NULL; /* Check that the socket still exists (it has not been * destroyed) and for safety, check that the m_fd field @@ -807,12 +865,27 @@ LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, case FD_READ: event = GSOCK_INPUT; break; case FD_WRITE: event = GSOCK_OUTPUT; break; case FD_ACCEPT: event = GSOCK_CONNECTION; break; - case FD_CONNECT: event = GSOCK_CONNECTION; break; + case FD_CONNECT: + { + if (WSAGETSELECTERROR(lParam) != 0) + event = GSOCK_LOST; + else + event = GSOCK_CONNECTION; + break; + } case FD_CLOSE: event = GSOCK_LOST; break; } if (event != -1) + { cback = socket->m_cbacks[event]; + data = socket->m_data[event]; + + if (event == GSOCK_LOST) + socket->m_detected = GSOCK_LOST_FLAG; + else + socket->m_detected |= (1 << event); + } } /* OK, we can now leave the critical section because we have @@ -822,7 +895,7 @@ LRESULT CALLBACK _GSocket_Internal_WinProc(HWND hWnd, LeaveCriticalSection(&critical); if (cback != NULL) - (cback)(socket, event, socket->m_data[event]); + (cback)(socket, event, data); return (LRESULT) 0; } @@ -839,7 +912,7 @@ GSocketError _GSocket_Input_Timeout(GSocket *socket) { fd_set readfds; - if (socket->m_non_blocking == FALSE) + if (!socket->m_non_blocking) { FD_ZERO(&readfds); FD_SET(socket->m_fd, &readfds); @@ -860,7 +933,7 @@ GSocketError _GSocket_Output_Timeout(GSocket *socket) { fd_set writefds; - if (socket->m_non_blocking == FALSE) + if (!socket->m_non_blocking) { FD_ZERO(&writefds); FD_SET(socket->m_fd, &writefds); @@ -875,42 +948,19 @@ GSocketError _GSocket_Output_Timeout(GSocket *socket) int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size) { - int ret; - - ret = recv(socket->m_fd, buffer, size, 0); - - if (ret == SOCKET_ERROR) - { - if (WSAGetLastError() != WSAEWOULDBLOCK) - socket->m_error = GSOCK_IOERR; - else - socket->m_error = GSOCK_WOULDBLOCK; - - return -1; - } - - return ret; + return recv(socket->m_fd, buffer, size, 0); } int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) { struct sockaddr from; - SOCKLEN_T fromlen; + SOCKLEN_T fromlen = sizeof(from); int ret; - fromlen = sizeof(from); - ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen); if (ret == SOCKET_ERROR) - { - if (WSAGetLastError() != WSAEWOULDBLOCK) - socket->m_error = GSOCK_IOERR; - else - socket->m_error = GSOCK_WOULDBLOCK; - - return -1; - } + return SOCKET_ERROR; /* Translate a system address into a GSocket address */ if (!socket->m_peer) @@ -924,8 +974,8 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) } if (_GAddress_translate_from(socket->m_peer, &from, fromlen) != GSOCK_NOERROR) { - socket->m_error = GSOCK_MEMERR; /* TODO: bug in Unix GSocket! */ - GAddress_destroy(socket->m_peer); /* TODO: bug in Unix GSocket! */ + socket->m_error = GSOCK_MEMERR; + GAddress_destroy(socket->m_peer); return -1; } @@ -934,20 +984,7 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size) { - int ret; - - ret = send(socket->m_fd, buffer, size, 0); - - if (ret == SOCKET_ERROR) - { - if (WSAGetLastError() != WSAEWOULDBLOCK) - socket->m_error = GSOCK_IOERR; - else - socket->m_error = GSOCK_WOULDBLOCK; - - return -1; - } - return ret; + return send(socket->m_fd, buffer, size, 0); } int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size) @@ -972,15 +1009,6 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size) /* Frees memory allocated by _GAddress_translate_to */ free(addr); - if (ret == SOCKET_ERROR) - { - if (WSAGetLastError() != WSAEWOULDBLOCK) - socket->m_error = GSOCK_IOERR; - else - socket->m_error = GSOCK_WOULDBLOCK; - - return -1; - } return ret; } @@ -1164,7 +1192,7 @@ GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname) addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr); addr->s_addr = inet_addr(hostname); - + /* If it is a numeric host name, convert it now */ if (addr->s_addr == INADDR_NONE) { @@ -1211,7 +1239,7 @@ GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port, address->m_error = GSOCK_INVPORT; return GSOCK_INVOP; } - + se = getservbyname(port, protocol); if (!se) { @@ -1241,7 +1269,7 @@ GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port) assert(address != NULL); CHECK_ADDRESS(address, INET, GSOCK_INVADDR); - + addr = (struct sockaddr_in *)address->m_addr; addr->sin_port = htons(port); @@ -1254,7 +1282,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, GSOCK_INVADDR); addr = (struct sockaddr_in *)address->m_addr; @@ -1276,8 +1304,8 @@ unsigned long GAddress_INET_GetHostAddress(GAddress *address) { struct sockaddr_in *addr; - assert(address != NULL); - CHECK_ADDRESS(address, INET, 0); + assert(address != NULL); + CHECK_ADDRESS(address, INET, 0); addr = (struct sockaddr_in *)address->m_addr; @@ -1288,8 +1316,8 @@ unsigned short GAddress_INET_GetPort(GAddress *address) { struct sockaddr_in *addr; - assert(address != NULL); - CHECK_ADDRESS(address, INET, 0); + assert(address != NULL); + CHECK_ADDRESS(address, INET, 0); addr = (struct sockaddr_in *)address->m_addr; return ntohs(addr->sin_port); @@ -1322,10 +1350,15 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf) return GSOCK_INVADDR; } +#else /* !wxUSE_SOCKETS */ -#endif /* !defined(__WXMSW__) || (defined(__WXMSW__) && wxUSE_SOCKETS) */ - +/* + * translation unit shouldn't be empty, so include this typedef to make the + * compiler (VC++ 6.0, for example) happy + */ +typedef (*wxDummy)(); +#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */ /* Diferencias con la version Unix: * - El descriptor es SOCKET y no int @@ -1335,9 +1368,7 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf) * - inet_addr en lugar de inet_aton * - Codigo de inicializacion y terminacion para inicializar y * terminar WinSocket y para la ventana interna. - * - SetTimeout en la version MSW simplemente guarda el valor en - * socket.m_timeout, por tanto no hay necesidad de llamar a - * SetTimeout cada vez que se crea realmente un socket (no - * un gsocket). - * - Lo mismo para SetNonBlocking. + * - SetTimeout, SetNonBlocking y la implementacion de los + * timeouts eran bastante diferentes, pero ahora se han + * hecho en la version Unix igual que en esta. */