summaryrefslogtreecommitdiff
path: root/sal/osl/w32/socket.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl/w32/socket.cxx')
-rw-r--r--sal/osl/w32/socket.cxx2190
1 files changed, 2190 insertions, 0 deletions
diff --git a/sal/osl/w32/socket.cxx b/sal/osl/w32/socket.cxx
new file mode 100644
index 000000000000..191c31fb986a
--- /dev/null
+++ b/sal/osl/w32/socket.cxx
@@ -0,0 +1,2190 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sal.hxx"
+
+#include "system.h"
+
+#include <osl/socket.h>
+#include <osl/diagnose.h>
+#include <rtl/alloc.h>
+
+#include "sockimpl.h"
+
+extern "C" {
+
+/* defines for shutdown */
+#ifdef GCC
+# define SD_RECEIVE 0
+# define SD_SEND 1
+# define SD_BOTH 2
+#endif
+
+/*
+ oslSocketAddr is a pointer to a Berkeley struct sockaddr.
+ I refrained from using sockaddr_in because of possible further
+ extensions of this socket-interface (IP-NG?).
+ The intention was to hide all Berkeley data-structures from
+ direct access past the osl-interface.
+
+ The current implementation is internet (IP) centered. All
+ the constructor-functions (osl_create...) take parameters
+ that will probably make sense only in the IP-environment
+ (e.g. because of using the dotted-Addr-format).
+
+ If the interface will be extended to host other protocol-
+ families, I expect no externally visible changes in the
+ existing functions. You'll probably need only new
+ constructor-functions who take the different Addr
+ formats into consideration (maybe a long dotted Addr
+ or whatever).
+*/
+
+/*
+ _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr
+ are the same! I don't like it very much but see no other easy way to
+ conceal the struct sockaddr from the eyes of the user.
+*/
+
+#define OSL_INVALID_SOCKET INVALID_SOCKET /* WIN32 */
+#define OSL_SOCKET_ERROR SOCKET_ERROR /* WIN32 */
+
+/*****************************************************************************/
+/* enum oslAddrFamily */
+/*****************************************************************************/
+
+/* map */
+static DWORD FamilyMap[]= {
+ AF_INET, /* osl_Socket_FamilyInet */
+ AF_IPX, /* osl_Socket_FamilyIpx */
+ 0 /* osl_Socket_FamilyInvalid */
+};
+
+/* reverse map */
+static oslAddrFamily osl_AddrFamilyFromNative(DWORD nativeType)
+{
+ oslAddrFamily i= (oslAddrFamily) 0;
+ while(i != osl_Socket_FamilyInvalid)
+ {
+ if(FamilyMap[i] == nativeType)
+ return i;
+ i = (oslAddrFamily) ( (int)i + 1);
+ }
+ return i;
+}
+
+/* macros */
+#define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
+#define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
+
+/*****************************************************************************/
+/* enum oslProtocol */
+/*****************************************************************************/
+
+/* map */
+static DWORD ProtocolMap[]= {
+ 0, /* osl_Socket_FamilyInet */
+ NSPROTO_IPX, /* osl_Socket_FamilyIpx */
+ NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
+ NSPROTO_SPXII, /* osl_Socket_ProtocolSpx_ii */
+ 0 /* osl_Socket_ProtocolInvalid */
+};
+
+/* macros */
+#define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
+#define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
+
+/*****************************************************************************/
+/* enum oslSocketType */
+/*****************************************************************************/
+
+/* map */
+static DWORD TypeMap[]= {
+ SOCK_STREAM, /* osl_Socket_TypeStream */
+ SOCK_DGRAM, /* osl_Socket_TypeDgram */
+ SOCK_RAW, /* osl_Socket_TypeRaw */
+ SOCK_RDM, /* osl_Socket_TypeRdm */
+ SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
+ 0 /* osl_Socket_TypeInvalid */
+};
+
+/* reverse map */
+static oslSocketType osl_SocketTypeFromNative(DWORD nativeType)
+{
+ oslSocketType i= (oslSocketType)0;
+ while(i != osl_Socket_TypeInvalid)
+ {
+ if(TypeMap[i] == nativeType)
+ return i;
+ i = (oslSocketType)((int)i+1);
+ }
+ return i;
+}
+
+/* macros */
+#define TYPE_TO_NATIVE(x) TypeMap[x]
+#define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
+
+/*****************************************************************************/
+/* enum oslSocketOption */
+/*****************************************************************************/
+
+/* map */
+static DWORD OptionMap[]= {
+ SO_DEBUG, /* osl_Socket_OptionDebug */
+ SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
+ SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
+ SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
+ SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
+ SO_BROADCAST, /* osl_Socket_OptionBroadcast */
+ SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
+ SO_LINGER, /* osl_Socket_OptionLinger */
+ SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
+ SO_SNDBUF, /* osl_Socket_OptionSndBuf */
+ SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
+ SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
+ SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
+ SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
+ SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
+ SO_ERROR, /* osl_Socket_OptionError */
+ SO_TYPE, /* osl_Socket_OptionType */
+ TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
+ 0 /* osl_Socket_OptionInvalid */
+};
+
+/* macros */
+#define OPTION_TO_NATIVE(x) OptionMap[x]
+#define OPTION_FROM_NATIVE(y) osl_SocketOptionFromNative(y)
+
+/*****************************************************************************/
+/* enum oslSocketOptionLevel */
+/*****************************************************************************/
+
+static DWORD OptionLevelMap[]= {
+ SOL_SOCKET, /* osl_Socket_LevelSocket */
+ IPPROTO_TCP, /* osl_Socket_LevelTcp */
+ 0 /* osl_invalid_SocketLevel */
+};
+
+/* macros */
+#define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
+#define OPTION_LEVEL_FROM_NATIVE(y) osl_SocketOptionLevelFromNative(y)
+
+/*****************************************************************************/
+/* enum oslSocketMsgFlag */
+/*****************************************************************************/
+
+static DWORD SocketMsgFlagMap[]= {
+ 0, /* osl_Socket_MsgNormal */
+ MSG_OOB, /* osl_Socket_MsgOOB */
+ MSG_PEEK, /* osl_Socket_MsgPeek */
+ MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
+ MSG_MAXIOVLEN /* osl_Socket_MsgMaxIOVLen */
+};
+
+/* macros */
+#define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
+#define MSG_FLAG_FROM_NATIVE(y) osl_SocketMsgFlagFromNative(y)
+
+/*****************************************************************************/
+/* enum oslSocketDirection */
+/*****************************************************************************/
+
+static DWORD SocketDirection[]= {
+ SD_RECEIVE, /* osl_Socket_DirRead */
+ SD_SEND, /* osl_Socket_DirWrite */
+ SD_BOTH /* osl_Socket_DirReadwrite */
+};
+
+/* macros */
+#define DIRECTION_TO_NATIVE(x) SocketDirection[x]
+#define DIRECTION_FROM_NATIVE(y) osl_SocketDirectionFromNative(y)
+
+/*****************************************************************************/
+/* enum oslSocketError */
+/*****************************************************************************/
+
+static int SocketError[]= {
+
+ 0, /* no error */
+ WSAENOTSOCK, /* Socket operation on non-socket */
+ WSAEDESTADDRREQ, /* Destination address required */
+ WSAEMSGSIZE, /* Message too long */
+ WSAEPROTOTYPE, /* Protocol wrong type for socket */
+ WSAENOPROTOOPT, /* Protocol not available */
+ WSAEPROTONOSUPPORT, /* Protocol not supported */
+ WSAESOCKTNOSUPPORT, /* Socket type not supported */
+ WSAEOPNOTSUPP, /* Operation not supported on socket */
+ WSAEPFNOSUPPORT, /* Protocol family not supported */
+ WSAEAFNOSUPPORT, /* Address family not supported by */
+ /* protocol family */
+ WSAEADDRINUSE, /* Address already in use */
+ WSAEADDRNOTAVAIL, /* Can't assign requested address */
+ WSAENETDOWN, /* Network is down */
+ WSAENETUNREACH, /* Network is unreachable */
+ WSAENETRESET, /* Network dropped connection because */
+ /* of reset */
+ WSAECONNABORTED, /* Software caused connection abort */
+ WSAECONNRESET, /* Connection reset by peer */
+ WSAENOBUFS, /* No buffer space available */
+ WSAEISCONN, /* Socket is already connected */
+ WSAENOTCONN, /* Socket is not connected */
+ WSAESHUTDOWN, /* Can't send after socket shutdown */
+ WSAETOOMANYREFS, /* Too many references: can't splice */
+ WSAETIMEDOUT, /* Connection timed out */
+ WSAECONNREFUSED, /* Connection refused */
+ WSAEHOSTDOWN, /* Host is down */
+ WSAEHOSTUNREACH, /* No route to host */
+ WSAEWOULDBLOCK, /* call would block on non-blocking socket */
+ WSAEALREADY, /* operation already in progress */
+ WSAEINPROGRESS /* operation now in progress */
+};
+
+/* reverse map */
+static oslSocketError osl_SocketErrorFromNative(int nativeType)
+{
+ oslSocketError i= (oslSocketError)0;
+
+ while(i != osl_Socket_E_InvalidError)
+ {
+ if(SocketError[i] == nativeType)
+ return i;
+
+ i = (oslSocketError)( (int) i + 1);
+ }
+ return i;
+}
+
+/* macros */
+#define ERROR_TO_NATIVE(x) SocketError[x]
+#define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
+
+/*****************************************************************************/
+/* oslSocketDialupImpl */
+/*****************************************************************************/
+static oslSocketDialupImpl *pDialupImpl = NULL;
+
+#if 0 /* INTERNAL DEBUG ONLY */
+BOOL WINAPI __osl_autodial_Impl (DWORD dwFlags, DWORD dwReserved)
+{
+ return 0;
+}
+
+BOOL WINAPI __osl_autodialHangup_Impl (DWORD dwReserved)
+{
+ return 1;
+}
+
+BOOL WINAPI __osl_getConnectedState_Impl (LPDWORD lpdwFlags, DWORD dwReserved)
+{
+ if (lpdwFlags)
+ *lpdwFlags = 0;
+ return 0;
+}
+#endif /* INTERNAL DEBUG ONLY */
+
+/*
+ * __osl_createSocketDialupImpl.
+ */
+static oslSocketDialupImpl* __osl_createSocketDialupImpl (void)
+{
+ oslSocketDialupImpl *pImpl;
+ pImpl = (oslSocketDialupImpl*)rtl_allocateZeroMemory( sizeof (oslSocketDialupImpl));
+
+ InitializeCriticalSection (&pImpl->m_hMutex);
+
+ return (pImpl);
+}
+
+/*
+ * __osl_initSocketDialupImpl.
+ */
+static void __osl_initSocketDialupImpl (oslSocketDialupImpl *pImpl)
+{
+#ifdef SOCKET_USE_AUTODIAL
+ if (pImpl)
+ {
+ HINSTANCE hModule;
+
+ EnterCriticalSection (&pImpl->m_hMutex);
+
+ hModule = LoadLibrary (INTERNET_MODULE_NAME);
+ if (!(hModule <= (HINSTANCE)HINSTANCE_ERROR))
+ {
+ pImpl->m_pfnAttemptConnect = (INTERNETATTEMPTCONNECT)
+ (GetProcAddress (hModule, "InternetAttemptConnect"));
+ pImpl->m_pfnAutodial = (INTERNETAUTODIAL)
+ (GetProcAddress (hModule, "InternetAutodial"));
+ pImpl->m_pfnAutodialHangup = (INTERNETAUTODIALHANGUP)
+ (GetProcAddress (hModule, "InternetAutodialHangup"));
+ pImpl->m_pfnGetConnectedState = (INTERNETGETCONNECTEDSTATE)
+ (GetProcAddress (hModule, "InternetGetConnectedState"));
+ pImpl->m_hModule = hModule;
+ }
+
+ LeaveCriticalSection (&pImpl->m_hMutex);
+ }
+#else
+ pImpl = pImpl; /* avoid warnings */
+#endif
+}
+
+/*
+ * __osl_destroySocketDialupImpl.
+ */
+static void __osl_destroySocketDialupImpl (oslSocketDialupImpl *pImpl)
+{
+ if (pImpl)
+ {
+ EnterCriticalSection (&pImpl->m_hMutex);
+
+ if (pImpl->m_dwFlags & INTERNET_CONNECTION_HANGUP)
+ {
+ if (pImpl->m_pfnAutodialHangup)
+ {
+ (pImpl->m_pfnAutodialHangup)(0);
+ pImpl->m_dwFlags &= ~INTERNET_CONNECTION_HANGUP;
+ }
+ }
+
+ if (pImpl->m_hModule)
+ FreeLibrary (pImpl->m_hModule);
+
+ LeaveCriticalSection (&pImpl->m_hMutex);
+ DeleteCriticalSection (&pImpl->m_hMutex);
+
+ rtl_freeMemory (pImpl);
+ }
+}
+
+/*
+ * __osl_querySocketDialupImpl.
+ */
+static sal_Bool __osl_querySocketDialupImpl (void)
+{
+ sal_Bool result;
+
+ if (pDialupImpl == NULL)
+ {
+ pDialupImpl = __osl_createSocketDialupImpl();
+ __osl_initSocketDialupImpl (pDialupImpl);
+ }
+
+ EnterCriticalSection (&pDialupImpl->m_hMutex);
+
+ result = sal_True;
+ if (pDialupImpl->m_pfnGetConnectedState)
+ {
+ DWORD dwFlags = 0;
+
+ result = (sal_Bool)(pDialupImpl->m_pfnGetConnectedState)(&dwFlags, 0);
+ pDialupImpl->m_dwFlags |= dwFlags;
+ }
+
+ LeaveCriticalSection (&pDialupImpl->m_hMutex);
+ return (result);
+}
+
+/*
+ * __osl_attemptSocketDialupImpl.
+ */
+static sal_Bool __osl_attemptSocketDialupImpl (void)
+{
+ sal_Bool result;
+
+ if (pDialupImpl == NULL)
+ {
+ pDialupImpl = __osl_createSocketDialupImpl();
+ __osl_initSocketDialupImpl (pDialupImpl);
+ }
+
+ EnterCriticalSection (&pDialupImpl->m_hMutex);
+
+ result = __osl_querySocketDialupImpl();
+ if (!result)
+ {
+ result = sal_True;
+ if (pDialupImpl->m_pfnAutodial)
+ {
+ result = (sal_Bool)(pDialupImpl->m_pfnAutodial)(0, 0);
+ if (result)
+ pDialupImpl->m_dwFlags |= INTERNET_CONNECTION_HANGUP;
+ else
+ WSASetLastError (WSAENETDOWN);
+ }
+ }
+
+ LeaveCriticalSection (&pDialupImpl->m_hMutex);
+ return (result);
+}
+
+/*****************************************************************************/
+/* oslSocketImpl */
+/*****************************************************************************/
+static sal_uInt32 g_nSocketImpl = 0;
+
+#if OSL_DEBUG_LEVEL > 1
+static sal_uInt32 g_nSocketAddr = 0;
+struct LeakWarning
+{
+ ~LeakWarning()
+ {
+ if( g_nSocketImpl )
+ OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl );
+ if( g_nSocketAddr )
+ OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr );
+ }
+};
+LeakWarning socketWarning;
+#endif
+
+/*
+ * __osl_createSocketImpl.
+ */
+oslSocket __osl_createSocketImpl(SOCKET Socket)
+{
+ oslSocket pSockImpl = (oslSocket) rtl_allocateZeroMemory( sizeof(struct oslSocketImpl));
+ pSockImpl->m_Socket = Socket;
+ pSockImpl->m_nRefCount = 1;
+
+ g_nSocketImpl++;
+
+ return (pSockImpl);
+}
+
+/*
+ * __osl_destroySocketImpl.
+ */
+void __osl_destroySocketImpl(oslSocketImpl *pImpl)
+{
+ if (pImpl)
+ {
+ if (--g_nSocketImpl == 0)
+ {
+ __osl_destroySocketDialupImpl (pDialupImpl);
+ pDialupImpl = NULL;
+ }
+ rtl_freeMemory (pImpl);
+ }
+}
+/*****************************************************************************/
+static oslSocketAddr __osl_createSocketAddr( )
+{
+ oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
+ pAddr->m_nRefCount = 1;
+#if OSL_DEBUG_LEVEL > 1
+ g_nSocketAddr ++;
+#endif
+ return pAddr;
+}
+
+static oslSocketAddr __osl_createSocketAddrWithFamily(
+ oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
+{
+ OSL_ASSERT( family == osl_Socket_FamilyInet );
+
+ oslSocketAddr pAddr = __osl_createSocketAddr();
+ switch( family )
+ {
+ case osl_Socket_FamilyInet:
+ {
+ struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
+
+ pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
+ pInetAddr->sin_addr.s_addr = nAddr;
+ pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
+ break;
+ }
+ default:
+ pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
+ }
+ return pAddr;
+}
+
+static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
+{
+ oslSocketAddr pAddr = __osl_createSocketAddr();
+ memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( sockaddr ) );
+ return pAddr;
+}
+
+static void __osl_destroySocketAddr( oslSocketAddr addr )
+{
+#if OSL_DEBUG_LEVEL > 1
+ g_nSocketAddr --;
+#endif
+ rtl_freeMemory( addr );
+}
+/*****************************************************************************/
+/* osl_createEmptySocketAddr */
+/*****************************************************************************/
+oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
+{
+ oslSocketAddr pAddr = 0;
+
+ /* is it an internet-Addr? */
+ if (Family == osl_Socket_FamilyInet)
+ {
+ pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
+ }
+ else
+ {
+ pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
+ }
+
+ return pAddr;
+}
+
+/*****************************************************************************/
+/* osl_copySocketAddr */
+/*****************************************************************************/
+// @deprecated, to be removed
+oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
+{
+ oslSocketAddr pCopy = 0;
+ if (Addr)
+ {
+ pCopy = __osl_createSocketAddr();
+
+ if (pCopy)
+ memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
+ }
+ return pCopy;
+}
+
+/*****************************************************************************/
+/* osl_isEqualSocketAddr */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_isEqualSocketAddr(oslSocketAddr Addr1, oslSocketAddr Addr2)
+{
+ struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
+ struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
+
+ OSL_ASSERT(pAddr1);
+ OSL_ASSERT(pAddr2);
+
+ if (pAddr1->sa_family == pAddr2->sa_family)
+ {
+ switch (pAddr1->sa_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
+ struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
+
+ if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
+ (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
+ (pInetAddr1->sin_port == pInetAddr2->sin_port))
+ return (sal_True);
+ }
+
+ default:
+ {
+ return (memcmp(pAddr1, Addr2, sizeof(struct sockaddr)) == 0);
+ }
+ }
+ }
+
+ return (sal_False);
+}
+
+/*****************************************************************************/
+/* osl_createInetBroadcastAddr */
+/*****************************************************************************/
+oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
+ rtl_uString *strDottedAddr,
+ sal_Int32 Port)
+{
+ sal_uInt32 nAddr = OSL_INADDR_NONE;
+
+ if (strDottedAddr && strDottedAddr->length)
+ {
+ /* Dotted host address for limited broadcast */
+ rtl_String *pDottedAddr = NULL;
+
+ rtl_uString2String (
+ &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ nAddr = inet_addr (pDottedAddr->buffer);
+ rtl_string_release (pDottedAddr);
+ }
+
+ if (nAddr != OSL_INADDR_NONE)
+ {
+ /* Limited broadcast */
+ nAddr = ntohl(nAddr);
+ if (IN_CLASSA(nAddr))
+ {
+ nAddr &= IN_CLASSA_NET;
+ nAddr |= IN_CLASSA_HOST;
+ }
+ else if (IN_CLASSB(nAddr))
+ {
+ nAddr &= IN_CLASSB_NET;
+ nAddr |= IN_CLASSB_HOST;
+ }
+ else if (IN_CLASSC(nAddr))
+ {
+ nAddr &= IN_CLASSC_NET;
+ nAddr |= IN_CLASSC_HOST;
+ }
+ else
+ {
+ /* No broadcast in class D */
+ return ((oslSocketAddr)NULL);
+ }
+ nAddr = htonl(nAddr);
+ }
+
+ oslSocketAddr pAddr =
+ __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( (sal_uInt16) Port), nAddr );
+ return pAddr;
+}
+
+/*****************************************************************************/
+/* osl_createInetSocketAddr */
+/*****************************************************************************/
+oslSocketAddr SAL_CALL osl_createInetSocketAddr (
+ rtl_uString *strDottedAddr,
+ sal_Int32 Port)
+{
+ DWORD Addr;
+ rtl_String *pDottedAddr=NULL;
+
+ rtl_uString2String(
+ &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ Addr= inet_addr (pDottedAddr->buffer);
+ rtl_string_release (pDottedAddr);
+
+ oslSocketAddr pAddr = 0;
+ if(Addr != -1)
+ {
+ pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( (sal_uInt16)Port), Addr );
+ }
+ return pAddr;
+}
+
+oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
+{
+ OSL_ASSERT( pAddr );
+ OSL_ASSERT( pByteSeq );
+
+ oslSocketResult res = osl_Socket_Error;
+ if( pAddr && pByteSeq )
+ {
+ OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
+ OSL_ASSERT( pByteSeq->nElements == 4 );
+ struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
+ memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
+ res = osl_Socket_Ok;
+ }
+ return res;
+}
+
+/** Returns the addr field in the struct sockaddr. ppByteSeq is in network byteorder. *ppByteSeq may
+ either be 0 or contain a constructed sal_Sequence.
+ */
+oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
+{
+ OSL_ASSERT( pAddr );
+ OSL_ASSERT( ppByteSeq );
+
+ oslSocketResult res = osl_Socket_Error;
+ if( pAddr && ppByteSeq )
+ {
+ struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
+ rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
+ res = osl_Socket_Ok;
+ }
+ return res;
+}
+
+/*****************************************************************************/
+/* oslHostAddr */
+/*****************************************************************************/
+struct oslHostAddrImpl {
+ rtl_uString *pHostName;
+ oslSocketAddr pSockAddr;
+} ;
+
+static oslHostAddr __osl_hostentToHostAddr (const struct hostent *he)
+{
+ oslHostAddr pAddr= NULL;
+ oslSocketAddr pSocketAddr = 0;
+
+ rtl_uString *cn= NULL;
+
+ if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
+ return ((oslHostAddr)NULL);
+
+ rtl_string2UString(
+ &cn, he->h_name, strlen(he->h_name),
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+ OSL_ASSERT(cn != 0);
+
+ pSocketAddr = __osl_createSocketAddr();
+
+ if (pSocketAddr == NULL)
+ {
+ rtl_uString_release(cn);
+ return ((oslHostAddr)NULL);
+ }
+
+ pSocketAddr->m_sockaddr.sa_family = he->h_addrtype;
+ if (pSocketAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
+ {
+ struct sockaddr_in *sin= (struct sockaddr_in *)&(pSocketAddr->m_sockaddr);
+ memcpy (
+ &(sin->sin_addr.s_addr),
+ he->h_addr_list[0],
+ he->h_length);
+ }
+ else
+ {
+ /* unknown address family */
+ /* future extensions for new families might be implemented here */
+
+ OSL_TRACE("_osl_hostentToHostAddr(): unknown address family.\n");
+ OSL_ASSERT(sal_False);
+
+ __osl_destroySocketAddr( pSocketAddr );
+ rtl_uString_release(cn);
+ return ((oslHostAddr)NULL);
+ }
+
+ pAddr= (oslHostAddr )rtl_allocateMemory (sizeof (struct oslHostAddrImpl));
+
+ if (pAddr == NULL)
+ {
+ __osl_destroySocketAddr( pSocketAddr );
+ rtl_uString_release(cn);
+ return ((oslHostAddr)NULL);
+ }
+
+ pAddr->pHostName= cn;
+ pAddr->pSockAddr= pSocketAddr;
+
+ return pAddr;
+}
+
+/*****************************************************************************/
+/* osl_createHostAddr */
+/*****************************************************************************/
+oslHostAddr SAL_CALL osl_createHostAddr (
+ rtl_uString *strHostname,
+ const oslSocketAddr pSocketAddr)
+{
+ oslHostAddr pAddr;
+ rtl_uString *cn= NULL;
+
+ if ((strHostname == NULL) || (strHostname->length == 0) || (pSocketAddr == NULL))
+ return ((oslHostAddr)NULL);
+
+ rtl_uString_newFromString( &cn, strHostname);
+
+ if ( ! pSocketAddr )
+ {
+ rtl_uString_release(cn);
+ return ((oslHostAddr)NULL);
+ }
+
+ pAddr= (oslHostAddr)rtl_allocateMemory (sizeof (struct oslHostAddrImpl));
+
+ if (pAddr == NULL)
+ {
+ rtl_uString_release(cn);
+ return ((oslHostAddr)NULL);
+ }
+
+ pAddr->pHostName= cn;
+ pAddr->pSockAddr= osl_copySocketAddr( pSocketAddr );
+
+ return ((oslHostAddr)pAddr);
+}
+
+/*****************************************************************************/
+/* osl_createHostAddrByName */
+/*****************************************************************************/
+oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *strHostname)
+{
+ if ((strHostname == NULL) || (strHostname->length == 0))
+ return ((oslHostAddr)NULL);
+
+ if (__osl_attemptSocketDialupImpl())
+ {
+ struct hostent *he;
+ rtl_String *Hostname= NULL;
+
+ rtl_uString2String(
+ &Hostname, strHostname->buffer, strHostname->length,
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ he= gethostbyname (Hostname->buffer);
+
+ rtl_string_release (Hostname);
+ return __osl_hostentToHostAddr (he);
+ }
+ return ((oslHostAddr)NULL);
+}
+
+/*****************************************************************************/
+/* osl_createHostAddrByAddr */
+/*****************************************************************************/
+oslHostAddr SAL_CALL osl_createHostAddrByAddr(const oslSocketAddr pAddr)
+{
+ if (pAddr == NULL)
+ return ((oslHostAddr)NULL);
+
+ if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
+ {
+ const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
+
+ if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
+ return ((oslHostAddr)NULL);
+
+ if (__osl_attemptSocketDialupImpl())
+ {
+ struct hostent *he;
+ he= gethostbyaddr ((const sal_Char *)&(sin->sin_addr),
+ sizeof (sin->sin_addr),
+ sin->sin_family);
+ return __osl_hostentToHostAddr (he);
+ }
+ }
+
+ return ((oslHostAddr)NULL);
+}
+
+/*****************************************************************************/
+/* osl_copyHostAddr */
+/*****************************************************************************/
+oslHostAddr SAL_CALL osl_copyHostAddr(const oslHostAddr Addr)
+{
+ oslHostAddr pAddr= (oslHostAddr)Addr;
+
+ if (pAddr)
+ return osl_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
+ else
+ return ((oslHostAddr)NULL);
+}
+
+/*****************************************************************************/
+/* osl_getHostnameOfHostAddr */
+/*****************************************************************************/
+void SAL_CALL osl_getHostnameOfHostAddr(
+ const oslHostAddr pAddr, rtl_uString **strHostname)
+{
+ if (pAddr)
+ rtl_uString_assign (strHostname, pAddr->pHostName);
+ else
+ rtl_uString_new (strHostname);
+}
+
+/*****************************************************************************/
+/* osl_getSocketAddrOfHostAddr */
+/*****************************************************************************/
+oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)
+{
+ if (pAddr)
+ return (const oslSocketAddr)(pAddr->pSockAddr);
+ else
+ return NULL;
+}
+
+/*****************************************************************************/
+/* osl_destroyHostAddr */
+/*****************************************************************************/
+void SAL_CALL osl_destroyHostAddr(oslHostAddr pAddr)
+{
+ if (pAddr)
+ {
+ if (pAddr->pHostName)
+ rtl_uString_release (pAddr->pHostName);
+ if (pAddr->pSockAddr)
+ osl_destroySocketAddr( pAddr->pSockAddr );
+
+ rtl_freeMemory (pAddr);
+ }
+}
+
+/*****************************************************************************/
+/* osl_getLocalHostname */
+/*****************************************************************************/
+oslSocketResult SAL_CALL osl_getLocalHostname (rtl_uString **strLocalHostname)
+{
+ static sal_Unicode LocalHostname[256] = {0};
+
+ if (rtl_ustr_getLength(LocalHostname) == 0)
+ {
+ sal_Char Host[256]= "";
+ if (gethostname(Host, sizeof(Host)) == 0)
+ {
+ /* check if we have an FQDN */
+ if (strchr(Host, '.') == NULL)
+ {
+ oslHostAddr pAddr;
+ rtl_uString *hostName= NULL;
+
+ rtl_string2UString(
+ &hostName, Host, strlen(Host),
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+ OSL_ASSERT(hostName != 0);
+
+ /* no, determine it via dns */
+ pAddr = osl_createHostAddrByName(hostName);
+ rtl_uString_release (hostName);
+
+ if (pAddr && pAddr->pHostName)
+ memcpy(LocalHostname, pAddr->pHostName->buffer, sizeof(sal_Unicode)*(rtl_ustr_getLength(pAddr->pHostName->buffer)+1));
+ else
+ memset(LocalHostname, 0, sizeof(LocalHostname));
+
+ osl_destroyHostAddr ((oslHostAddr)pAddr);
+ }
+ }
+ }
+
+ if (rtl_ustr_getLength(LocalHostname) > 0)
+ {
+ rtl_uString_newFromStr (strLocalHostname, LocalHostname);
+ return osl_Socket_Ok;
+ }
+
+ return osl_Socket_Error;
+}
+
+/*****************************************************************************/
+/* osl_resolveHostname */
+/*****************************************************************************/
+oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString* strHostname)
+{
+ oslHostAddr pAddr=
+ (oslHostAddr )osl_createHostAddrByName (strHostname);
+ if (pAddr)
+ {
+ oslSocketAddr SockAddr = osl_copySocketAddr( pAddr->pSockAddr );
+ osl_destroyHostAddr(pAddr);
+ return (SockAddr);
+ }
+ return ((oslSocketAddr)NULL);
+}
+
+/*****************************************************************************/
+/* osl_getServicePort */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_getServicePort (
+ rtl_uString* strServicename,
+ rtl_uString* strProtocol)
+{
+ struct servent* ps;
+
+ rtl_String *str_Servicename=NULL;
+ rtl_String *str_Protocol=NULL;
+
+ rtl_uString2String(
+ &str_Servicename,
+ rtl_uString_getStr(strServicename),
+ rtl_uString_getLength(strServicename),
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+ rtl_uString2String(
+ &str_Protocol,
+ rtl_uString_getStr(strProtocol),
+ rtl_uString_getLength(strProtocol),
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ ps= getservbyname(
+ rtl_string_getStr(str_Servicename),
+ rtl_string_getStr(str_Protocol));
+
+ rtl_string_release( str_Servicename );
+ rtl_string_release( str_Protocol );
+
+ if (ps != 0)
+ return ntohs(ps->s_port);
+
+ return OSL_INVALID_PORT;
+}
+
+/*****************************************************************************/
+/* osl_destroySocketAddr */
+/*****************************************************************************/
+void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
+{
+ __osl_destroySocketAddr( pAddr );
+}
+
+/*****************************************************************************/
+/* osl_getFamilyOfSocketAddr */
+/*****************************************************************************/
+oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
+{
+ if (pAddr)
+ return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
+ else
+ return osl_Socket_FamilyInvalid;
+}
+
+/*****************************************************************************/
+/* osl_getInetPortOfSocketAddr */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
+{
+ if( pAddr )
+ {
+ struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
+
+ if ( (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet)))
+ return ntohs(pSystemInetAddr->sin_port);
+ }
+ return OSL_INVALID_PORT;
+}
+
+/*****************************************************************************/
+/* osl_setInetPortOfSocketAddr */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_setInetPortOfSocketAddr (
+ oslSocketAddr pAddr,
+ sal_Int32 Port)
+{
+ if (pAddr == NULL)
+ return sal_False;
+
+ struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
+
+ if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
+ return sal_False;
+
+ pSystemInetAddr->sin_port= htons((short)Port);
+ return sal_True;
+}
+
+/*****************************************************************************/
+/* osl_getHostnameOfSocketAddr */
+/*****************************************************************************/
+oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr (
+ oslSocketAddr Addr,
+ rtl_uString **strHostName)
+{
+ oslHostAddr pAddr= osl_createHostAddrByAddr (Addr);
+
+ if (pAddr)
+ {
+ rtl_uString_newFromString(strHostName, pAddr->pHostName);
+
+ osl_destroyHostAddr(pAddr);
+
+ return osl_Socket_Ok;
+ }
+
+ return osl_Socket_Error;
+}
+
+/*****************************************************************************/
+/* osl_getDottedInetAddrOfSocketAddr */
+/*****************************************************************************/
+oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr (
+ oslSocketAddr pAddr,
+ rtl_uString **strDottedInetAddr)
+{
+ sal_Char *pDotted;
+
+ if (pAddr == NULL)
+ return osl_Socket_Error;
+
+ struct sockaddr_in *pSystemInetAddr = (struct sockaddr_in*) &(pAddr->m_sockaddr);
+ if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
+ return osl_Socket_Error;
+
+ pDotted = inet_ntoa (pSystemInetAddr->sin_addr);
+ rtl_string2UString(
+ strDottedInetAddr, pDotted, strlen (pDotted),
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+ OSL_ASSERT(*strDottedInetAddr != 0);
+
+ return osl_Socket_Ok;
+}
+
+/*****************************************************************************/
+/* osl_createSocket */
+/*****************************************************************************/
+oslSocket SAL_CALL osl_createSocket (
+ oslAddrFamily Family,
+ oslSocketType Type,
+ oslProtocol Protocol)
+{
+ /* alloc memory */
+ oslSocket pSocket = __osl_createSocketImpl(0);
+
+ if (pSocket == NULL)
+ return 0;
+
+ /* create socket */
+ pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
+ TYPE_TO_NATIVE(Type),
+ PROTOCOL_TO_NATIVE(Protocol));
+
+ /* creation failed => free memory */
+ if(pSocket->m_Socket == OSL_INVALID_SOCKET)
+ {
+ __osl_destroySocketImpl(pSocket);
+ pSocket= 0;
+ }
+ else
+ {
+ pSocket->m_Flags = 0;
+ pSocket->m_CloseCallback = NULL;
+ pSocket->m_CallbackArg = NULL;
+ }
+
+ return pSocket;
+}
+
+void SAL_CALL osl_acquireSocket( oslSocket pSocket )
+{
+ osl_incrementInterlockedCount( &(pSocket->m_nRefCount) );
+}
+
+void SAL_CALL osl_releaseSocket( oslSocket pSocket )
+{
+ if( pSocket && 0 == osl_decrementInterlockedCount( &(pSocket->m_nRefCount) ) )
+ {
+ osl_closeSocket( pSocket );
+ __osl_destroySocketImpl( pSocket );
+ }
+}
+
+/*****************************************************************************/
+/* osl_closeSocket */
+/*****************************************************************************/
+void SAL_CALL osl_closeSocket(oslSocket pSocket)
+{
+ /* socket already invalid */
+ if(pSocket==0)
+ return;
+
+ /* close */
+ closesocket(pSocket->m_Socket);
+
+ pSocket->m_Socket = OSL_INVALID_SOCKET;
+
+ /* registrierten Callback ausfuehren */
+ if (pSocket->m_CloseCallback != NULL)
+ {
+ pSocket->m_CloseCallback(pSocket->m_CallbackArg);
+ }
+}
+
+/*****************************************************************************/
+/* osl_getLocalAddrOfSocket */
+/* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
+/* are the same! I don't like it very much but see no other easy way */
+/* to conceal the struct sockaddr from the eyes of the user. */
+/*****************************************************************************/
+oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
+{
+ struct sockaddr Addr;
+ int AddrLen;
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return ((oslSocketAddr)NULL);
+
+ AddrLen= sizeof(struct sockaddr);
+
+ if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
+ return ((oslSocketAddr)NULL);
+
+ oslSocketAddr pAddr = __osl_createSocketAddrFromSystem( &Addr );
+ return pAddr;
+}
+
+/*****************************************************************************/
+/* osl_getPeerAddrOfSocket */
+/*****************************************************************************/
+oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
+{
+ struct sockaddr Addr;
+ int AddrLen;
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return ((oslSocketAddr)NULL);
+
+ AddrLen= sizeof(struct sockaddr);
+
+ if (getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
+ return ((oslSocketAddr)NULL);
+
+ oslSocketAddr pAddr = __osl_createSocketAddrFromSystem( &Addr );
+ return pAddr;
+}
+
+/*****************************************************************************/
+/* osl_bindAddrToSocket */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_bindAddrToSocket ( oslSocket pSocket, oslSocketAddr pAddr)
+{
+ OSL_ASSERT( pAddr );
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ return (bind(pSocket->m_Socket,
+ &(pAddr->m_sockaddr),
+ sizeof(struct sockaddr)) != OSL_SOCKET_ERROR);
+}
+
+/*****************************************************************************/
+/* osl_connectSocketTo */
+/*****************************************************************************/
+oslSocketResult SAL_CALL osl_connectSocketTo (
+ oslSocket pSocket,
+ oslSocketAddr pAddr,
+ const TimeValue* pTimeout)
+{
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return osl_Socket_Error;
+
+ if (pAddr == NULL) /* EDESTADDRREQ */
+ return osl_Socket_Error;
+
+ if (!__osl_attemptSocketDialupImpl()) /* ENETDOWN */
+ return osl_Socket_Error;
+
+ if (pTimeout == NULL)
+ {
+ if(connect(pSocket->m_Socket,
+ &(pAddr->m_sockaddr),
+ sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
+ return osl_Socket_Error;
+ else
+ return osl_Socket_Ok;
+ }
+ else
+ {
+ fd_set fds;
+ int error;
+ struct timeval tv;
+ unsigned long Param;
+ oslSocketResult Result= osl_Socket_Ok;
+
+ if (pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING)
+ {
+ if (connect(pSocket->m_Socket,
+ &(pAddr->m_sockaddr),
+ sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
+ {
+ switch (WSAGetLastError())
+ {
+ case WSAEWOULDBLOCK:
+ case WSAEINPROGRESS:
+ return osl_Socket_InProgress;
+
+ default:
+ return osl_Socket_Error;
+ }
+ }
+ else
+ return osl_Socket_Ok;
+ }
+
+ /* set socket temporarily to non-blocking */
+ Param= 1;
+ OSL_VERIFY(ioctlsocket(
+ pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
+
+ /* initiate connect */
+ if (connect(pSocket->m_Socket,
+ &(pAddr->m_sockaddr),
+ sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
+ {
+ /* immediate connection */
+
+ Param= 0;
+ ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
+
+ return osl_Socket_Ok;
+ }
+ else
+ {
+ error = WSAGetLastError();
+
+ /* really an error or just delayed? */
+ if (error != WSAEWOULDBLOCK && error != WSAEINPROGRESS)
+ {
+ Param= 0;
+ ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
+
+ return osl_Socket_Error;
+ }
+ }
+
+ /* prepare select set for socket */
+ FD_ZERO(&fds);
+ FD_SET(pSocket->m_Socket, &fds);
+
+ /* divide milliseconds into seconds and microseconds */
+ tv.tv_sec= pTimeout->Seconds;
+ tv.tv_usec= pTimeout->Nanosec / 1000L;
+
+ /* select */
+ error= select(pSocket->m_Socket+1,
+ 0,
+ &fds,
+ 0,
+ &tv);
+
+ if (error > 0) /* connected */
+ {
+ OSL_POSTCOND(
+ FD_ISSET(pSocket->m_Socket, &fds),
+ "osl_connectSocketTo(): select returned but socket not set\n");
+
+ Result= osl_Socket_Ok;
+
+ }
+ else if(error < 0) /* error */
+ {
+ /* errno == EBADF: most probably interrupted by close() */
+ if(WSAGetLastError() == WSAEBADF)
+ {
+ /* do not access pSockImpl because it is about to be or */
+ /* already destroyed */
+ return osl_Socket_Interrupted;
+ }
+ else
+ Result= osl_Socket_Error;
+
+ }
+ else /* timeout */
+ Result= osl_Socket_TimedOut;
+
+
+ /* clean up */
+ Param= 0;
+ ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
+
+ return Result;
+ }
+}
+
+/*****************************************************************************/
+/* osl_listenOnSocket */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_listenOnSocket (
+ oslSocket pSocket,
+ sal_Int32 MaxPendingConnections)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ return (listen(pSocket->m_Socket,
+ MaxPendingConnections == -1 ?
+ SOMAXCONN :
+ MaxPendingConnections) != OSL_SOCKET_ERROR);
+}
+
+/*****************************************************************************/
+/* osl_acceptConnectionOnSocket */
+/*****************************************************************************/
+oslSocket SAL_CALL osl_acceptConnectionOnSocket (
+ oslSocket pSocket,
+ oslSocketAddr* ppAddr)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return ((oslSocket)NULL);
+
+ SOCKET Connection;
+ if(ppAddr)
+ {
+ if( *ppAddr )
+ {
+ osl_destroySocketAddr( *ppAddr );
+ *ppAddr = 0;
+ }
+ int AddrLen= sizeof(struct sockaddr);
+
+ /* user wants to know peer Addr */
+ struct sockaddr Addr;
+
+ Connection= accept(pSocket->m_Socket, &Addr, &AddrLen);
+ OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
+
+ if(Connection != OSL_SOCKET_ERROR)
+ *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
+ else
+ *ppAddr = NULL;
+ }
+ else
+ {
+ /* user is not interested in peer-addr */
+ Connection= accept(pSocket->m_Socket, 0, 0);
+ }
+
+ /* accept failed? */
+ if(Connection == OSL_SOCKET_ERROR)
+ return ((oslSocket)NULL);
+
+ /* alloc memory */
+ oslSocket pConnectionSocket;
+ pConnectionSocket= __osl_createSocketImpl(Connection);
+
+ pConnectionSocket->m_Flags = 0;
+ pConnectionSocket->m_CloseCallback = NULL;
+ pConnectionSocket->m_CallbackArg = NULL;
+
+ return pConnectionSocket;
+}
+
+/*****************************************************************************/
+/* osl_receiveSocket */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_receiveSocket (
+ oslSocket pSocket,
+ void* pBuffer,
+ sal_uInt32 BytesToRead,
+ oslSocketMsgFlag Flag)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return osl_Socket_Error;
+
+ return recv(pSocket->m_Socket,
+ (sal_Char*)pBuffer,
+ BytesToRead,
+ MSG_FLAG_TO_NATIVE(Flag));
+}
+
+/*****************************************************************************/
+/* osl_receiveFromSocket */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_receiveFromSocket (
+ oslSocket pSocket,
+ oslSocketAddr SenderAddr,
+ void* pBuffer,
+ sal_uInt32 BufferSize,
+ oslSocketMsgFlag Flag)
+{
+ struct sockaddr *pSystemSockAddr = 0;
+ int AddrLen = 0;
+ if( SenderAddr )
+ {
+ AddrLen = sizeof( struct sockaddr );
+ pSystemSockAddr = &(SenderAddr->m_sockaddr);
+ }
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return osl_Socket_Error;
+
+ return recvfrom(pSocket->m_Socket,
+ (sal_Char*)pBuffer,
+ BufferSize,
+ MSG_FLAG_TO_NATIVE(Flag),
+ pSystemSockAddr,
+ &AddrLen);
+}
+
+/*****************************************************************************/
+/* osl_sendSocket */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_sendSocket (
+ oslSocket pSocket,
+ const void* pBuffer,
+ sal_uInt32 BytesToSend,
+ oslSocketMsgFlag Flag)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return osl_Socket_Error;
+
+ return send(pSocket->m_Socket,
+ (sal_Char*)pBuffer,
+ BytesToSend,
+ MSG_FLAG_TO_NATIVE(Flag));
+}
+
+/*****************************************************************************/
+/* osl_sendToSocket */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_sendToSocket (
+ oslSocket pSocket,
+ oslSocketAddr ReceiverAddr,
+ const void* pBuffer,
+ sal_uInt32 BytesToSend,
+ oslSocketMsgFlag Flag)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return osl_Socket_Error;
+
+ /* ReceiverAddr might be 0 when used on a connected socket. */
+ /* Then sendto should behave like send. */
+
+ struct sockaddr *pSystemSockAddr = 0;
+ if( ReceiverAddr )
+ pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
+
+ return sendto(pSocket->m_Socket,
+ (sal_Char*)pBuffer,
+ BytesToSend,
+ MSG_FLAG_TO_NATIVE(Flag),
+ pSystemSockAddr,
+ pSystemSockAddr == 0 ? 0 : sizeof(struct sockaddr));
+}
+
+/*****************************************************************************/
+/* osl_readSocket */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_readSocket( oslSocket pSocket, void *pBuffer, sal_Int32 n )
+{
+ sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
+
+ OSL_ASSERT( pSocket);
+
+ /* loop until all desired bytes were read or an error occured */
+ sal_uInt32 BytesRead= 0;
+ sal_uInt32 BytesToRead= n;
+ while (BytesToRead > 0)
+ {
+ sal_Int32 RetVal;
+ RetVal= osl_receiveSocket(pSocket,
+ Ptr,
+ BytesToRead,
+ osl_Socket_MsgNormal);
+
+ /* error occured? */
+ if(RetVal <= 0)
+ {
+ break;
+ }
+
+ BytesToRead -= RetVal;
+ BytesRead += RetVal;
+ Ptr += RetVal;
+ }
+
+ return BytesRead;
+}
+
+/*****************************************************************************/
+/* osl_writeSocket */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_writeSocket( oslSocket pSocket, const void *pBuffer, sal_Int32 n )
+{
+ OSL_ASSERT( pSocket );
+
+ /* loop until all desired bytes were send or an error occured */
+ sal_uInt32 BytesSend= 0;
+ sal_uInt32 BytesToSend= n;
+ sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
+ while (BytesToSend > 0)
+ {
+ sal_Int32 RetVal;
+
+ RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
+
+ /* error occured? */
+ if(RetVal <= 0)
+ {
+ break;
+ }
+
+ BytesToSend -= RetVal;
+ BytesSend += RetVal;
+ Ptr += RetVal;
+
+ }
+ return BytesSend;
+}
+
+
+/*****************************************************************************/
+/* osl_isReceiveReady */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_isReceiveReady (
+ oslSocket pSocket,
+ const TimeValue* pTimeout)
+{
+ fd_set fds;
+ struct timeval tv;
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ FD_ZERO(&fds);
+ FD_SET(pSocket->m_Socket, &fds);
+
+ if (pTimeout)
+ {
+ tv.tv_sec = pTimeout->Seconds;
+ tv.tv_usec = pTimeout->Nanosec / 1000L;
+ }
+
+ return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
+ &fds, /* check read operations */
+ 0, /* check write ops */
+ 0, /* ckeck for OOB */
+ (pTimeout) ? &tv : 0)==1); /* use timeout? */
+}
+
+/*****************************************************************************/
+/* osl_isSendReady */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_isSendReady (
+ oslSocket pSocket,
+ const TimeValue* pTimeout)
+{
+ fd_set fds;
+ struct timeval tv;
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ FD_ZERO(&fds);
+ FD_SET(pSocket->m_Socket, &fds);
+
+ if (pTimeout)
+ {
+ tv.tv_sec = pTimeout->Seconds;
+ tv.tv_usec = pTimeout->Nanosec / 1000L;
+ }
+
+ return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
+ 0, /* check read operations */
+ &fds, /* check write ops */
+ 0, /* ckeck for OOB */
+ (pTimeout) ? &tv : 0)==1); /* use timeout? */
+}
+
+/*****************************************************************************/
+/* osl_isExceptionPending */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_isExceptionPending (
+ oslSocket pSocket,
+ const TimeValue* pTimeout)
+{
+ fd_set fds;
+ struct timeval tv;
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ FD_ZERO(&fds);
+ FD_SET(pSocket->m_Socket, &fds);
+
+ if (pTimeout)
+ {
+ tv.tv_sec = pTimeout->Seconds;
+ tv.tv_usec = pTimeout->Nanosec / 1000L;
+ }
+
+ return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
+ 0, /* check read operations */
+ 0, /* check write ops */
+ &fds, /* ckeck for OOB */
+ (pTimeout) ? &tv : 0)==1); /* use timeout? */
+}
+
+/*****************************************************************************/
+/* osl_shutdownSocket */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_shutdownSocket (
+ oslSocket pSocket,
+ oslSocketDirection Direction)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ return (shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction))==0);
+}
+
+/*****************************************************************************/
+/* osl_getSocketOption */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_getSocketOption (
+ oslSocket pSocket,
+ oslSocketOptionLevel Level,
+ oslSocketOption Option,
+ void* pBuffer,
+ sal_uInt32 BufferLen)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return osl_Socket_Error;
+
+ if (getsockopt(pSocket->m_Socket,
+ OPTION_LEVEL_TO_NATIVE(Level),
+ OPTION_TO_NATIVE(Option),
+ (sal_Char*)pBuffer,
+ (int*)&BufferLen) == -1)
+ {
+ return -1;
+ }
+
+ return (sal_Int32)BufferLen;
+}
+
+/*****************************************************************************/
+/* osl_setSocketOption */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_setSocketOption (
+ oslSocket pSocket,
+ oslSocketOptionLevel Level,
+ oslSocketOption Option,
+ void* pBuffer,
+ sal_uInt32 BufferLen)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ return(setsockopt(pSocket->m_Socket,
+ OPTION_LEVEL_TO_NATIVE(Level),
+ OPTION_TO_NATIVE(Option),
+ (sal_Char*)pBuffer,
+ BufferLen) == 0);
+}
+
+/*****************************************************************************/
+/* osl_enableNonBlockingMode */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_enableNonBlockingMode ( oslSocket pSocket, sal_Bool On)
+{
+ unsigned long Param= On ? 1 : 0;
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ pSocket->m_Flags = Param ?
+ (pSocket->m_Flags | OSL_SOCKET_FLAGS_NONBLOCKING) :
+ (pSocket->m_Flags & ~OSL_SOCKET_FLAGS_NONBLOCKING) ;
+
+ return (
+ ioctlsocket(pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
+}
+
+/*****************************************************************************/
+/* osl_isNonBlockingMode */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
+{
+ if (pSocket == NULL) /* ENOTSOCK */
+ return sal_False;
+
+ return (sal_Bool)((pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING) != 0);
+}
+
+/*****************************************************************************/
+/* osl_getSocketType */
+/*****************************************************************************/
+oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
+{
+ int Type=0;
+ int TypeSize= sizeof(Type);
+
+ if (pSocket == NULL) /* ENOTSOCK */
+ return osl_Socket_TypeInvalid;
+
+ if(getsockopt(pSocket->m_Socket,
+ OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
+ OPTION_TO_NATIVE(osl_Socket_OptionType),
+ (sal_Char *)&Type,
+ &TypeSize) == -1)
+ {
+ /* error */
+ return osl_Socket_TypeInvalid;
+ }
+
+ return TYPE_FROM_NATIVE(Type);
+}
+
+/*****************************************************************************/
+/* osl_getLastSocketErrorDescription */
+/*****************************************************************************/
+void SAL_CALL osl_getLastSocketErrorDescription (
+ oslSocket /*Socket*/,
+ rtl_uString **strError)
+{
+ int error;
+
+ switch(error = WSAGetLastError())
+ {
+ case WSAENOTSOCK:
+ rtl_uString_newFromAscii (strError, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
+ break;
+
+ case WSAEDESTADDRREQ:
+ rtl_uString_newFromAscii (strError, "WSAEDESTADDRREQ, Destination Addr required");
+ break;
+
+ case WSAEMSGSIZE:
+ rtl_uString_newFromAscii (strError, "WSAEMSGSIZE, Message too long");
+ break;
+
+ case WSAEPROTOTYPE:
+ rtl_uString_newFromAscii (strError, "WSAEPROTOTYPE, Protocol wrong type for socket");
+ break;
+
+ case WSAENOPROTOOPT:
+ rtl_uString_newFromAscii (strError, "WSAENOPROTOOPT, Protocol not available");
+ break;
+
+ case WSAEPROTONOSUPPORT:
+ rtl_uString_newFromAscii (strError, "WSAEPROTONOSUPPORT, Protocol not supported");
+ break;
+
+ case WSAESOCKTNOSUPPORT:
+ rtl_uString_newFromAscii (strError, "WSAESOCKTNOSUPPORT, Socket type not supported");
+ break;
+
+ case WSAEOPNOTSUPP:
+ rtl_uString_newFromAscii (strError, "WSAEOPNOTSUPP, Operation not supported on socket");
+ break;
+
+ case WSAEPFNOSUPPORT:
+ rtl_uString_newFromAscii (strError, "WSAEPFNOSUPPORT, Protocol family not supported");
+ break;
+
+ case WSAEAFNOSUPPORT:
+ rtl_uString_newFromAscii (strError, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
+ break;
+
+ case WSAEADDRINUSE:
+ rtl_uString_newFromAscii (strError, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
+ break;
+
+ case WSAEADDRNOTAVAIL:
+ rtl_uString_newFromAscii (strError, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
+ break;
+
+ case WSAENETDOWN:
+ rtl_uString_newFromAscii (strError, "WSAENETDOWN, Network is down");
+ break;
+
+ case WSAENETUNREACH:
+ rtl_uString_newFromAscii (strError, "WSAENETUNREACH, Network is unreachable");
+ break;
+
+ case WSAENETRESET:
+ rtl_uString_newFromAscii (strError, "WSAENETRESET, Network dropped connection or reset");
+ break;
+
+ case WSAECONNABORTED:
+ rtl_uString_newFromAscii (strError, "WSAECONNABORTED, Software caused connection abort");
+ break;
+
+ case WSAECONNRESET:
+ rtl_uString_newFromAscii (strError, "WSAECONNRESET, Connection reset by peer");
+ break;
+
+ case WSAENOBUFS:
+ rtl_uString_newFromAscii (strError, "WSAENOBUFS, No buffer space available.");
+ break;
+
+ case WSAEISCONN:
+ rtl_uString_newFromAscii (strError, "WSAEISCONN, Socket is already connected");
+ break;
+
+ case WSAENOTCONN:
+ rtl_uString_newFromAscii (strError, "WSAENOTCONN, Socket is not connected");
+ break;
+
+ case WSAESHUTDOWN:
+ rtl_uString_newFromAscii (strError, "WSAESHUTDOWN, Can't send after socket shutdown");
+ break;
+
+ case WSAETIMEDOUT:
+ rtl_uString_newFromAscii (strError, "WSAETIMEDOUT, Connection timed out");
+ break;
+
+ case WSAECONNREFUSED:
+ rtl_uString_newFromAscii (strError, "WSAECONNREFUSED, Connection refused");
+ break;
+
+ case WSAEHOSTDOWN:
+ rtl_uString_newFromAscii (strError, "WSAEHOSTDOWN, Networking subsystem not started");
+ break;
+
+ case WSAEHOSTUNREACH:
+ rtl_uString_newFromAscii (strError, "WSAEHOSTUNREACH, No route to host");
+ break;
+
+ case WSAEWOULDBLOCK:
+ rtl_uString_newFromAscii (strError, "WSAEWOULDBLOCK, Operation would block");
+ break;
+
+ case WSAEINPROGRESS:
+ rtl_uString_newFromAscii (strError, "WSAEINPROGRESS, Operation now in progress");
+ break;
+
+ case WSAEALREADY:
+ rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation already in progress");
+ break;
+
+ case WSAEINTR:
+ rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation was interrupted");
+ break;
+
+ case WSAEBADF:
+ rtl_uString_newFromAscii (strError, "WSAEBADF, Bad file number");
+ break;
+
+ case WSAEACCES:
+ rtl_uString_newFromAscii (strError, "WSAEACCES, Access is denied");
+ break;
+
+ case WSAEFAULT:
+ rtl_uString_newFromAscii (strError, "WSAEFAULT, Bad memory Addr");
+ break;
+
+ case WSAEINVAL:
+ rtl_uString_newFromAscii (strError, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
+ break;
+
+ case WSAEMFILE:
+ rtl_uString_newFromAscii (strError, "WSAEMFILE, No more file descriptors are available");
+ break;
+
+ case WSAETOOMANYREFS:
+ rtl_uString_newFromAscii (strError, "WSAETOOMANYREFS, Undocumented WinSock error");
+ break;
+
+ case WSAENAMETOOLONG:
+ rtl_uString_newFromAscii (strError, "WSAENAMETOOLONG, Undocumented WinSock error");
+ break;
+
+ case WSAENOTEMPTY:
+ rtl_uString_newFromAscii (strError, "WSAENOTEMPTY, Undocumented WinSock error");
+ break;
+
+ case WSAEPROCLIM:
+ rtl_uString_newFromAscii (strError, "WSAEPROCLIM, Undocumented WinSock error");
+ break;
+
+ case WSAEUSERS:
+ rtl_uString_newFromAscii (strError, "WSAEUSERS, Undocumented WinSock error");
+ break;
+
+ case WSAEDQUOT:
+ rtl_uString_newFromAscii (strError, "WSAEDQUOT, Undocumented WinSock error");
+ break;
+
+ case WSAESTALE:
+ rtl_uString_newFromAscii (strError, "WSAESTALE, Undocumented WinSock error");
+ break;
+
+ case WSAEREMOTE:
+ rtl_uString_newFromAscii (strError, "WSAEREMOTE, Undocumented WinSock error");
+ break;
+
+ case WSAEDISCON:
+ rtl_uString_newFromAscii (strError, "WSAEDISCON, Circuit was gracefully terminated");
+ break;
+
+ case WSASYSNOTREADY:
+ rtl_uString_newFromAscii (strError, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
+ break;
+
+ case WSAVERNOTSUPPORTED:
+ rtl_uString_newFromAscii (strError, "WSAVERNOTSUPPORTED, The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation");
+ break;
+
+ case WSANOTINITIALISED:
+ rtl_uString_newFromAscii (strError, "WSANOTINITIALISED, WSAStartup() has not been called");
+ break;
+
+ case WSAHOST_NOT_FOUND:
+ rtl_uString_newFromAscii (strError, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
+ break;
+
+ case WSATRY_AGAIN:
+ rtl_uString_newFromAscii (strError, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
+ break;
+
+ case WSANO_RECOVERY:
+ rtl_uString_newFromAscii (strError, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
+ break;
+
+ case WSANO_DATA:
+ rtl_uString_newFromAscii (strError, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
+ break;
+
+ default:
+ {
+ sal_Unicode message[128];
+
+ wsprintfW(reinterpret_cast<LPWSTR>(message), L"Unknown WinSock Error Number %d", error);
+ rtl_uString_newFromStr (strError, message);
+ }
+
+ return;
+
+ }
+}
+
+/*****************************************************************************/
+/* osl_getLastSocketError */
+/*****************************************************************************/
+oslSocketError SAL_CALL osl_getLastSocketError(oslSocket /*Socket*/)
+{
+ return ERROR_FROM_NATIVE(WSAGetLastError());
+}
+
+/*****************************************************************************/
+/* SocketSet */
+/*****************************************************************************/
+typedef struct _TSocketSetImpl
+{
+ fd_set m_Set; /* the set of descriptors */
+
+} TSocketSetImpl;
+
+/*****************************************************************************/
+/* osl_createSocketSet */
+/*****************************************************************************/
+oslSocketSet SAL_CALL osl_createSocketSet()
+{
+ TSocketSetImpl* pSet;
+
+ pSet = (TSocketSetImpl*) rtl_allocateMemory(sizeof(TSocketSetImpl));
+
+ if(pSet)
+ {
+ FD_ZERO(&pSet->m_Set);
+ }
+
+ return (oslSocketSet)pSet;
+}
+
+/*****************************************************************************/
+/* osl_destroySocketSet */
+/*****************************************************************************/
+void SAL_CALL osl_destroySocketSet (oslSocketSet Set)
+{
+ if(Set)
+ rtl_freeMemory(Set);
+}
+
+/*****************************************************************************/
+/* osl_clearSocketSet */
+/*****************************************************************************/
+void SAL_CALL osl_clearSocketSet (oslSocketSet Set)
+{
+ TSocketSetImpl* pSet;
+
+ pSet= (TSocketSetImpl*)Set;
+
+ if (pSet)
+ FD_ZERO(&pSet->m_Set);
+}
+
+/*****************************************************************************/
+/* osl_addToSocketSet */
+/*****************************************************************************/
+void SAL_CALL osl_addToSocketSet (
+ oslSocketSet Set,
+ oslSocket Socket)
+{
+ TSocketSetImpl* pSet;
+ oslSocketImpl* pSockImpl;
+
+ pSet= (TSocketSetImpl*)Set;
+ pSockImpl= (oslSocketImpl*)Socket;
+
+ if (pSet && pSockImpl)
+ FD_SET(pSockImpl->m_Socket, &pSet->m_Set);
+}
+
+/*****************************************************************************/
+/* osl_removeFromSocketSet */
+/*****************************************************************************/
+void SAL_CALL osl_removeFromSocketSet (
+ oslSocketSet Set,
+ oslSocket Socket)
+{
+ TSocketSetImpl* pSet;
+ oslSocketImpl* pSockImpl;
+
+ pSet= (TSocketSetImpl*)Set;
+ pSockImpl= (oslSocketImpl*)Socket;
+
+ if (pSet && pSockImpl)
+ FD_CLR(pSockImpl->m_Socket, &pSet->m_Set);
+}
+
+/*****************************************************************************/
+/* osl_isInSocketSet */
+/*****************************************************************************/
+sal_Bool SAL_CALL osl_isInSocketSet (
+ oslSocketSet Set,
+ oslSocket Socket)
+{
+ TSocketSetImpl* pSet;
+ oslSocketImpl* pSockImpl;
+
+ pSet= (TSocketSetImpl*)Set;
+ pSockImpl= (oslSocketImpl*)Socket;
+
+ if (pSet && pSockImpl)
+ return (FD_ISSET(pSockImpl->m_Socket, &pSet->m_Set) != 0);
+ else
+ return sal_False;
+}
+
+/*****************************************************************************/
+/* osl_demultiplexSocketEvents */
+/*****************************************************************************/
+sal_Int32 SAL_CALL osl_demultiplexSocketEvents (
+ oslSocketSet IncomingSet,
+ oslSocketSet OutgoingSet,
+ oslSocketSet OutOfBandSet,
+ const TimeValue* pTimeout)
+{
+ int MaxHandle= 0;
+ struct timeval tv;
+ TSocketSetImpl* pInSet;
+ TSocketSetImpl* pOutSet;
+ TSocketSetImpl* pOOBSet;
+
+ if(pTimeout)
+ {
+ /* divide milliseconds into seconds and microseconds */
+ tv.tv_sec = pTimeout->Seconds;
+ tv.tv_usec = pTimeout->Nanosec / 1000L;
+ }
+
+ /* map opaque data to impl-types */
+ pInSet= (TSocketSetImpl*)IncomingSet;
+ pOutSet= (TSocketSetImpl*)OutgoingSet;
+ pOOBSet= (TSocketSetImpl*)OutOfBandSet;
+
+ return select(MaxHandle, /* redundant in WIN32 */
+ pInSet ? &pInSet->m_Set : 0,
+ pOutSet ? &pOutSet->m_Set : 0,
+ pOOBSet ? &pOOBSet->m_Set : 0,
+ pTimeout ? &tv : 0);
+}
+
+}