X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/38bb138f09688c1575766aafdbf296dfeeee0d7d..095b80e2b5120d4c476a834b2017c355fa9afef0:/src/unix/gsocket.c diff --git a/src/unix/gsocket.c b/src/unix/gsocket.c index 36a2ca622f..3f1c19c862 100644 --- a/src/unix/gsocket.c +++ b/src/unix/gsocket.c @@ -3,8 +3,8 @@ * Name: gsocket.c * Authors: Guilhem Lavaux, * Guillermo Rodriguez Garcia (maintainer) - * Purpose: GSocket main Unix file - * Licence: The wxWindows licence + * Purpose: GSocket main Unix and OS/2 file + * Licence: The wxWidgets licence * CVSID: $Id$ * ------------------------------------------------------------------------- */ @@ -17,10 +17,23 @@ #include "wx/setup.h" #endif +#if defined(__VISAGECPP__) +/* Seems to be needed by Visual Age C++, though I don't see how it manages + to not break on including a C++ header into a plain C source file */ +#include "wx/defs.h" +#define BSD_SELECT /* use Berkley Sockets select */ +#endif + #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) #include #include +#ifdef __VISAGECPP__ +#include +#include +#include +#include +#endif #include #include @@ -37,12 +50,42 @@ struct sockaddr_un #include #endif +#ifndef __VISAGECPP__ #include #include #include #include #include #include +#else +#include +# if __IBMCPP__ < 400 +#include +#include +#include +#include +#include + +#define EBADF SOCEBADF + +# ifdef min +# undef min +# endif +# else +#include +#include +#include + +#define close(a) soclose(a) +#define select(a,b,c,d,e) bsdselect(a,b,c,d,e) +int _System bsdselect(int, + struct fd_set *, + struct fd_set *, + struct fd_set *, + struct timeval *); +int _System soclose(int); +# endif +#endif #include #include #include @@ -218,7 +261,10 @@ GSocket *GSocket_new(void) void GSocket_close(GSocket *socket) { _GSocket_Disable_Events(socket); + /* gsockosx.c calls CFSocketInvalidate which closes the socket for us */ +#if !(defined(__DARWIN__) && (defined(__WXMAC__) || defined(__WXCOCOA__))) close(socket->m_fd); +#endif socket->m_fd = INVALID_SOCKET; } @@ -430,10 +476,18 @@ GSocketError GSocket_SetServer(GSocket *sck) sck->m_error = GSOCK_IOERR; return GSOCK_IOERR; } - +#if defined(__EMX__) || defined(__VISAGECPP__) + ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg)); +#else ioctl(sck->m_fd, FIONBIO, &arg); +#endif _GSocket_Enable_Events(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)); + /* Bind to the local address, * retrieve the actual address bound, * and listen up to 5 connections. @@ -535,8 +589,11 @@ GSocket *GSocket_WaitConnection(GSocket *socket) socket->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 _GSocket_Enable_Events(connection); return connection; @@ -604,8 +661,11 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) sck->m_error = GSOCK_IOERR; return GSOCK_IOERR; } - +#if defined(__EMX__) || defined(__VISAGECPP__) + ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg)); +#else ioctl(sck->m_fd, FIONBIO, &arg); +#endif _GSocket_Enable_Events(sck); /* Connect it to the peer address, with a timeout (see below) */ @@ -708,8 +768,11 @@ GSocketError GSocket_SetNonOriented(GSocket *sck) sck->m_error = GSOCK_IOERR; return GSOCK_IOERR; } - +#if defined(__EMX__) || defined(__VISAGECPP__) + ioctl(sck->m_fd, FIONBIO, (char*)&arg, sizeof(arg)); +#else ioctl(sck->m_fd, FIONBIO, &arg); +#endif _GSocket_Enable_Events(sck); /* Bind to the local address, @@ -737,24 +800,26 @@ int GSocket_Read(GSocket *socket, char *buffer, int size) assert(socket != NULL); - /* Reenable INPUT events */ - _GSocket_Enable(socket, GSOCK_INPUT); - if (socket->m_fd == INVALID_SOCKET || socket->m_server) { socket->m_error = GSOCK_INVSOCK; return -1; } + /* 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) - return -1; - - /* Read the data */ - if (socket->m_stream) - ret = _GSocket_Recv_Stream(socket, buffer, size); - else - ret = _GSocket_Recv_Dgram(socket, buffer, size); + /* We no longer return here immediately, otherwise socket events would not be re-enabled! */ + ret = -1; + else { + /* Read the data */ + if (socket->m_stream) + ret = _GSocket_Recv_Stream(socket, buffer, size); + else + ret = _GSocket_Recv_Dgram(socket, buffer, size); + } if (ret == -1) { @@ -764,6 +829,9 @@ int GSocket_Read(GSocket *socket, char *buffer, int size) socket->m_error = GSOCK_IOERR; } + /* Enable events again now that we are done processing */ + _GSocket_Enable(socket, GSOCK_INPUT); + return ret; } @@ -842,17 +910,18 @@ GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags) fd_set exceptfds; struct timeval tv; - /* Do not use a static struct, Linux can garble it */ - tv.tv_sec = 0; - tv.tv_usec = 0; - assert(socket != NULL); + /* Do not use a static struct, Linux can garble it */ + tv.tv_sec = socket->m_timeout / 1000; + tv.tv_usec = (socket->m_timeout % 1000) / 1000; + FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(socket->m_fd, &readfds); - FD_SET(socket->m_fd, &writefds); + if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG) + FD_SET(socket->m_fd, &writefds); FD_SET(socket->m_fd, &exceptfds); /* Check 'sticky' CONNECTION flag first */ @@ -1216,9 +1285,13 @@ int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size) { int ret; +#ifndef __VISAGECPP__ MASK_SIGNAL(); ret = send(socket->m_fd, buffer, size, 0); UNMASK_SIGNAL(); +#else + ret = send(socket->m_fd, (char *)buffer, size, 0); +#endif return ret; } @@ -1242,9 +1315,13 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size) return -1; } +#ifndef __VISAGECPP__ MASK_SIGNAL(); ret = sendto(socket->m_fd, buffer, size, 0, addr, len); UNMASK_SIGNAL(); +#else + ret = sendto(socket->m_fd, (char *)buffer, size, 0, addr, len); +#endif /* Frees memory allocated from _GAddress_translate_to */ free(addr); @@ -1536,7 +1613,10 @@ GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname) { #else /* Use gethostbyname by default */ - if (1) +#ifndef __WXMAC__ + int val = 1; /* VA doesn't like constants in conditional expressions */ + if (val) +#endif { #endif struct in_addr *array_addr; @@ -1570,7 +1650,7 @@ GSocketError GAddress_INET_SetHostAddress(GAddress *address, CHECK_ADDRESS(address, INET); addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr); - addr->s_addr = hostaddr; + addr->s_addr = htonl(hostaddr); return GSOCK_NOERROR; } @@ -1661,7 +1741,7 @@ unsigned long GAddress_INET_GetHostAddress(GAddress *address) addr = (struct sockaddr_in *)address->m_addr; - return addr->sin_addr.s_addr; + return ntohl(addr->sin_addr.s_addr); } unsigned short GAddress_INET_GetPort(GAddress *address) @@ -1681,6 +1761,7 @@ unsigned short GAddress_INET_GetPort(GAddress *address) * ------------------------------------------------------------------------- */ +#ifndef __VISAGECPP__ GSocketError _GAddress_Init_UNIX(GAddress *address) { address->m_len = sizeof(struct sockaddr_un); @@ -1729,6 +1810,6 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf) return GSOCK_NOERROR; } - +#endif /* !defined(__VISAGECPP__) */ #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */