Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / sal / osl / w32 / socket.cxx
blob2b7e74202f5c037c67247782665e5da985a2e39c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "system.h"
23 #include <osl/socket.h>
24 #include <osl/diagnose.h>
25 #include <rtl/alloc.h>
27 #include "sockimpl.h"
29 extern "C" {
32 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
33 I refrained from using sockaddr_in because of possible further
34 extensions of this socket-interface (IP-NG?).
35 The intention was to hide all Berkeley data-structures from
36 direct access past the osl-interface.
38 The current implementation is internet (IP) centered. All
39 the constructor-functions (osl_create...) take parameters
40 that will probably make sense only in the IP-environment
41 (e.g. because of using the dotted-Addr-format).
43 If the interface will be extended to host other protocol-
44 families, I expect no externally visible changes in the
45 existing functions. You'll probably need only new
46 constructor-functions who take the different Addr
47 formats into consideration (maybe a long dotted Addr
48 or whatever).
52 _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr
53 are the same! I don't like it very much but see no other easy way to
54 conceal the struct sockaddr from the eyes of the user.
57 #define OSL_INVALID_SOCKET INVALID_SOCKET /* WIN32 */
58 #define OSL_SOCKET_ERROR SOCKET_ERROR /* WIN32 */
60 /*****************************************************************************/
61 /* enum oslAddrFamily */
62 /*****************************************************************************/
64 /* map */
65 static DWORD FamilyMap[]= {
66 AF_INET, /* osl_Socket_FamilyInet */
67 AF_IPX, /* osl_Socket_FamilyIpx */
68 0 /* osl_Socket_FamilyInvalid */
71 /* reverse map */
72 static oslAddrFamily osl_AddrFamilyFromNative(DWORD nativeType)
74 oslAddrFamily i= (oslAddrFamily) 0;
75 while(i != osl_Socket_FamilyInvalid)
77 if(FamilyMap[i] == nativeType)
78 return i;
79 i = (oslAddrFamily) ( (int)i + 1);
81 return i;
84 /* macros */
85 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
86 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
88 /*****************************************************************************/
89 /* enum oslProtocol */
90 /*****************************************************************************/
92 /* map */
93 static DWORD ProtocolMap[]= {
94 0, /* osl_Socket_FamilyInet */
95 NSPROTO_IPX, /* osl_Socket_FamilyIpx */
96 NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
97 NSPROTO_SPXII, /* osl_Socket_ProtocolSpx_ii */
98 0 /* osl_Socket_ProtocolInvalid */
101 /* macros */
102 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
104 /*****************************************************************************/
105 /* enum oslSocketType */
106 /*****************************************************************************/
108 /* map */
109 static DWORD TypeMap[]= {
110 SOCK_STREAM, /* osl_Socket_TypeStream */
111 SOCK_DGRAM, /* osl_Socket_TypeDgram */
112 SOCK_RAW, /* osl_Socket_TypeRaw */
113 SOCK_RDM, /* osl_Socket_TypeRdm */
114 SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
115 0 /* osl_Socket_TypeInvalid */
118 /* reverse map */
119 static oslSocketType osl_SocketTypeFromNative(DWORD nativeType)
121 oslSocketType i= (oslSocketType)0;
122 while(i != osl_Socket_TypeInvalid)
124 if(TypeMap[i] == nativeType)
125 return i;
126 i = (oslSocketType)((int)i+1);
128 return i;
131 /* macros */
132 #define TYPE_TO_NATIVE(x) TypeMap[x]
133 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
135 /*****************************************************************************/
136 /* enum oslSocketOption */
137 /*****************************************************************************/
139 /* map */
140 static DWORD OptionMap[]= {
141 SO_DEBUG, /* osl_Socket_OptionDebug */
142 SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
143 SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
144 SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
145 SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
146 SO_BROADCAST, /* osl_Socket_OptionBroadcast */
147 SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
148 SO_LINGER, /* osl_Socket_OptionLinger */
149 SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
150 SO_SNDBUF, /* osl_Socket_OptionSndBuf */
151 SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
152 SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
153 SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
154 SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
155 SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
156 SO_ERROR, /* osl_Socket_OptionError */
157 SO_TYPE, /* osl_Socket_OptionType */
158 TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
159 0 /* osl_Socket_OptionInvalid */
162 /* macros */
163 #define OPTION_TO_NATIVE(x) OptionMap[x]
165 /*****************************************************************************/
166 /* enum oslSocketOptionLevel */
167 /*****************************************************************************/
169 static DWORD OptionLevelMap[]= {
170 SOL_SOCKET, /* osl_Socket_LevelSocket */
171 IPPROTO_TCP, /* osl_Socket_LevelTcp */
172 0 /* osl_invalid_SocketLevel */
175 /* macros */
176 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
178 /*****************************************************************************/
179 /* enum oslSocketMsgFlag */
180 /*****************************************************************************/
182 static DWORD SocketMsgFlagMap[]= {
183 0, /* osl_Socket_MsgNormal */
184 MSG_OOB, /* osl_Socket_MsgOOB */
185 MSG_PEEK, /* osl_Socket_MsgPeek */
186 MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
187 MSG_MAXIOVLEN /* osl_Socket_MsgMaxIOVLen */
190 /* macros */
191 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
193 /*****************************************************************************/
194 /* enum oslSocketDirection */
195 /*****************************************************************************/
197 static DWORD SocketDirection[]= {
198 SD_RECEIVE, /* osl_Socket_DirRead */
199 SD_SEND, /* osl_Socket_DirWrite */
200 SD_BOTH /* osl_Socket_DirReadwrite */
203 /* macros */
204 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
206 /*****************************************************************************/
207 /* enum oslSocketError */
208 /*****************************************************************************/
210 static int SocketError[]= {
212 0, /* no error */
213 WSAENOTSOCK, /* Socket operation on non-socket */
214 WSAEDESTADDRREQ, /* Destination address required */
215 WSAEMSGSIZE, /* Message too long */
216 WSAEPROTOTYPE, /* Protocol wrong type for socket */
217 WSAENOPROTOOPT, /* Protocol not available */
218 WSAEPROTONOSUPPORT, /* Protocol not supported */
219 WSAESOCKTNOSUPPORT, /* Socket type not supported */
220 WSAEOPNOTSUPP, /* Operation not supported on socket */
221 WSAEPFNOSUPPORT, /* Protocol family not supported */
222 WSAEAFNOSUPPORT, /* Address family not supported by */
223 /* protocol family */
224 WSAEADDRINUSE, /* Address already in use */
225 WSAEADDRNOTAVAIL, /* Can't assign requested address */
226 WSAENETDOWN, /* Network is down */
227 WSAENETUNREACH, /* Network is unreachable */
228 WSAENETRESET, /* Network dropped connection because */
229 /* of reset */
230 WSAECONNABORTED, /* Software caused connection abort */
231 WSAECONNRESET, /* Connection reset by peer */
232 WSAENOBUFS, /* No buffer space available */
233 WSAEISCONN, /* Socket is already connected */
234 WSAENOTCONN, /* Socket is not connected */
235 WSAESHUTDOWN, /* Can't send after socket shutdown */
236 WSAETOOMANYREFS, /* Too many references: can't splice */
237 WSAETIMEDOUT, /* Connection timed out */
238 WSAECONNREFUSED, /* Connection refused */
239 WSAEHOSTDOWN, /* Host is down */
240 WSAEHOSTUNREACH, /* No route to host */
241 WSAEWOULDBLOCK, /* call would block on non-blocking socket */
242 WSAEALREADY, /* operation already in progress */
243 WSAEINPROGRESS /* operation now in progress */
246 /* reverse map */
247 static oslSocketError osl_SocketErrorFromNative(int nativeType)
249 oslSocketError i= (oslSocketError)0;
251 while(i != osl_Socket_E_InvalidError)
253 if(SocketError[i] == nativeType)
254 return i;
256 i = (oslSocketError)( (int) i + 1);
258 return i;
261 /* macros */
262 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
264 /*****************************************************************************/
265 /* oslSocketDialupImpl */
266 /*****************************************************************************/
267 static oslSocketDialupImpl *pDialupImpl = NULL;
270 * __osl_createSocketDialupImpl.
272 static oslSocketDialupImpl* __osl_createSocketDialupImpl (void)
274 oslSocketDialupImpl *pImpl;
275 pImpl = (oslSocketDialupImpl*)rtl_allocateZeroMemory( sizeof (oslSocketDialupImpl));
277 InitializeCriticalSection (&pImpl->m_hMutex);
279 return (pImpl);
283 * __osl_initSocketDialupImpl.
285 static void __osl_initSocketDialupImpl (oslSocketDialupImpl *pImpl)
287 #ifdef SOCKET_USE_AUTODIAL
288 if (pImpl)
290 HINSTANCE hModule;
292 EnterCriticalSection (&pImpl->m_hMutex);
294 hModule = LoadLibrary (INTERNET_MODULE_NAME);
295 if (!(hModule <= (HINSTANCE)HINSTANCE_ERROR))
297 pImpl->m_pfnAttemptConnect = (INTERNETATTEMPTCONNECT)
298 (GetProcAddress (hModule, "InternetAttemptConnect"));
299 pImpl->m_pfnAutodial = (INTERNETAUTODIAL)
300 (GetProcAddress (hModule, "InternetAutodial"));
301 pImpl->m_pfnAutodialHangup = (INTERNETAUTODIALHANGUP)
302 (GetProcAddress (hModule, "InternetAutodialHangup"));
303 pImpl->m_pfnGetConnectedState = (INTERNETGETCONNECTEDSTATE)
304 (GetProcAddress (hModule, "InternetGetConnectedState"));
305 pImpl->m_hModule = hModule;
308 LeaveCriticalSection (&pImpl->m_hMutex);
310 #else
311 (void)pImpl;
312 #endif
316 * __osl_destroySocketDialupImpl.
318 static void __osl_destroySocketDialupImpl (oslSocketDialupImpl *pImpl)
320 if (pImpl)
322 EnterCriticalSection (&pImpl->m_hMutex);
324 if (pImpl->m_dwFlags & INTERNET_CONNECTION_HANGUP)
326 if (pImpl->m_pfnAutodialHangup)
328 (pImpl->m_pfnAutodialHangup)(0);
329 pImpl->m_dwFlags &= ~INTERNET_CONNECTION_HANGUP;
333 if (pImpl->m_hModule)
334 FreeLibrary (pImpl->m_hModule);
336 LeaveCriticalSection (&pImpl->m_hMutex);
337 DeleteCriticalSection (&pImpl->m_hMutex);
339 rtl_freeMemory (pImpl);
344 * __osl_querySocketDialupImpl.
346 static sal_Bool __osl_querySocketDialupImpl (void)
348 sal_Bool result;
350 if (pDialupImpl == NULL)
352 pDialupImpl = __osl_createSocketDialupImpl();
353 __osl_initSocketDialupImpl (pDialupImpl);
356 EnterCriticalSection (&pDialupImpl->m_hMutex);
358 result = sal_True;
359 if (pDialupImpl->m_pfnGetConnectedState)
361 DWORD dwFlags = 0;
363 result = (sal_Bool)(pDialupImpl->m_pfnGetConnectedState)(&dwFlags, 0);
364 pDialupImpl->m_dwFlags |= dwFlags;
367 LeaveCriticalSection (&pDialupImpl->m_hMutex);
368 return (result);
372 * __osl_attemptSocketDialupImpl.
374 static sal_Bool __osl_attemptSocketDialupImpl (void)
376 sal_Bool result;
378 if (pDialupImpl == NULL)
380 pDialupImpl = __osl_createSocketDialupImpl();
381 __osl_initSocketDialupImpl (pDialupImpl);
384 EnterCriticalSection (&pDialupImpl->m_hMutex);
386 result = __osl_querySocketDialupImpl();
387 if (!result)
389 result = sal_True;
390 if (pDialupImpl->m_pfnAutodial)
392 result = (sal_Bool)(pDialupImpl->m_pfnAutodial)(0, 0);
393 if (result)
394 pDialupImpl->m_dwFlags |= INTERNET_CONNECTION_HANGUP;
395 else
396 WSASetLastError (WSAENETDOWN);
400 LeaveCriticalSection (&pDialupImpl->m_hMutex);
401 return (result);
404 /*****************************************************************************/
405 /* oslSocketImpl */
406 /*****************************************************************************/
407 static sal_uInt32 g_nSocketImpl = 0;
409 #if OSL_DEBUG_LEVEL > 1
410 static sal_uInt32 g_nSocketAddr = 0;
411 struct LeakWarning
413 ~LeakWarning()
415 if( g_nSocketImpl )
416 OSL_TRACE( "sal_socket: %d socket instances leak" , g_nSocketImpl );
417 if( g_nSocketAddr )
418 OSL_TRACE( "sal_socket: %d socket address instances leak" , g_nSocketAddr );
421 LeakWarning socketWarning;
422 #endif
425 * __osl_createSocketImpl.
427 oslSocket __osl_createSocketImpl(SOCKET Socket)
429 oslSocket pSockImpl = (oslSocket) rtl_allocateZeroMemory( sizeof(struct oslSocketImpl));
430 pSockImpl->m_Socket = Socket;
431 pSockImpl->m_nRefCount = 1;
433 g_nSocketImpl++;
435 return (pSockImpl);
439 * __osl_destroySocketImpl.
441 void __osl_destroySocketImpl(oslSocketImpl *pImpl)
443 if (pImpl)
445 if (--g_nSocketImpl == 0)
447 __osl_destroySocketDialupImpl (pDialupImpl);
448 pDialupImpl = NULL;
450 rtl_freeMemory (pImpl);
453 /*****************************************************************************/
454 static oslSocketAddr __osl_createSocketAddr( )
456 oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
457 pAddr->m_nRefCount = 1;
458 #if OSL_DEBUG_LEVEL > 1
459 g_nSocketAddr ++;
460 #endif
461 return pAddr;
464 static oslSocketAddr __osl_createSocketAddrWithFamily(
465 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
467 OSL_ASSERT( family == osl_Socket_FamilyInet );
469 oslSocketAddr pAddr = __osl_createSocketAddr();
470 switch( family )
472 case osl_Socket_FamilyInet:
474 struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
476 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
477 pInetAddr->sin_addr.s_addr = nAddr;
478 pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
479 break;
481 default:
482 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
484 return pAddr;
487 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
489 oslSocketAddr pAddr = __osl_createSocketAddr();
490 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( sockaddr ) );
491 return pAddr;
494 static void __osl_destroySocketAddr( oslSocketAddr addr )
496 #if OSL_DEBUG_LEVEL > 1
497 g_nSocketAddr --;
498 #endif
499 rtl_freeMemory( addr );
501 /*****************************************************************************/
502 /* osl_createEmptySocketAddr */
503 /*****************************************************************************/
504 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
506 oslSocketAddr pAddr = 0;
508 /* is it an internet-Addr? */
509 if (Family == osl_Socket_FamilyInet)
511 pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
513 else
515 pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
518 return pAddr;
521 /*****************************************************************************/
522 /* osl_copySocketAddr */
523 /*****************************************************************************/
524 // @deprecated, to be removed
525 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
527 oslSocketAddr pCopy = 0;
528 if (Addr)
530 pCopy = __osl_createSocketAddr();
532 if (pCopy)
533 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
535 return pCopy;
538 /*****************************************************************************/
539 /* osl_isEqualSocketAddr */
540 /*****************************************************************************/
541 sal_Bool SAL_CALL osl_isEqualSocketAddr(oslSocketAddr Addr1, oslSocketAddr Addr2)
543 OSL_ASSERT(Addr1);
544 OSL_ASSERT(Addr2);
545 struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
546 struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
548 OSL_ASSERT(pAddr1);
549 OSL_ASSERT(pAddr2);
551 if (pAddr1->sa_family == pAddr2->sa_family)
553 switch (pAddr1->sa_family)
555 case AF_INET:
557 struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
558 struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
560 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
561 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
562 (pInetAddr1->sin_port == pInetAddr2->sin_port))
563 return (sal_True);
566 default:
568 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
573 return (sal_False);
576 /*****************************************************************************/
577 /* osl_createInetBroadcastAddr */
578 /*****************************************************************************/
579 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
580 rtl_uString *strDottedAddr,
581 sal_Int32 Port)
583 sal_uInt32 nAddr = OSL_INADDR_NONE;
585 if (strDottedAddr && strDottedAddr->length)
587 /* Dotted host address for limited broadcast */
588 rtl_String *pDottedAddr = NULL;
590 rtl_uString2String (
591 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
592 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
594 nAddr = inet_addr (pDottedAddr->buffer);
595 rtl_string_release (pDottedAddr);
598 if (nAddr != OSL_INADDR_NONE)
600 /* Limited broadcast */
601 nAddr = ntohl(nAddr);
602 if (IN_CLASSA(nAddr))
604 nAddr &= IN_CLASSA_NET;
605 nAddr |= IN_CLASSA_HOST;
607 else if (IN_CLASSB(nAddr))
609 nAddr &= IN_CLASSB_NET;
610 nAddr |= IN_CLASSB_HOST;
612 else if (IN_CLASSC(nAddr))
614 nAddr &= IN_CLASSC_NET;
615 nAddr |= IN_CLASSC_HOST;
617 else
619 /* No broadcast in class D */
620 return ((oslSocketAddr)NULL);
622 nAddr = htonl(nAddr);
625 oslSocketAddr pAddr =
626 __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( (sal_uInt16) Port), nAddr );
627 return pAddr;
630 /*****************************************************************************/
631 /* osl_createInetSocketAddr */
632 /*****************************************************************************/
633 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
634 rtl_uString *strDottedAddr,
635 sal_Int32 Port)
637 sal_uInt32 Addr;
638 rtl_String *pDottedAddr=NULL;
640 rtl_uString2String(
641 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
642 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
644 Addr= inet_addr (pDottedAddr->buffer);
645 rtl_string_release (pDottedAddr);
647 oslSocketAddr pAddr = 0;
648 if(Addr != OSL_INADDR_NONE)
650 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( (sal_uInt16)Port), Addr );
652 return pAddr;
655 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
657 OSL_ASSERT( pAddr );
658 OSL_ASSERT( pByteSeq );
660 oslSocketResult res = osl_Socket_Error;
661 if( pAddr && pByteSeq )
663 OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
664 OSL_ASSERT( pByteSeq->nElements == 4 );
665 struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
666 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
667 res = osl_Socket_Ok;
669 return res;
672 /** Returns the addr field in the struct sockaddr. ppByteSeq is in network byteorder. *ppByteSeq may
673 either be 0 or contain a constructed sal_Sequence.
675 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
677 OSL_ASSERT( pAddr );
678 OSL_ASSERT( ppByteSeq );
680 oslSocketResult res = osl_Socket_Error;
681 if( pAddr && ppByteSeq )
683 struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
684 rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
685 res = osl_Socket_Ok;
687 return res;
690 /*****************************************************************************/
691 /* oslHostAddr */
692 /*****************************************************************************/
693 struct oslHostAddrImpl {
694 rtl_uString *pHostName;
695 oslSocketAddr pSockAddr;
698 static oslHostAddr __osl_hostentToHostAddr (const struct hostent *he)
700 oslHostAddr pAddr= NULL;
701 oslSocketAddr pSocketAddr = 0;
703 rtl_uString *cn= NULL;
705 if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
706 return ((oslHostAddr)NULL);
708 rtl_string2UString(
709 &cn, he->h_name, strlen(he->h_name),
710 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
711 OSL_ASSERT(cn != 0);
713 pSocketAddr = __osl_createSocketAddr();
715 if (pSocketAddr == NULL)
717 rtl_uString_release(cn);
718 return ((oslHostAddr)NULL);
721 pSocketAddr->m_sockaddr.sa_family = he->h_addrtype;
722 if (pSocketAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
724 struct sockaddr_in *sin= (struct sockaddr_in *)&(pSocketAddr->m_sockaddr);
725 memcpy (
726 &(sin->sin_addr.s_addr),
727 he->h_addr_list[0],
728 he->h_length);
730 else
732 /* unknown address family */
733 /* future extensions for new families might be implemented here */
735 OSL_TRACE("_osl_hostentToHostAddr(): unknown address family.");
736 OSL_ASSERT(sal_False);
738 __osl_destroySocketAddr( pSocketAddr );
739 rtl_uString_release(cn);
740 return ((oslHostAddr)NULL);
743 pAddr= (oslHostAddr )rtl_allocateMemory (sizeof (struct oslHostAddrImpl));
745 if (pAddr == NULL)
747 __osl_destroySocketAddr( pSocketAddr );
748 rtl_uString_release(cn);
749 return ((oslHostAddr)NULL);
752 pAddr->pHostName= cn;
753 pAddr->pSockAddr= pSocketAddr;
755 return pAddr;
758 /*****************************************************************************/
759 /* osl_createHostAddr */
760 /*****************************************************************************/
761 oslHostAddr SAL_CALL osl_createHostAddr (
762 rtl_uString *strHostname,
763 const oslSocketAddr pSocketAddr)
765 oslHostAddr pAddr;
766 rtl_uString *cn= NULL;
768 if ((strHostname == NULL) || (strHostname->length == 0) || (pSocketAddr == NULL))
769 return ((oslHostAddr)NULL);
771 rtl_uString_newFromString( &cn, strHostname);
773 if ( ! pSocketAddr )
775 rtl_uString_release(cn);
776 return ((oslHostAddr)NULL);
779 pAddr= (oslHostAddr)rtl_allocateMemory (sizeof (struct oslHostAddrImpl));
781 if (pAddr == NULL)
783 rtl_uString_release(cn);
784 return ((oslHostAddr)NULL);
787 pAddr->pHostName= cn;
788 pAddr->pSockAddr= osl_copySocketAddr( pSocketAddr );
790 return ((oslHostAddr)pAddr);
793 /*****************************************************************************/
794 /* osl_createHostAddrByName */
795 /*****************************************************************************/
796 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *strHostname)
798 if ((strHostname == NULL) || (strHostname->length == 0))
799 return ((oslHostAddr)NULL);
801 if (__osl_attemptSocketDialupImpl())
803 struct hostent *he;
804 rtl_String *Hostname= NULL;
806 rtl_uString2String(
807 &Hostname, strHostname->buffer, strHostname->length,
808 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
810 he= gethostbyname (Hostname->buffer);
812 rtl_string_release (Hostname);
813 return __osl_hostentToHostAddr (he);
815 return ((oslHostAddr)NULL);
818 /*****************************************************************************/
819 /* osl_createHostAddrByAddr */
820 /*****************************************************************************/
821 oslHostAddr SAL_CALL osl_createHostAddrByAddr(const oslSocketAddr pAddr)
823 if (pAddr == NULL)
824 return ((oslHostAddr)NULL);
826 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
828 const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
830 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
831 return ((oslHostAddr)NULL);
833 if (__osl_attemptSocketDialupImpl())
835 struct hostent *he;
836 he= gethostbyaddr ((const sal_Char *)&(sin->sin_addr),
837 sizeof (sin->sin_addr),
838 sin->sin_family);
839 return __osl_hostentToHostAddr (he);
843 return ((oslHostAddr)NULL);
846 /*****************************************************************************/
847 /* osl_copyHostAddr */
848 /*****************************************************************************/
849 oslHostAddr SAL_CALL osl_copyHostAddr(const oslHostAddr Addr)
851 oslHostAddr pAddr= (oslHostAddr)Addr;
853 if (pAddr)
854 return osl_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
855 else
856 return ((oslHostAddr)NULL);
859 /*****************************************************************************/
860 /* osl_getHostnameOfHostAddr */
861 /*****************************************************************************/
862 void SAL_CALL osl_getHostnameOfHostAddr(
863 const oslHostAddr pAddr, rtl_uString **strHostname)
865 if (pAddr)
866 rtl_uString_assign (strHostname, pAddr->pHostName);
867 else
868 rtl_uString_new (strHostname);
871 /*****************************************************************************/
872 /* osl_getSocketAddrOfHostAddr */
873 /*****************************************************************************/
874 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)
876 if (pAddr)
877 return (const oslSocketAddr)(pAddr->pSockAddr);
878 else
879 return NULL;
882 /*****************************************************************************/
883 /* osl_destroyHostAddr */
884 /*****************************************************************************/
885 void SAL_CALL osl_destroyHostAddr(oslHostAddr pAddr)
887 if (pAddr)
889 if (pAddr->pHostName)
890 rtl_uString_release (pAddr->pHostName);
891 if (pAddr->pSockAddr)
892 osl_destroySocketAddr( pAddr->pSockAddr );
894 rtl_freeMemory (pAddr);
898 /*****************************************************************************/
899 /* osl_getLocalHostname */
900 /*****************************************************************************/
901 oslSocketResult SAL_CALL osl_getLocalHostname (rtl_uString **strLocalHostname)
903 static sal_Unicode LocalHostname[256] = {0};
905 if (rtl_ustr_getLength(LocalHostname) == 0)
907 sal_Char Host[256]= "";
908 if (gethostname(Host, sizeof(Host)) == 0)
910 /* check if we have an FQDN */
911 if (strchr(Host, '.') == NULL)
913 oslHostAddr pAddr;
914 rtl_uString *hostName= NULL;
916 rtl_string2UString(
917 &hostName, Host, strlen(Host),
918 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
919 OSL_ASSERT(hostName != 0);
921 /* no, determine it via dns */
922 pAddr = osl_createHostAddrByName(hostName);
923 rtl_uString_release (hostName);
925 if (pAddr && pAddr->pHostName)
926 memcpy(LocalHostname, pAddr->pHostName->buffer, sizeof(sal_Unicode)*(rtl_ustr_getLength(pAddr->pHostName->buffer)+1));
927 else
928 memset(LocalHostname, 0, sizeof(LocalHostname));
930 osl_destroyHostAddr ((oslHostAddr)pAddr);
935 if (rtl_ustr_getLength(LocalHostname) > 0)
937 rtl_uString_newFromStr (strLocalHostname, LocalHostname);
938 return osl_Socket_Ok;
941 return osl_Socket_Error;
944 /*****************************************************************************/
945 /* osl_resolveHostname */
946 /*****************************************************************************/
947 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString* strHostname)
949 oslHostAddr pAddr=
950 (oslHostAddr )osl_createHostAddrByName (strHostname);
951 if (pAddr)
953 oslSocketAddr SockAddr = osl_copySocketAddr( pAddr->pSockAddr );
954 osl_destroyHostAddr(pAddr);
955 return (SockAddr);
957 return ((oslSocketAddr)NULL);
960 /*****************************************************************************/
961 /* osl_getServicePort */
962 /*****************************************************************************/
963 sal_Int32 SAL_CALL osl_getServicePort (
964 rtl_uString* strServicename,
965 rtl_uString* strProtocol)
967 struct servent* ps;
969 rtl_String *str_Servicename=NULL;
970 rtl_String *str_Protocol=NULL;
972 rtl_uString2String(
973 &str_Servicename,
974 rtl_uString_getStr(strServicename),
975 rtl_uString_getLength(strServicename),
976 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
977 rtl_uString2String(
978 &str_Protocol,
979 rtl_uString_getStr(strProtocol),
980 rtl_uString_getLength(strProtocol),
981 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
983 ps= getservbyname(
984 rtl_string_getStr(str_Servicename),
985 rtl_string_getStr(str_Protocol));
987 rtl_string_release( str_Servicename );
988 rtl_string_release( str_Protocol );
990 if (ps != 0)
991 return ntohs(ps->s_port);
993 return OSL_INVALID_PORT;
996 /*****************************************************************************/
997 /* osl_destroySocketAddr */
998 /*****************************************************************************/
999 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1001 __osl_destroySocketAddr( pAddr );
1004 /*****************************************************************************/
1005 /* osl_getFamilyOfSocketAddr */
1006 /*****************************************************************************/
1007 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1009 if (pAddr)
1010 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1011 else
1012 return osl_Socket_FamilyInvalid;
1015 /*****************************************************************************/
1016 /* osl_getInetPortOfSocketAddr */
1017 /*****************************************************************************/
1018 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1020 if( pAddr )
1022 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1024 if ( (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet)))
1025 return ntohs(pSystemInetAddr->sin_port);
1027 return OSL_INVALID_PORT;
1030 /*****************************************************************************/
1031 /* osl_setInetPortOfSocketAddr */
1032 /*****************************************************************************/
1033 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr (
1034 oslSocketAddr pAddr,
1035 sal_Int32 Port)
1037 if (pAddr == NULL)
1038 return sal_False;
1040 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1042 if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1043 return sal_False;
1045 pSystemInetAddr->sin_port= htons((short)Port);
1046 return sal_True;
1049 /*****************************************************************************/
1050 /* osl_getHostnameOfSocketAddr */
1051 /*****************************************************************************/
1052 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr (
1053 oslSocketAddr Addr,
1054 rtl_uString **strHostName)
1056 oslHostAddr pAddr= osl_createHostAddrByAddr (Addr);
1058 if (pAddr)
1060 rtl_uString_newFromString(strHostName, pAddr->pHostName);
1062 osl_destroyHostAddr(pAddr);
1064 return osl_Socket_Ok;
1067 return osl_Socket_Error;
1070 /*****************************************************************************/
1071 /* osl_getDottedInetAddrOfSocketAddr */
1072 /*****************************************************************************/
1073 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr (
1074 oslSocketAddr pAddr,
1075 rtl_uString **strDottedInetAddr)
1077 sal_Char *pDotted;
1079 if (pAddr == NULL)
1080 return osl_Socket_Error;
1082 struct sockaddr_in *pSystemInetAddr = (struct sockaddr_in*) &(pAddr->m_sockaddr);
1083 if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1084 return osl_Socket_Error;
1086 pDotted = inet_ntoa (pSystemInetAddr->sin_addr);
1087 rtl_string2UString(
1088 strDottedInetAddr, pDotted, strlen (pDotted),
1089 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
1090 OSL_ASSERT(*strDottedInetAddr != 0);
1092 return osl_Socket_Ok;
1095 /*****************************************************************************/
1096 /* osl_createSocket */
1097 /*****************************************************************************/
1098 oslSocket SAL_CALL osl_createSocket (
1099 oslAddrFamily Family,
1100 oslSocketType Type,
1101 oslProtocol Protocol)
1103 /* alloc memory */
1104 oslSocket pSocket = __osl_createSocketImpl(0);
1106 if (pSocket == NULL)
1107 return 0;
1109 /* create socket */
1110 pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1111 TYPE_TO_NATIVE(Type),
1112 PROTOCOL_TO_NATIVE(Protocol));
1114 /* creation failed => free memory */
1115 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1117 __osl_destroySocketImpl(pSocket);
1118 pSocket= 0;
1120 else
1122 pSocket->m_Flags = 0;
1125 return pSocket;
1128 void SAL_CALL osl_acquireSocket( oslSocket pSocket )
1130 osl_atomic_increment( &(pSocket->m_nRefCount) );
1133 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1135 if( pSocket && 0 == osl_atomic_decrement( &(pSocket->m_nRefCount) ) )
1137 osl_closeSocket( pSocket );
1138 __osl_destroySocketImpl( pSocket );
1142 /*****************************************************************************/
1143 /* osl_closeSocket */
1144 /*****************************************************************************/
1145 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1147 /* socket already invalid */
1148 if(pSocket==0)
1149 return;
1151 /* close */
1152 closesocket(pSocket->m_Socket);
1154 pSocket->m_Socket = OSL_INVALID_SOCKET;
1157 /*****************************************************************************/
1158 /* osl_getLocalAddrOfSocket */
1159 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1160 /* are the same! I don't like it very much but see no other easy way */
1161 /* to conceal the struct sockaddr from the eyes of the user. */
1162 /*****************************************************************************/
1163 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1165 struct sockaddr Addr;
1166 int AddrLen;
1168 if (pSocket == NULL) /* ENOTSOCK */
1169 return ((oslSocketAddr)NULL);
1171 AddrLen= sizeof(struct sockaddr);
1173 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1174 return ((oslSocketAddr)NULL);
1176 oslSocketAddr pAddr = __osl_createSocketAddrFromSystem( &Addr );
1177 return pAddr;
1180 /*****************************************************************************/
1181 /* osl_getPeerAddrOfSocket */
1182 /*****************************************************************************/
1183 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1185 struct sockaddr Addr;
1186 int AddrLen;
1188 if (pSocket == NULL) /* ENOTSOCK */
1189 return ((oslSocketAddr)NULL);
1191 AddrLen= sizeof(struct sockaddr);
1193 if (getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1194 return ((oslSocketAddr)NULL);
1196 oslSocketAddr pAddr = __osl_createSocketAddrFromSystem( &Addr );
1197 return pAddr;
1200 /*****************************************************************************/
1201 /* osl_bindAddrToSocket */
1202 /*****************************************************************************/
1203 sal_Bool SAL_CALL osl_bindAddrToSocket ( oslSocket pSocket, oslSocketAddr pAddr)
1205 OSL_ASSERT( pAddr );
1207 if (pSocket == NULL) /* ENOTSOCK */
1208 return sal_False;
1210 return (bind(pSocket->m_Socket,
1211 &(pAddr->m_sockaddr),
1212 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR);
1215 /*****************************************************************************/
1216 /* osl_connectSocketTo */
1217 /*****************************************************************************/
1218 oslSocketResult SAL_CALL osl_connectSocketTo (
1219 oslSocket pSocket,
1220 oslSocketAddr pAddr,
1221 const TimeValue* pTimeout)
1224 if (pSocket == NULL) /* ENOTSOCK */
1225 return osl_Socket_Error;
1227 if (pAddr == NULL) /* EDESTADDRREQ */
1228 return osl_Socket_Error;
1230 if (!__osl_attemptSocketDialupImpl()) /* ENETDOWN */
1231 return osl_Socket_Error;
1233 if (pTimeout == NULL)
1235 if(connect(pSocket->m_Socket,
1236 &(pAddr->m_sockaddr),
1237 sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
1238 return osl_Socket_Error;
1239 else
1240 return osl_Socket_Ok;
1242 else
1244 fd_set fds;
1245 int error;
1246 struct timeval tv;
1247 unsigned long Param;
1248 oslSocketResult Result= osl_Socket_Ok;
1250 if (pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING)
1252 if (connect(pSocket->m_Socket,
1253 &(pAddr->m_sockaddr),
1254 sizeof(struct sockaddr)) == OSL_SOCKET_ERROR)
1256 switch (WSAGetLastError())
1258 case WSAEWOULDBLOCK:
1259 case WSAEINPROGRESS:
1260 return osl_Socket_InProgress;
1262 default:
1263 return osl_Socket_Error;
1266 else
1267 return osl_Socket_Ok;
1270 /* set socket temporarily to non-blocking */
1271 Param= 1;
1272 OSL_VERIFY(ioctlsocket(
1273 pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
1275 /* initiate connect */
1276 if (connect(pSocket->m_Socket,
1277 &(pAddr->m_sockaddr),
1278 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1280 /* immediate connection */
1282 Param= 0;
1283 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1285 return osl_Socket_Ok;
1287 else
1289 error = WSAGetLastError();
1291 /* really an error or just delayed? */
1292 if (error != WSAEWOULDBLOCK && error != WSAEINPROGRESS)
1294 Param= 0;
1295 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1297 return osl_Socket_Error;
1301 /* prepare select set for socket */
1302 FD_ZERO(&fds);
1303 FD_SET(pSocket->m_Socket, &fds);
1305 /* divide milliseconds into seconds and microseconds */
1306 tv.tv_sec= pTimeout->Seconds;
1307 tv.tv_usec= pTimeout->Nanosec / 1000L;
1309 /* select */
1310 error= select(pSocket->m_Socket+1,
1312 &fds,
1314 &tv);
1316 if (error > 0) /* connected */
1318 OSL_POSTCOND(
1319 FD_ISSET(pSocket->m_Socket, &fds),
1320 "osl_connectSocketTo(): select returned but socket not set\n");
1322 Result= osl_Socket_Ok;
1325 else if(error < 0) /* error */
1327 /* errno == EBADF: most probably interrupted by close() */
1328 if(WSAGetLastError() == WSAEBADF)
1330 /* do not access pSockImpl because it is about to be or */
1331 /* already destroyed */
1332 return osl_Socket_Interrupted;
1334 else
1335 Result= osl_Socket_Error;
1338 else /* timeout */
1339 Result= osl_Socket_TimedOut;
1342 /* clean up */
1343 Param= 0;
1344 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1346 return Result;
1350 /*****************************************************************************/
1351 /* osl_listenOnSocket */
1352 /*****************************************************************************/
1353 sal_Bool SAL_CALL osl_listenOnSocket (
1354 oslSocket pSocket,
1355 sal_Int32 MaxPendingConnections)
1357 if (pSocket == NULL) /* ENOTSOCK */
1358 return sal_False;
1360 return (listen(pSocket->m_Socket,
1361 MaxPendingConnections == -1 ?
1362 SOMAXCONN :
1363 MaxPendingConnections) != OSL_SOCKET_ERROR);
1366 /*****************************************************************************/
1367 /* osl_acceptConnectionOnSocket */
1368 /*****************************************************************************/
1369 oslSocket SAL_CALL osl_acceptConnectionOnSocket (
1370 oslSocket pSocket,
1371 oslSocketAddr* ppAddr)
1373 if (pSocket == NULL) /* ENOTSOCK */
1374 return ((oslSocket)NULL);
1376 SOCKET Connection;
1377 if(ppAddr)
1379 if( *ppAddr )
1381 osl_destroySocketAddr( *ppAddr );
1382 *ppAddr = 0;
1384 int AddrLen= sizeof(struct sockaddr);
1386 /* user wants to know peer Addr */
1387 struct sockaddr Addr;
1389 Connection= accept(pSocket->m_Socket, &Addr, &AddrLen);
1390 OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
1392 if(Connection != static_cast<SOCKET>(OSL_SOCKET_ERROR))
1393 *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
1394 else
1395 *ppAddr = NULL;
1397 else
1399 /* user is not interested in peer-addr */
1400 Connection= accept(pSocket->m_Socket, 0, 0);
1403 /* accept failed? */
1404 if(Connection == static_cast<SOCKET>(OSL_SOCKET_ERROR))
1405 return ((oslSocket)NULL);
1407 /* alloc memory */
1408 oslSocket pConnectionSocket;
1409 pConnectionSocket= __osl_createSocketImpl(Connection);
1411 pConnectionSocket->m_Flags = 0;
1413 return pConnectionSocket;
1416 /*****************************************************************************/
1417 /* osl_receiveSocket */
1418 /*****************************************************************************/
1419 sal_Int32 SAL_CALL osl_receiveSocket (
1420 oslSocket pSocket,
1421 void* pBuffer,
1422 sal_uInt32 BytesToRead,
1423 oslSocketMsgFlag Flag)
1425 if (pSocket == NULL) /* ENOTSOCK */
1426 return osl_Socket_Error;
1428 return recv(pSocket->m_Socket,
1429 (sal_Char*)pBuffer,
1430 BytesToRead,
1431 MSG_FLAG_TO_NATIVE(Flag));
1434 /*****************************************************************************/
1435 /* osl_receiveFromSocket */
1436 /*****************************************************************************/
1437 sal_Int32 SAL_CALL osl_receiveFromSocket (
1438 oslSocket pSocket,
1439 oslSocketAddr SenderAddr,
1440 void* pBuffer,
1441 sal_uInt32 BufferSize,
1442 oslSocketMsgFlag Flag)
1444 struct sockaddr *pSystemSockAddr = 0;
1445 int AddrLen = 0;
1446 if( SenderAddr )
1448 AddrLen = sizeof( struct sockaddr );
1449 pSystemSockAddr = &(SenderAddr->m_sockaddr);
1452 if (pSocket == NULL) /* ENOTSOCK */
1453 return osl_Socket_Error;
1455 return recvfrom(pSocket->m_Socket,
1456 (sal_Char*)pBuffer,
1457 BufferSize,
1458 MSG_FLAG_TO_NATIVE(Flag),
1459 pSystemSockAddr,
1460 &AddrLen);
1463 /*****************************************************************************/
1464 /* osl_sendSocket */
1465 /*****************************************************************************/
1466 sal_Int32 SAL_CALL osl_sendSocket (
1467 oslSocket pSocket,
1468 const void* pBuffer,
1469 sal_uInt32 BytesToSend,
1470 oslSocketMsgFlag Flag)
1472 if (pSocket == NULL) /* ENOTSOCK */
1473 return osl_Socket_Error;
1475 return send(pSocket->m_Socket,
1476 (sal_Char*)pBuffer,
1477 BytesToSend,
1478 MSG_FLAG_TO_NATIVE(Flag));
1481 /*****************************************************************************/
1482 /* osl_sendToSocket */
1483 /*****************************************************************************/
1484 sal_Int32 SAL_CALL osl_sendToSocket (
1485 oslSocket pSocket,
1486 oslSocketAddr ReceiverAddr,
1487 const void* pBuffer,
1488 sal_uInt32 BytesToSend,
1489 oslSocketMsgFlag Flag)
1491 if (pSocket == NULL) /* ENOTSOCK */
1492 return osl_Socket_Error;
1494 /* ReceiverAddr might be 0 when used on a connected socket. */
1495 /* Then sendto should behave like send. */
1497 struct sockaddr *pSystemSockAddr = 0;
1498 if( ReceiverAddr )
1499 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1501 return sendto(pSocket->m_Socket,
1502 (sal_Char*)pBuffer,
1503 BytesToSend,
1504 MSG_FLAG_TO_NATIVE(Flag),
1505 pSystemSockAddr,
1506 pSystemSockAddr == 0 ? 0 : sizeof(struct sockaddr));
1509 /*****************************************************************************/
1510 /* osl_readSocket */
1511 /*****************************************************************************/
1512 sal_Int32 SAL_CALL osl_readSocket( oslSocket pSocket, void *pBuffer, sal_Int32 n )
1514 sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
1516 OSL_ASSERT( pSocket);
1518 /* loop until all desired bytes were read or an error occurred */
1519 sal_uInt32 BytesRead= 0;
1520 sal_uInt32 BytesToRead= n;
1521 while (BytesToRead > 0)
1523 sal_Int32 RetVal;
1524 RetVal= osl_receiveSocket(pSocket,
1525 Ptr,
1526 BytesToRead,
1527 osl_Socket_MsgNormal);
1529 /* error occurred? */
1530 if(RetVal <= 0)
1532 break;
1535 BytesToRead -= RetVal;
1536 BytesRead += RetVal;
1537 Ptr += RetVal;
1540 return BytesRead;
1543 /*****************************************************************************/
1544 /* osl_writeSocket */
1545 /*****************************************************************************/
1546 sal_Int32 SAL_CALL osl_writeSocket( oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1548 OSL_ASSERT( pSocket );
1550 /* loop until all desired bytes were send or an error occurred */
1551 sal_uInt32 BytesSend= 0;
1552 sal_uInt32 BytesToSend= n;
1553 sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
1554 while (BytesToSend > 0)
1556 sal_Int32 RetVal;
1558 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1560 /* error occurred? */
1561 if(RetVal <= 0)
1563 break;
1566 BytesToSend -= RetVal;
1567 BytesSend += RetVal;
1568 Ptr += RetVal;
1571 return BytesSend;
1575 /*****************************************************************************/
1576 /* osl_isReceiveReady */
1577 /*****************************************************************************/
1578 sal_Bool SAL_CALL osl_isReceiveReady (
1579 oslSocket pSocket,
1580 const TimeValue* pTimeout)
1582 fd_set fds;
1583 struct timeval tv;
1585 if (pSocket == NULL) /* ENOTSOCK */
1586 return sal_False;
1588 FD_ZERO(&fds);
1589 FD_SET(pSocket->m_Socket, &fds);
1591 if (pTimeout)
1593 tv.tv_sec = pTimeout->Seconds;
1594 tv.tv_usec = pTimeout->Nanosec / 1000L;
1597 return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
1598 &fds, /* check read operations */
1599 0, /* check write ops */
1600 0, /* ckeck for OOB */
1601 (pTimeout) ? &tv : 0)==1); /* use timeout? */
1604 /*****************************************************************************/
1605 /* osl_isSendReady */
1606 /*****************************************************************************/
1607 sal_Bool SAL_CALL osl_isSendReady (
1608 oslSocket pSocket,
1609 const TimeValue* pTimeout)
1611 fd_set fds;
1612 struct timeval tv;
1614 if (pSocket == NULL) /* ENOTSOCK */
1615 return sal_False;
1617 FD_ZERO(&fds);
1618 FD_SET(pSocket->m_Socket, &fds);
1620 if (pTimeout)
1622 tv.tv_sec = pTimeout->Seconds;
1623 tv.tv_usec = pTimeout->Nanosec / 1000L;
1626 return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
1627 0, /* check read operations */
1628 &fds, /* check write ops */
1629 0, /* ckeck for OOB */
1630 (pTimeout) ? &tv : 0)==1); /* use timeout? */
1633 /*****************************************************************************/
1634 /* osl_isExceptionPending */
1635 /*****************************************************************************/
1636 sal_Bool SAL_CALL osl_isExceptionPending (
1637 oslSocket pSocket,
1638 const TimeValue* pTimeout)
1640 fd_set fds;
1641 struct timeval tv;
1643 if (pSocket == NULL) /* ENOTSOCK */
1644 return sal_False;
1646 FD_ZERO(&fds);
1647 FD_SET(pSocket->m_Socket, &fds);
1649 if (pTimeout)
1651 tv.tv_sec = pTimeout->Seconds;
1652 tv.tv_usec = pTimeout->Nanosec / 1000L;
1655 return (select(pSocket->m_Socket + 1, /* no of sockets to monitor */
1656 0, /* check read operations */
1657 0, /* check write ops */
1658 &fds, /* ckeck for OOB */
1659 (pTimeout) ? &tv : 0)==1); /* use timeout? */
1662 /*****************************************************************************/
1663 /* osl_shutdownSocket */
1664 /*****************************************************************************/
1665 sal_Bool SAL_CALL osl_shutdownSocket (
1666 oslSocket pSocket,
1667 oslSocketDirection Direction)
1669 if (pSocket == NULL) /* ENOTSOCK */
1670 return sal_False;
1672 return (shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction))==0);
1675 /*****************************************************************************/
1676 /* osl_getSocketOption */
1677 /*****************************************************************************/
1678 sal_Int32 SAL_CALL osl_getSocketOption (
1679 oslSocket pSocket,
1680 oslSocketOptionLevel Level,
1681 oslSocketOption Option,
1682 void* pBuffer,
1683 sal_uInt32 BufferLen)
1685 if (pSocket == NULL) /* ENOTSOCK */
1686 return osl_Socket_Error;
1688 if (getsockopt(pSocket->m_Socket,
1689 OPTION_LEVEL_TO_NATIVE(Level),
1690 OPTION_TO_NATIVE(Option),
1691 (sal_Char*)pBuffer,
1692 (int*)&BufferLen) == -1)
1694 return -1;
1697 return (sal_Int32)BufferLen;
1700 /*****************************************************************************/
1701 /* osl_setSocketOption */
1702 /*****************************************************************************/
1703 sal_Bool SAL_CALL osl_setSocketOption (
1704 oslSocket pSocket,
1705 oslSocketOptionLevel Level,
1706 oslSocketOption Option,
1707 void* pBuffer,
1708 sal_uInt32 BufferLen)
1710 if (pSocket == NULL) /* ENOTSOCK */
1711 return sal_False;
1713 return(setsockopt(pSocket->m_Socket,
1714 OPTION_LEVEL_TO_NATIVE(Level),
1715 OPTION_TO_NATIVE(Option),
1716 (sal_Char*)pBuffer,
1717 BufferLen) == 0);
1720 /*****************************************************************************/
1721 /* osl_enableNonBlockingMode */
1722 /*****************************************************************************/
1723 sal_Bool SAL_CALL osl_enableNonBlockingMode ( oslSocket pSocket, sal_Bool On)
1725 unsigned long Param= On ? 1 : 0;
1727 if (pSocket == NULL) /* ENOTSOCK */
1728 return sal_False;
1730 pSocket->m_Flags = Param ?
1731 (pSocket->m_Flags | OSL_SOCKET_FLAGS_NONBLOCKING) :
1732 (pSocket->m_Flags & ~OSL_SOCKET_FLAGS_NONBLOCKING) ;
1734 return (
1735 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
1738 /*****************************************************************************/
1739 /* osl_isNonBlockingMode */
1740 /*****************************************************************************/
1741 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
1743 if (pSocket == NULL) /* ENOTSOCK */
1744 return sal_False;
1746 return (sal_Bool)((pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING) != 0);
1749 /*****************************************************************************/
1750 /* osl_getSocketType */
1751 /*****************************************************************************/
1752 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
1754 int Type=0;
1755 int TypeSize= sizeof(Type);
1757 if (pSocket == NULL) /* ENOTSOCK */
1758 return osl_Socket_TypeInvalid;
1760 if(getsockopt(pSocket->m_Socket,
1761 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
1762 OPTION_TO_NATIVE(osl_Socket_OptionType),
1763 (sal_Char *)&Type,
1764 &TypeSize) == -1)
1766 /* error */
1767 return osl_Socket_TypeInvalid;
1770 return TYPE_FROM_NATIVE(Type);
1773 /*****************************************************************************/
1774 /* osl_getLastSocketErrorDescription */
1775 /*****************************************************************************/
1776 void SAL_CALL osl_getLastSocketErrorDescription (
1777 oslSocket /*Socket*/,
1778 rtl_uString **strError)
1780 int error;
1782 switch(error = WSAGetLastError())
1784 case WSAENOTSOCK:
1785 rtl_uString_newFromAscii (strError, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1786 break;
1788 case WSAEDESTADDRREQ:
1789 rtl_uString_newFromAscii (strError, "WSAEDESTADDRREQ, Destination Addr required");
1790 break;
1792 case WSAEMSGSIZE:
1793 rtl_uString_newFromAscii (strError, "WSAEMSGSIZE, Message too long");
1794 break;
1796 case WSAEPROTOTYPE:
1797 rtl_uString_newFromAscii (strError, "WSAEPROTOTYPE, Protocol wrong type for socket");
1798 break;
1800 case WSAENOPROTOOPT:
1801 rtl_uString_newFromAscii (strError, "WSAENOPROTOOPT, Protocol not available");
1802 break;
1804 case WSAEPROTONOSUPPORT:
1805 rtl_uString_newFromAscii (strError, "WSAEPROTONOSUPPORT, Protocol not supported");
1806 break;
1808 case WSAESOCKTNOSUPPORT:
1809 rtl_uString_newFromAscii (strError, "WSAESOCKTNOSUPPORT, Socket type not supported");
1810 break;
1812 case WSAEOPNOTSUPP:
1813 rtl_uString_newFromAscii (strError, "WSAEOPNOTSUPP, Operation not supported on socket");
1814 break;
1816 case WSAEPFNOSUPPORT:
1817 rtl_uString_newFromAscii (strError, "WSAEPFNOSUPPORT, Protocol family not supported");
1818 break;
1820 case WSAEAFNOSUPPORT:
1821 rtl_uString_newFromAscii (strError, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1822 break;
1824 case WSAEADDRINUSE:
1825 rtl_uString_newFromAscii (strError, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1826 break;
1828 case WSAEADDRNOTAVAIL:
1829 rtl_uString_newFromAscii (strError, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1830 break;
1832 case WSAENETDOWN:
1833 rtl_uString_newFromAscii (strError, "WSAENETDOWN, Network is down");
1834 break;
1836 case WSAENETUNREACH:
1837 rtl_uString_newFromAscii (strError, "WSAENETUNREACH, Network is unreachable");
1838 break;
1840 case WSAENETRESET:
1841 rtl_uString_newFromAscii (strError, "WSAENETRESET, Network dropped connection or reset");
1842 break;
1844 case WSAECONNABORTED:
1845 rtl_uString_newFromAscii (strError, "WSAECONNABORTED, Software caused connection abort");
1846 break;
1848 case WSAECONNRESET:
1849 rtl_uString_newFromAscii (strError, "WSAECONNRESET, Connection reset by peer");
1850 break;
1852 case WSAENOBUFS:
1853 rtl_uString_newFromAscii (strError, "WSAENOBUFS, No buffer space available.");
1854 break;
1856 case WSAEISCONN:
1857 rtl_uString_newFromAscii (strError, "WSAEISCONN, Socket is already connected");
1858 break;
1860 case WSAENOTCONN:
1861 rtl_uString_newFromAscii (strError, "WSAENOTCONN, Socket is not connected");
1862 break;
1864 case WSAESHUTDOWN:
1865 rtl_uString_newFromAscii (strError, "WSAESHUTDOWN, Can't send after socket shutdown");
1866 break;
1868 case WSAETIMEDOUT:
1869 rtl_uString_newFromAscii (strError, "WSAETIMEDOUT, Connection timed out");
1870 break;
1872 case WSAECONNREFUSED:
1873 rtl_uString_newFromAscii (strError, "WSAECONNREFUSED, Connection refused");
1874 break;
1876 case WSAEHOSTDOWN:
1877 rtl_uString_newFromAscii (strError, "WSAEHOSTDOWN, Networking subsystem not started");
1878 break;
1880 case WSAEHOSTUNREACH:
1881 rtl_uString_newFromAscii (strError, "WSAEHOSTUNREACH, No route to host");
1882 break;
1884 case WSAEWOULDBLOCK:
1885 rtl_uString_newFromAscii (strError, "WSAEWOULDBLOCK, Operation would block");
1886 break;
1888 case WSAEINPROGRESS:
1889 rtl_uString_newFromAscii (strError, "WSAEINPROGRESS, Operation now in progress");
1890 break;
1892 case WSAEALREADY:
1893 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation already in progress");
1894 break;
1896 case WSAEINTR:
1897 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation was interrupted");
1898 break;
1900 case WSAEBADF:
1901 rtl_uString_newFromAscii (strError, "WSAEBADF, Bad file number");
1902 break;
1904 case WSAEACCES:
1905 rtl_uString_newFromAscii (strError, "WSAEACCES, Access is denied");
1906 break;
1908 case WSAEFAULT:
1909 rtl_uString_newFromAscii (strError, "WSAEFAULT, Bad memory Addr");
1910 break;
1912 case WSAEINVAL:
1913 rtl_uString_newFromAscii (strError, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1914 break;
1916 case WSAEMFILE:
1917 rtl_uString_newFromAscii (strError, "WSAEMFILE, No more file descriptors are available");
1918 break;
1920 case WSAETOOMANYREFS:
1921 rtl_uString_newFromAscii (strError, "WSAETOOMANYREFS, Undocumented WinSock error");
1922 break;
1924 case WSAENAMETOOLONG:
1925 rtl_uString_newFromAscii (strError, "WSAENAMETOOLONG, Undocumented WinSock error");
1926 break;
1928 case WSAENOTEMPTY:
1929 rtl_uString_newFromAscii (strError, "WSAENOTEMPTY, Undocumented WinSock error");
1930 break;
1932 case WSAEPROCLIM:
1933 rtl_uString_newFromAscii (strError, "WSAEPROCLIM, Undocumented WinSock error");
1934 break;
1936 case WSAEUSERS:
1937 rtl_uString_newFromAscii (strError, "WSAEUSERS, Undocumented WinSock error");
1938 break;
1940 case WSAEDQUOT:
1941 rtl_uString_newFromAscii (strError, "WSAEDQUOT, Undocumented WinSock error");
1942 break;
1944 case WSAESTALE:
1945 rtl_uString_newFromAscii (strError, "WSAESTALE, Undocumented WinSock error");
1946 break;
1948 case WSAEREMOTE:
1949 rtl_uString_newFromAscii (strError, "WSAEREMOTE, Undocumented WinSock error");
1950 break;
1952 case WSAEDISCON:
1953 rtl_uString_newFromAscii (strError, "WSAEDISCON, Circuit was gracefully terminated");
1954 break;
1956 case WSASYSNOTREADY:
1957 rtl_uString_newFromAscii (strError, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
1958 break;
1960 case WSAVERNOTSUPPORTED:
1961 rtl_uString_newFromAscii (strError, "WSAVERNOTSUPPORTED, The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation");
1962 break;
1964 case WSANOTINITIALISED:
1965 rtl_uString_newFromAscii (strError, "WSANOTINITIALISED, WSAStartup() has not been called");
1966 break;
1968 case WSAHOST_NOT_FOUND:
1969 rtl_uString_newFromAscii (strError, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
1970 break;
1972 case WSATRY_AGAIN:
1973 rtl_uString_newFromAscii (strError, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
1974 break;
1976 case WSANO_RECOVERY:
1977 rtl_uString_newFromAscii (strError, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1978 break;
1980 case WSANO_DATA:
1981 rtl_uString_newFromAscii (strError, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
1982 break;
1984 default:
1986 sal_Unicode message[128];
1988 wsprintfW(reinterpret_cast<LPWSTR>(message), L"Unknown WinSock Error Number %d", error);
1989 rtl_uString_newFromStr (strError, message);
1992 return;
1997 /*****************************************************************************/
1998 /* osl_getLastSocketError */
1999 /*****************************************************************************/
2000 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket /*Socket*/)
2002 return ERROR_FROM_NATIVE(WSAGetLastError());
2005 /*****************************************************************************/
2006 /* SocketSet */
2007 /*****************************************************************************/
2008 typedef struct _TSocketSetImpl
2010 fd_set m_Set; /* the set of descriptors */
2012 } TSocketSetImpl;
2014 /*****************************************************************************/
2015 /* osl_createSocketSet */
2016 /*****************************************************************************/
2017 oslSocketSet SAL_CALL osl_createSocketSet()
2019 TSocketSetImpl* pSet;
2021 pSet = (TSocketSetImpl*) rtl_allocateMemory(sizeof(TSocketSetImpl));
2023 if(pSet)
2025 FD_ZERO(&pSet->m_Set);
2028 return (oslSocketSet)pSet;
2031 /*****************************************************************************/
2032 /* osl_destroySocketSet */
2033 /*****************************************************************************/
2034 void SAL_CALL osl_destroySocketSet (oslSocketSet Set)
2036 if(Set)
2037 rtl_freeMemory(Set);
2040 /*****************************************************************************/
2041 /* osl_clearSocketSet */
2042 /*****************************************************************************/
2043 void SAL_CALL osl_clearSocketSet (oslSocketSet Set)
2045 TSocketSetImpl* pSet;
2047 pSet= (TSocketSetImpl*)Set;
2049 if (pSet)
2050 FD_ZERO(&pSet->m_Set);
2053 /*****************************************************************************/
2054 /* osl_addToSocketSet */
2055 /*****************************************************************************/
2056 void SAL_CALL osl_addToSocketSet (
2057 oslSocketSet Set,
2058 oslSocket Socket)
2060 TSocketSetImpl* pSet;
2061 oslSocketImpl* pSockImpl;
2063 pSet= (TSocketSetImpl*)Set;
2064 pSockImpl= (oslSocketImpl*)Socket;
2066 if (pSet && pSockImpl)
2067 FD_SET(pSockImpl->m_Socket, &pSet->m_Set);
2070 /*****************************************************************************/
2071 /* osl_removeFromSocketSet */
2072 /*****************************************************************************/
2073 void SAL_CALL osl_removeFromSocketSet (
2074 oslSocketSet Set,
2075 oslSocket Socket)
2077 TSocketSetImpl* pSet;
2078 oslSocketImpl* pSockImpl;
2080 pSet= (TSocketSetImpl*)Set;
2081 pSockImpl= (oslSocketImpl*)Socket;
2083 if (pSet && pSockImpl)
2084 FD_CLR(pSockImpl->m_Socket, &pSet->m_Set);
2087 /*****************************************************************************/
2088 /* osl_isInSocketSet */
2089 /*****************************************************************************/
2090 sal_Bool SAL_CALL osl_isInSocketSet (
2091 oslSocketSet Set,
2092 oslSocket Socket)
2094 TSocketSetImpl* pSet;
2095 oslSocketImpl* pSockImpl;
2097 pSet= (TSocketSetImpl*)Set;
2098 pSockImpl= (oslSocketImpl*)Socket;
2100 if (pSet && pSockImpl)
2101 return (FD_ISSET(pSockImpl->m_Socket, &pSet->m_Set) != 0);
2102 else
2103 return sal_False;
2106 /*****************************************************************************/
2107 /* osl_demultiplexSocketEvents */
2108 /*****************************************************************************/
2109 sal_Int32 SAL_CALL osl_demultiplexSocketEvents (
2110 oslSocketSet IncomingSet,
2111 oslSocketSet OutgoingSet,
2112 oslSocketSet OutOfBandSet,
2113 const TimeValue* pTimeout)
2115 int MaxHandle= 0;
2116 struct timeval tv;
2117 TSocketSetImpl* pInSet;
2118 TSocketSetImpl* pOutSet;
2119 TSocketSetImpl* pOOBSet;
2121 if(pTimeout)
2123 /* divide milliseconds into seconds and microseconds */
2124 tv.tv_sec = pTimeout->Seconds;
2125 tv.tv_usec = pTimeout->Nanosec / 1000L;
2128 /* map opaque data to impl-types */
2129 pInSet= (TSocketSetImpl*)IncomingSet;
2130 pOutSet= (TSocketSetImpl*)OutgoingSet;
2131 pOOBSet= (TSocketSetImpl*)OutOfBandSet;
2133 return select(MaxHandle, /* redundant in WIN32 */
2134 pInSet ? &pInSet->m_Set : 0,
2135 pOutSet ? &pOutSet->m_Set : 0,
2136 pOOBSet ? &pOOBSet->m_Set : 0,
2137 pTimeout ? &tv : 0);
2142 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */