1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
23 #include <osl/socket.h>
24 #include <osl/diagnose.h>
25 #include <rtl/alloc.h>
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
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 /*****************************************************************************/
65 static DWORD FamilyMap
[]= {
66 AF_INET
, /* osl_Socket_FamilyInet */
67 AF_IPX
, /* osl_Socket_FamilyIpx */
68 0 /* osl_Socket_FamilyInvalid */
72 static oslAddrFamily
osl_AddrFamilyFromNative(DWORD nativeType
)
74 oslAddrFamily i
= (oslAddrFamily
) 0;
75 while(i
!= osl_Socket_FamilyInvalid
)
77 if(FamilyMap
[i
] == nativeType
)
79 i
= (oslAddrFamily
) ( (int)i
+ 1);
85 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
86 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
88 /*****************************************************************************/
89 /* enum oslProtocol */
90 /*****************************************************************************/
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 */
102 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
104 /*****************************************************************************/
105 /* enum oslSocketType */
106 /*****************************************************************************/
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 */
119 static oslSocketType
osl_SocketTypeFromNative(DWORD nativeType
)
121 oslSocketType i
= (oslSocketType
)0;
122 while(i
!= osl_Socket_TypeInvalid
)
124 if(TypeMap
[i
] == nativeType
)
126 i
= (oslSocketType
)((int)i
+1);
132 #define TYPE_TO_NATIVE(x) TypeMap[x]
133 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
135 /*****************************************************************************/
136 /* enum oslSocketOption */
137 /*****************************************************************************/
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 */
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 */
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 */
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 */
204 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
206 /*****************************************************************************/
207 /* enum oslSocketError */
208 /*****************************************************************************/
210 static int SocketError
[]= {
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 */
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 */
247 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
249 oslSocketError i
= (oslSocketError
)0;
251 while(i
!= osl_Socket_E_InvalidError
)
253 if(SocketError
[i
] == nativeType
)
256 i
= (oslSocketError
)( (int) i
+ 1);
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
);
283 * __osl_initSocketDialupImpl.
285 static void __osl_initSocketDialupImpl (oslSocketDialupImpl
*pImpl
)
287 #ifdef SOCKET_USE_AUTODIAL
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
);
316 * __osl_destroySocketDialupImpl.
318 static void __osl_destroySocketDialupImpl (oslSocketDialupImpl
*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)
350 if (pDialupImpl
== NULL
)
352 pDialupImpl
= __osl_createSocketDialupImpl();
353 __osl_initSocketDialupImpl (pDialupImpl
);
356 EnterCriticalSection (&pDialupImpl
->m_hMutex
);
359 if (pDialupImpl
->m_pfnGetConnectedState
)
363 result
= (sal_Bool
)(pDialupImpl
->m_pfnGetConnectedState
)(&dwFlags
, 0);
364 pDialupImpl
->m_dwFlags
|= dwFlags
;
367 LeaveCriticalSection (&pDialupImpl
->m_hMutex
);
372 * __osl_attemptSocketDialupImpl.
374 static sal_Bool
__osl_attemptSocketDialupImpl (void)
378 if (pDialupImpl
== NULL
)
380 pDialupImpl
= __osl_createSocketDialupImpl();
381 __osl_initSocketDialupImpl (pDialupImpl
);
384 EnterCriticalSection (&pDialupImpl
->m_hMutex
);
386 result
= __osl_querySocketDialupImpl();
390 if (pDialupImpl
->m_pfnAutodial
)
392 result
= (sal_Bool
)(pDialupImpl
->m_pfnAutodial
)(0, 0);
394 pDialupImpl
->m_dwFlags
|= INTERNET_CONNECTION_HANGUP
;
396 WSASetLastError (WSAENETDOWN
);
400 LeaveCriticalSection (&pDialupImpl
->m_hMutex
);
404 /*****************************************************************************/
406 /*****************************************************************************/
407 static sal_uInt32 g_nSocketImpl
= 0;
409 #if OSL_DEBUG_LEVEL > 1
410 static sal_uInt32 g_nSocketAddr
= 0;
416 OSL_TRACE( "sal_socket: %d socket instances leak" , g_nSocketImpl
);
418 OSL_TRACE( "sal_socket: %d socket address instances leak" , g_nSocketAddr
);
421 LeakWarning socketWarning
;
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;
439 * __osl_destroySocketImpl.
441 void __osl_destroySocketImpl(oslSocketImpl
*pImpl
)
445 if (--g_nSocketImpl
== 0)
447 __osl_destroySocketDialupImpl (pDialupImpl
);
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
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();
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);
482 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
487 static oslSocketAddr
__osl_createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
489 oslSocketAddr pAddr
= __osl_createSocketAddr();
490 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( sockaddr
) );
494 static void __osl_destroySocketAddr( oslSocketAddr addr
)
496 #if OSL_DEBUG_LEVEL > 1
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
) );
515 pAddr
= __osl_createSocketAddrWithFamily( Family
, 0 , 0 );
521 /*****************************************************************************/
522 /* osl_copySocketAddr */
523 /*****************************************************************************/
524 // @deprecated, to be removed
525 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
527 oslSocketAddr pCopy
= 0;
530 pCopy
= __osl_createSocketAddr();
533 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
538 /*****************************************************************************/
539 /* osl_isEqualSocketAddr */
540 /*****************************************************************************/
541 sal_Bool SAL_CALL
osl_isEqualSocketAddr(oslSocketAddr Addr1
, oslSocketAddr Addr2
)
545 struct sockaddr
* pAddr1
= &(Addr1
->m_sockaddr
);
546 struct sockaddr
* pAddr2
= &(Addr2
->m_sockaddr
);
551 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
553 switch (pAddr1
->sa_family
)
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
))
568 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
576 /*****************************************************************************/
577 /* osl_createInetBroadcastAddr */
578 /*****************************************************************************/
579 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
580 rtl_uString
*strDottedAddr
,
583 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
585 if (strDottedAddr
&& strDottedAddr
->length
)
587 /* Dotted host address for limited broadcast */
588 rtl_String
*pDottedAddr
= NULL
;
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
;
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
);
630 /*****************************************************************************/
631 /* osl_createInetSocketAddr */
632 /*****************************************************************************/
633 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
634 rtl_uString
*strDottedAddr
,
638 rtl_String
*pDottedAddr
=NULL
;
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
);
655 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
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 );
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
)
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);
690 /*****************************************************************************/
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
);
709 &cn
, he
->h_name
, strlen(he
->h_name
),
710 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
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
);
726 &(sin
->sin_addr
.s_addr
),
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
));
747 __osl_destroySocketAddr( pSocketAddr
);
748 rtl_uString_release(cn
);
749 return ((oslHostAddr
)NULL
);
752 pAddr
->pHostName
= cn
;
753 pAddr
->pSockAddr
= pSocketAddr
;
758 /*****************************************************************************/
759 /* osl_createHostAddr */
760 /*****************************************************************************/
761 oslHostAddr SAL_CALL
osl_createHostAddr (
762 rtl_uString
*strHostname
,
763 const oslSocketAddr pSocketAddr
)
766 rtl_uString
*cn
= NULL
;
768 if ((strHostname
== NULL
) || (strHostname
->length
== 0) || (pSocketAddr
== NULL
))
769 return ((oslHostAddr
)NULL
);
771 rtl_uString_newFromString( &cn
, strHostname
);
775 rtl_uString_release(cn
);
776 return ((oslHostAddr
)NULL
);
779 pAddr
= (oslHostAddr
)rtl_allocateMemory (sizeof (struct oslHostAddrImpl
));
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())
804 rtl_String
*Hostname
= NULL
;
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
)
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())
836 he
= gethostbyaddr ((const sal_Char
*)&(sin
->sin_addr
),
837 sizeof (sin
->sin_addr
),
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
;
854 return osl_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
856 return ((oslHostAddr
)NULL
);
859 /*****************************************************************************/
860 /* osl_getHostnameOfHostAddr */
861 /*****************************************************************************/
862 void SAL_CALL
osl_getHostnameOfHostAddr(
863 const oslHostAddr pAddr
, rtl_uString
**strHostname
)
866 rtl_uString_assign (strHostname
, pAddr
->pHostName
);
868 rtl_uString_new (strHostname
);
871 /*****************************************************************************/
872 /* osl_getSocketAddrOfHostAddr */
873 /*****************************************************************************/
874 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr
)
877 return (const oslSocketAddr
)(pAddr
->pSockAddr
);
882 /*****************************************************************************/
883 /* osl_destroyHostAddr */
884 /*****************************************************************************/
885 void SAL_CALL
osl_destroyHostAddr(oslHostAddr 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
)
914 rtl_uString
*hostName
= NULL
;
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));
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
)
950 (oslHostAddr
)osl_createHostAddrByName (strHostname
);
953 oslSocketAddr SockAddr
= osl_copySocketAddr( pAddr
->pSockAddr
);
954 osl_destroyHostAddr(pAddr
);
957 return ((oslSocketAddr
)NULL
);
960 /*****************************************************************************/
961 /* osl_getServicePort */
962 /*****************************************************************************/
963 sal_Int32 SAL_CALL
osl_getServicePort (
964 rtl_uString
* strServicename
,
965 rtl_uString
* strProtocol
)
969 rtl_String
*str_Servicename
=NULL
;
970 rtl_String
*str_Protocol
=NULL
;
974 rtl_uString_getStr(strServicename
),
975 rtl_uString_getLength(strServicename
),
976 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
979 rtl_uString_getStr(strProtocol
),
980 rtl_uString_getLength(strProtocol
),
981 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
984 rtl_string_getStr(str_Servicename
),
985 rtl_string_getStr(str_Protocol
));
987 rtl_string_release( str_Servicename
);
988 rtl_string_release( str_Protocol
);
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
)
1010 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1012 return osl_Socket_FamilyInvalid
;
1015 /*****************************************************************************/
1016 /* osl_getInetPortOfSocketAddr */
1017 /*****************************************************************************/
1018 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr 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
,
1040 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1042 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1045 pSystemInetAddr
->sin_port
= htons((short)Port
);
1049 /*****************************************************************************/
1050 /* osl_getHostnameOfSocketAddr */
1051 /*****************************************************************************/
1052 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr (
1054 rtl_uString
**strHostName
)
1056 oslHostAddr pAddr
= osl_createHostAddrByAddr (Addr
);
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
)
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
);
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
,
1101 oslProtocol Protocol
)
1104 oslSocket pSocket
= __osl_createSocketImpl(0);
1106 if (pSocket
== NULL
)
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
);
1122 pSocket
->m_Flags
= 0;
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 */
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
;
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
);
1180 /*****************************************************************************/
1181 /* osl_getPeerAddrOfSocket */
1182 /*****************************************************************************/
1183 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1185 struct sockaddr Addr
;
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
);
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 */
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 (
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
;
1240 return osl_Socket_Ok
;
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
;
1263 return osl_Socket_Error
;
1267 return osl_Socket_Ok
;
1270 /* set socket temporarily to non-blocking */
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 */
1283 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1285 return osl_Socket_Ok
;
1289 error
= WSAGetLastError();
1291 /* really an error or just delayed? */
1292 if (error
!= WSAEWOULDBLOCK
&& error
!= WSAEINPROGRESS
)
1295 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1297 return osl_Socket_Error
;
1301 /* prepare select set for socket */
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;
1310 error
= select(pSocket
->m_Socket
+1,
1316 if (error
> 0) /* connected */
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
;
1335 Result
= osl_Socket_Error
;
1339 Result
= osl_Socket_TimedOut
;
1344 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1350 /*****************************************************************************/
1351 /* osl_listenOnSocket */
1352 /*****************************************************************************/
1353 sal_Bool SAL_CALL
osl_listenOnSocket (
1355 sal_Int32 MaxPendingConnections
)
1357 if (pSocket
== NULL
) /* ENOTSOCK */
1360 return (listen(pSocket
->m_Socket
,
1361 MaxPendingConnections
== -1 ?
1363 MaxPendingConnections
) != OSL_SOCKET_ERROR
);
1366 /*****************************************************************************/
1367 /* osl_acceptConnectionOnSocket */
1368 /*****************************************************************************/
1369 oslSocket SAL_CALL
osl_acceptConnectionOnSocket (
1371 oslSocketAddr
* ppAddr
)
1373 if (pSocket
== NULL
) /* ENOTSOCK */
1374 return ((oslSocket
)NULL
);
1381 osl_destroySocketAddr( *ppAddr
);
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
);
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
);
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 (
1422 sal_uInt32 BytesToRead
,
1423 oslSocketMsgFlag Flag
)
1425 if (pSocket
== NULL
) /* ENOTSOCK */
1426 return osl_Socket_Error
;
1428 return recv(pSocket
->m_Socket
,
1431 MSG_FLAG_TO_NATIVE(Flag
));
1434 /*****************************************************************************/
1435 /* osl_receiveFromSocket */
1436 /*****************************************************************************/
1437 sal_Int32 SAL_CALL
osl_receiveFromSocket (
1439 oslSocketAddr SenderAddr
,
1441 sal_uInt32 BufferSize
,
1442 oslSocketMsgFlag Flag
)
1444 struct sockaddr
*pSystemSockAddr
= 0;
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
,
1458 MSG_FLAG_TO_NATIVE(Flag
),
1463 /*****************************************************************************/
1464 /* osl_sendSocket */
1465 /*****************************************************************************/
1466 sal_Int32 SAL_CALL
osl_sendSocket (
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
,
1478 MSG_FLAG_TO_NATIVE(Flag
));
1481 /*****************************************************************************/
1482 /* osl_sendToSocket */
1483 /*****************************************************************************/
1484 sal_Int32 SAL_CALL
osl_sendToSocket (
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;
1499 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
1501 return sendto(pSocket
->m_Socket
,
1504 MSG_FLAG_TO_NATIVE(Flag
),
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)
1524 RetVal
= osl_receiveSocket(pSocket
,
1527 osl_Socket_MsgNormal
);
1529 /* error occurred? */
1535 BytesToRead
-= RetVal
;
1536 BytesRead
+= RetVal
;
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)
1558 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
1560 /* error occurred? */
1566 BytesToSend
-= RetVal
;
1567 BytesSend
+= RetVal
;
1575 /*****************************************************************************/
1576 /* osl_isReceiveReady */
1577 /*****************************************************************************/
1578 sal_Bool SAL_CALL
osl_isReceiveReady (
1580 const TimeValue
* pTimeout
)
1585 if (pSocket
== NULL
) /* ENOTSOCK */
1589 FD_SET(pSocket
->m_Socket
, &fds
);
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 (
1609 const TimeValue
* pTimeout
)
1614 if (pSocket
== NULL
) /* ENOTSOCK */
1618 FD_SET(pSocket
->m_Socket
, &fds
);
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 (
1638 const TimeValue
* pTimeout
)
1643 if (pSocket
== NULL
) /* ENOTSOCK */
1647 FD_SET(pSocket
->m_Socket
, &fds
);
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 (
1667 oslSocketDirection Direction
)
1669 if (pSocket
== NULL
) /* ENOTSOCK */
1672 return (shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
))==0);
1675 /*****************************************************************************/
1676 /* osl_getSocketOption */
1677 /*****************************************************************************/
1678 sal_Int32 SAL_CALL
osl_getSocketOption (
1680 oslSocketOptionLevel Level
,
1681 oslSocketOption Option
,
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
),
1692 (int*)&BufferLen
) == -1)
1697 return (sal_Int32
)BufferLen
;
1700 /*****************************************************************************/
1701 /* osl_setSocketOption */
1702 /*****************************************************************************/
1703 sal_Bool SAL_CALL
osl_setSocketOption (
1705 oslSocketOptionLevel Level
,
1706 oslSocketOption Option
,
1708 sal_uInt32 BufferLen
)
1710 if (pSocket
== NULL
) /* ENOTSOCK */
1713 return(setsockopt(pSocket
->m_Socket
,
1714 OPTION_LEVEL_TO_NATIVE(Level
),
1715 OPTION_TO_NATIVE(Option
),
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 */
1730 pSocket
->m_Flags
= Param
?
1731 (pSocket
->m_Flags
| OSL_SOCKET_FLAGS_NONBLOCKING
) :
1732 (pSocket
->m_Flags
& ~OSL_SOCKET_FLAGS_NONBLOCKING
) ;
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 */
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
)
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
),
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
)
1782 switch(error
= WSAGetLastError())
1785 rtl_uString_newFromAscii (strError
, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1788 case WSAEDESTADDRREQ
:
1789 rtl_uString_newFromAscii (strError
, "WSAEDESTADDRREQ, Destination Addr required");
1793 rtl_uString_newFromAscii (strError
, "WSAEMSGSIZE, Message too long");
1797 rtl_uString_newFromAscii (strError
, "WSAEPROTOTYPE, Protocol wrong type for socket");
1800 case WSAENOPROTOOPT
:
1801 rtl_uString_newFromAscii (strError
, "WSAENOPROTOOPT, Protocol not available");
1804 case WSAEPROTONOSUPPORT
:
1805 rtl_uString_newFromAscii (strError
, "WSAEPROTONOSUPPORT, Protocol not supported");
1808 case WSAESOCKTNOSUPPORT
:
1809 rtl_uString_newFromAscii (strError
, "WSAESOCKTNOSUPPORT, Socket type not supported");
1813 rtl_uString_newFromAscii (strError
, "WSAEOPNOTSUPP, Operation not supported on socket");
1816 case WSAEPFNOSUPPORT
:
1817 rtl_uString_newFromAscii (strError
, "WSAEPFNOSUPPORT, Protocol family not supported");
1820 case WSAEAFNOSUPPORT
:
1821 rtl_uString_newFromAscii (strError
, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1825 rtl_uString_newFromAscii (strError
, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1828 case WSAEADDRNOTAVAIL
:
1829 rtl_uString_newFromAscii (strError
, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1833 rtl_uString_newFromAscii (strError
, "WSAENETDOWN, Network is down");
1836 case WSAENETUNREACH
:
1837 rtl_uString_newFromAscii (strError
, "WSAENETUNREACH, Network is unreachable");
1841 rtl_uString_newFromAscii (strError
, "WSAENETRESET, Network dropped connection or reset");
1844 case WSAECONNABORTED
:
1845 rtl_uString_newFromAscii (strError
, "WSAECONNABORTED, Software caused connection abort");
1849 rtl_uString_newFromAscii (strError
, "WSAECONNRESET, Connection reset by peer");
1853 rtl_uString_newFromAscii (strError
, "WSAENOBUFS, No buffer space available.");
1857 rtl_uString_newFromAscii (strError
, "WSAEISCONN, Socket is already connected");
1861 rtl_uString_newFromAscii (strError
, "WSAENOTCONN, Socket is not connected");
1865 rtl_uString_newFromAscii (strError
, "WSAESHUTDOWN, Can't send after socket shutdown");
1869 rtl_uString_newFromAscii (strError
, "WSAETIMEDOUT, Connection timed out");
1872 case WSAECONNREFUSED
:
1873 rtl_uString_newFromAscii (strError
, "WSAECONNREFUSED, Connection refused");
1877 rtl_uString_newFromAscii (strError
, "WSAEHOSTDOWN, Networking subsystem not started");
1880 case WSAEHOSTUNREACH
:
1881 rtl_uString_newFromAscii (strError
, "WSAEHOSTUNREACH, No route to host");
1884 case WSAEWOULDBLOCK
:
1885 rtl_uString_newFromAscii (strError
, "WSAEWOULDBLOCK, Operation would block");
1888 case WSAEINPROGRESS
:
1889 rtl_uString_newFromAscii (strError
, "WSAEINPROGRESS, Operation now in progress");
1893 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation already in progress");
1897 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation was interrupted");
1901 rtl_uString_newFromAscii (strError
, "WSAEBADF, Bad file number");
1905 rtl_uString_newFromAscii (strError
, "WSAEACCES, Access is denied");
1909 rtl_uString_newFromAscii (strError
, "WSAEFAULT, Bad memory Addr");
1913 rtl_uString_newFromAscii (strError
, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1917 rtl_uString_newFromAscii (strError
, "WSAEMFILE, No more file descriptors are available");
1920 case WSAETOOMANYREFS
:
1921 rtl_uString_newFromAscii (strError
, "WSAETOOMANYREFS, Undocumented WinSock error");
1924 case WSAENAMETOOLONG
:
1925 rtl_uString_newFromAscii (strError
, "WSAENAMETOOLONG, Undocumented WinSock error");
1929 rtl_uString_newFromAscii (strError
, "WSAENOTEMPTY, Undocumented WinSock error");
1933 rtl_uString_newFromAscii (strError
, "WSAEPROCLIM, Undocumented WinSock error");
1937 rtl_uString_newFromAscii (strError
, "WSAEUSERS, Undocumented WinSock error");
1941 rtl_uString_newFromAscii (strError
, "WSAEDQUOT, Undocumented WinSock error");
1945 rtl_uString_newFromAscii (strError
, "WSAESTALE, Undocumented WinSock error");
1949 rtl_uString_newFromAscii (strError
, "WSAEREMOTE, Undocumented WinSock error");
1953 rtl_uString_newFromAscii (strError
, "WSAEDISCON, Circuit was gracefully terminated");
1956 case WSASYSNOTREADY
:
1957 rtl_uString_newFromAscii (strError
, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
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");
1964 case WSANOTINITIALISED
:
1965 rtl_uString_newFromAscii (strError
, "WSANOTINITIALISED, WSAStartup() has not been called");
1968 case WSAHOST_NOT_FOUND
:
1969 rtl_uString_newFromAscii (strError
, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
1973 rtl_uString_newFromAscii (strError
, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
1976 case WSANO_RECOVERY
:
1977 rtl_uString_newFromAscii (strError
, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1981 rtl_uString_newFromAscii (strError
, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
1986 sal_Unicode message
[128];
1988 wsprintfW(reinterpret_cast<LPWSTR
>(message
), L
"Unknown WinSock Error Number %d", error
);
1989 rtl_uString_newFromStr (strError
, message
);
1997 /*****************************************************************************/
1998 /* osl_getLastSocketError */
1999 /*****************************************************************************/
2000 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket
/*Socket*/)
2002 return ERROR_FROM_NATIVE(WSAGetLastError());
2005 /*****************************************************************************/
2007 /*****************************************************************************/
2008 typedef struct _TSocketSetImpl
2010 fd_set m_Set
; /* the set of descriptors */
2014 /*****************************************************************************/
2015 /* osl_createSocketSet */
2016 /*****************************************************************************/
2017 oslSocketSet SAL_CALL
osl_createSocketSet()
2019 TSocketSetImpl
* pSet
;
2021 pSet
= (TSocketSetImpl
*) rtl_allocateMemory(sizeof(TSocketSetImpl
));
2025 FD_ZERO(&pSet
->m_Set
);
2028 return (oslSocketSet
)pSet
;
2031 /*****************************************************************************/
2032 /* osl_destroySocketSet */
2033 /*****************************************************************************/
2034 void SAL_CALL
osl_destroySocketSet (oslSocketSet 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
;
2050 FD_ZERO(&pSet
->m_Set
);
2053 /*****************************************************************************/
2054 /* osl_addToSocketSet */
2055 /*****************************************************************************/
2056 void SAL_CALL
osl_addToSocketSet (
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 (
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 (
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);
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
)
2117 TSocketSetImpl
* pInSet
;
2118 TSocketSetImpl
* pOutSet
;
2119 TSocketSetImpl
* pOOBSet
;
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: */