1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: socket.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sal.hxx"
36 #include <osl/socket.h>
37 #include <osl/diagnose.h>
38 #include <rtl/alloc.h>
44 /* defines for shutdown */
52 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
53 I refrained from using sockaddr_in because of possible further
54 extensions of this socket-interface (IP-NG?).
55 The intention was to hide all Berkeley data-structures from
56 direct access past the osl-interface.
58 The current implementation is internet (IP) centered. All
59 the constructor-functions (osl_create...) take parameters
60 that will probably make sense only in the IP-environment
61 (e.g. because of using the dotted-Addr-format).
63 If the interface will be extended to host other protocol-
64 families, I expect no externally visible changes in the
65 existing functions. You'll probably need only new
66 constructor-functions who take the different Addr
67 formats into consideration (maybe a long dotted Addr
72 _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr
73 are the same! I don't like it very much but see no other easy way to
74 conceal the struct sockaddr from the eyes of the user.
77 #define OSL_INVALID_SOCKET INVALID_SOCKET /* WIN32 */
78 #define OSL_SOCKET_ERROR SOCKET_ERROR /* WIN32 */
80 /*****************************************************************************/
81 /* enum oslAddrFamily */
82 /*****************************************************************************/
85 static DWORD FamilyMap
[]= {
86 AF_INET
, /* osl_Socket_FamilyInet */
87 AF_IPX
, /* osl_Socket_FamilyIpx */
88 0 /* osl_Socket_FamilyInvalid */
92 static oslAddrFamily
osl_AddrFamilyFromNative(DWORD nativeType
)
94 oslAddrFamily i
= (oslAddrFamily
) 0;
95 while(i
!= osl_Socket_FamilyInvalid
)
97 if(FamilyMap
[i
] == nativeType
)
99 i
= (oslAddrFamily
) ( (int)i
+ 1);
105 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
106 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
108 /*****************************************************************************/
109 /* enum oslProtocol */
110 /*****************************************************************************/
113 static DWORD ProtocolMap
[]= {
114 0, /* osl_Socket_FamilyInet */
115 NSPROTO_IPX
, /* osl_Socket_FamilyIpx */
116 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
117 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpx_ii */
118 0 /* osl_Socket_ProtocolInvalid */
122 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
123 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
125 /*****************************************************************************/
126 /* enum oslSocketType */
127 /*****************************************************************************/
130 static DWORD TypeMap
[]= {
131 SOCK_STREAM
, /* osl_Socket_TypeStream */
132 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
133 SOCK_RAW
, /* osl_Socket_TypeRaw */
134 SOCK_RDM
, /* osl_Socket_TypeRdm */
135 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
136 0 /* osl_Socket_TypeInvalid */
140 static oslSocketType
osl_SocketTypeFromNative(DWORD nativeType
)
142 oslSocketType i
= (oslSocketType
)0;
143 while(i
!= osl_Socket_TypeInvalid
)
145 if(TypeMap
[i
] == nativeType
)
147 i
= (oslSocketType
)((int)i
+1);
153 #define TYPE_TO_NATIVE(x) TypeMap[x]
154 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
156 /*****************************************************************************/
157 /* enum oslSocketOption */
158 /*****************************************************************************/
161 static DWORD OptionMap
[]= {
162 SO_DEBUG
, /* osl_Socket_OptionDebug */
163 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
164 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
165 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
166 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
167 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
168 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
169 SO_LINGER
, /* osl_Socket_OptionLinger */
170 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
171 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
172 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
173 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
174 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
175 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
176 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
177 SO_ERROR
, /* osl_Socket_OptionError */
178 SO_TYPE
, /* osl_Socket_OptionType */
179 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
180 0 /* osl_Socket_OptionInvalid */
184 #define OPTION_TO_NATIVE(x) OptionMap[x]
185 #define OPTION_FROM_NATIVE(y) osl_SocketOptionFromNative(y)
187 /*****************************************************************************/
188 /* enum oslSocketOptionLevel */
189 /*****************************************************************************/
191 static DWORD OptionLevelMap
[]= {
192 SOL_SOCKET
, /* osl_Socket_LevelSocket */
193 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
194 0 /* osl_invalid_SocketLevel */
198 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
199 #define OPTION_LEVEL_FROM_NATIVE(y) osl_SocketOptionLevelFromNative(y)
201 /*****************************************************************************/
202 /* enum oslSocketMsgFlag */
203 /*****************************************************************************/
205 static DWORD SocketMsgFlagMap
[]= {
206 0, /* osl_Socket_MsgNormal */
207 MSG_OOB
, /* osl_Socket_MsgOOB */
208 MSG_PEEK
, /* osl_Socket_MsgPeek */
209 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
210 MSG_MAXIOVLEN
/* osl_Socket_MsgMaxIOVLen */
214 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
215 #define MSG_FLAG_FROM_NATIVE(y) osl_SocketMsgFlagFromNative(y)
217 /*****************************************************************************/
218 /* enum oslSocketDirection */
219 /*****************************************************************************/
221 static DWORD SocketDirection
[]= {
222 SD_RECEIVE
, /* osl_Socket_DirRead */
223 SD_SEND
, /* osl_Socket_DirWrite */
224 SD_BOTH
/* osl_Socket_DirReadwrite */
228 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
229 #define DIRECTION_FROM_NATIVE(y) osl_SocketDirectionFromNative(y)
231 /*****************************************************************************/
232 /* enum oslSocketError */
233 /*****************************************************************************/
235 static int SocketError
[]= {
238 WSAENOTSOCK
, /* Socket operation on non-socket */
239 WSAEDESTADDRREQ
, /* Destination address required */
240 WSAEMSGSIZE
, /* Message too long */
241 WSAEPROTOTYPE
, /* Protocol wrong type for socket */
242 WSAENOPROTOOPT
, /* Protocol not available */
243 WSAEPROTONOSUPPORT
, /* Protocol not supported */
244 WSAESOCKTNOSUPPORT
, /* Socket type not supported */
245 WSAEOPNOTSUPP
, /* Operation not supported on socket */
246 WSAEPFNOSUPPORT
, /* Protocol family not supported */
247 WSAEAFNOSUPPORT
, /* Address family not supported by */
248 /* protocol family */
249 WSAEADDRINUSE
, /* Address already in use */
250 WSAEADDRNOTAVAIL
, /* Can't assign requested address */
251 WSAENETDOWN
, /* Network is down */
252 WSAENETUNREACH
, /* Network is unreachable */
253 WSAENETRESET
, /* Network dropped connection because */
255 WSAECONNABORTED
, /* Software caused connection abort */
256 WSAECONNRESET
, /* Connection reset by peer */
257 WSAENOBUFS
, /* No buffer space available */
258 WSAEISCONN
, /* Socket is already connected */
259 WSAENOTCONN
, /* Socket is not connected */
260 WSAESHUTDOWN
, /* Can't send after socket shutdown */
261 WSAETOOMANYREFS
, /* Too many references: can't splice */
262 WSAETIMEDOUT
, /* Connection timed out */
263 WSAECONNREFUSED
, /* Connection refused */
264 WSAEHOSTDOWN
, /* Host is down */
265 WSAEHOSTUNREACH
, /* No route to host */
266 WSAEWOULDBLOCK
, /* call would block on non-blocking socket */
267 WSAEALREADY
, /* operation already in progress */
268 WSAEINPROGRESS
/* operation now in progress */
272 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
274 oslSocketError i
= (oslSocketError
)0;
276 while(i
!= osl_Socket_E_InvalidError
)
278 if(SocketError
[i
] == nativeType
)
281 i
= (oslSocketError
)( (int) i
+ 1);
287 #define ERROR_TO_NATIVE(x) SocketError[x]
288 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
290 /*****************************************************************************/
291 /* oslSocketDialupImpl */
292 /*****************************************************************************/
293 static oslSocketDialupImpl
*pDialupImpl
= NULL
;
295 #if 0 /* INTERNAL DEBUG ONLY */
296 BOOL WINAPI
__osl_autodial_Impl (DWORD dwFlags
, DWORD dwReserved
)
301 BOOL WINAPI
__osl_autodialHangup_Impl (DWORD dwReserved
)
306 BOOL WINAPI
__osl_getConnectedState_Impl (LPDWORD lpdwFlags
, DWORD dwReserved
)
312 #endif /* INTERNAL DEBUG ONLY */
315 * __osl_createSocketDialupImpl.
317 static oslSocketDialupImpl
* __osl_createSocketDialupImpl (void)
319 oslSocketDialupImpl
*pImpl
;
320 pImpl
= (oslSocketDialupImpl
*)rtl_allocateZeroMemory( sizeof (oslSocketDialupImpl
));
322 InitializeCriticalSection (&pImpl
->m_hMutex
);
328 * __osl_initSocketDialupImpl.
330 static void __osl_initSocketDialupImpl (oslSocketDialupImpl
*pImpl
)
332 #ifdef SOCKET_USE_AUTODIAL
337 EnterCriticalSection (&pImpl
->m_hMutex
);
339 hModule
= LoadLibrary (INTERNET_MODULE_NAME
);
340 if (!(hModule
<= (HINSTANCE
)HINSTANCE_ERROR
))
342 pImpl
->m_pfnAttemptConnect
= (INTERNETATTEMPTCONNECT
)
343 (GetProcAddress (hModule
, "InternetAttemptConnect"));
344 pImpl
->m_pfnAutodial
= (INTERNETAUTODIAL
)
345 (GetProcAddress (hModule
, "InternetAutodial"));
346 pImpl
->m_pfnAutodialHangup
= (INTERNETAUTODIALHANGUP
)
347 (GetProcAddress (hModule
, "InternetAutodialHangup"));
348 pImpl
->m_pfnGetConnectedState
= (INTERNETGETCONNECTEDSTATE
)
349 (GetProcAddress (hModule
, "InternetGetConnectedState"));
350 pImpl
->m_hModule
= hModule
;
353 LeaveCriticalSection (&pImpl
->m_hMutex
);
356 pImpl
= pImpl
; /* avoid warnings */
361 * __osl_destroySocketDialupImpl.
363 static void __osl_destroySocketDialupImpl (oslSocketDialupImpl
*pImpl
)
367 EnterCriticalSection (&pImpl
->m_hMutex
);
369 if (pImpl
->m_dwFlags
& INTERNET_CONNECTION_HANGUP
)
371 if (pImpl
->m_pfnAutodialHangup
)
373 (pImpl
->m_pfnAutodialHangup
)(0);
374 pImpl
->m_dwFlags
&= ~INTERNET_CONNECTION_HANGUP
;
378 if (pImpl
->m_hModule
)
379 FreeLibrary (pImpl
->m_hModule
);
381 LeaveCriticalSection (&pImpl
->m_hMutex
);
382 DeleteCriticalSection (&pImpl
->m_hMutex
);
384 rtl_freeMemory (pImpl
);
389 * __osl_querySocketDialupImpl.
391 static sal_Bool
__osl_querySocketDialupImpl (void)
395 if (pDialupImpl
== NULL
)
397 pDialupImpl
= __osl_createSocketDialupImpl();
398 __osl_initSocketDialupImpl (pDialupImpl
);
401 EnterCriticalSection (&pDialupImpl
->m_hMutex
);
404 if (pDialupImpl
->m_pfnGetConnectedState
)
408 result
= (sal_Bool
)(pDialupImpl
->m_pfnGetConnectedState
)(&dwFlags
, 0);
409 pDialupImpl
->m_dwFlags
|= dwFlags
;
412 LeaveCriticalSection (&pDialupImpl
->m_hMutex
);
417 * __osl_attemptSocketDialupImpl.
419 static sal_Bool
__osl_attemptSocketDialupImpl (void)
423 if (pDialupImpl
== NULL
)
425 pDialupImpl
= __osl_createSocketDialupImpl();
426 __osl_initSocketDialupImpl (pDialupImpl
);
429 EnterCriticalSection (&pDialupImpl
->m_hMutex
);
431 result
= __osl_querySocketDialupImpl();
435 if (pDialupImpl
->m_pfnAutodial
)
437 result
= (sal_Bool
)(pDialupImpl
->m_pfnAutodial
)(0, 0);
439 pDialupImpl
->m_dwFlags
|= INTERNET_CONNECTION_HANGUP
;
441 WSASetLastError (WSAENETDOWN
);
445 LeaveCriticalSection (&pDialupImpl
->m_hMutex
);
449 /*****************************************************************************/
451 /*****************************************************************************/
452 static sal_uInt32 g_nSocketImpl
= 0;
454 #if OSL_DEBUG_LEVEL > 1
455 static sal_uInt32 g_nSocketAddr
= 0;
461 OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl
);
463 OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr
);
466 LeakWarning socketWarning
;
470 * __osl_createSocketImpl.
472 oslSocket
__osl_createSocketImpl(SOCKET Socket
)
474 oslSocket pSockImpl
= (oslSocket
) rtl_allocateZeroMemory( sizeof(struct oslSocketImpl
));
475 pSockImpl
->m_Socket
= Socket
;
476 pSockImpl
->m_nRefCount
= 1;
484 * __osl_destroySocketImpl.
486 void __osl_destroySocketImpl(oslSocketImpl
*pImpl
)
490 if (--g_nSocketImpl
== 0)
492 __osl_destroySocketDialupImpl (pDialupImpl
);
495 rtl_freeMemory (pImpl
);
498 /*****************************************************************************/
499 static oslSocketAddr
__osl_createSocketAddr( )
501 oslSocketAddr pAddr
= (oslSocketAddr
) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
));
502 pAddr
->m_nRefCount
= 1;
503 #if OSL_DEBUG_LEVEL > 1
509 static oslSocketAddr
__osl_createSocketAddrWithFamily(
510 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
512 OSL_ASSERT( family
== osl_Socket_FamilyInet
);
514 oslSocketAddr pAddr
= __osl_createSocketAddr();
517 case osl_Socket_FamilyInet
:
519 struct sockaddr_in
* pInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
521 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
522 pInetAddr
->sin_addr
.s_addr
= nAddr
;
523 pInetAddr
->sin_port
= (sal_uInt16
)(port
&0xffff);
527 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
532 static oslSocketAddr
__osl_createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
534 oslSocketAddr pAddr
= __osl_createSocketAddr();
535 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( sockaddr
) );
539 static void __osl_destroySocketAddr( oslSocketAddr addr
)
541 #if OSL_DEBUG_LEVEL > 1
544 rtl_freeMemory( addr
);
546 /*****************************************************************************/
547 /* osl_createEmptySocketAddr */
548 /*****************************************************************************/
549 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
551 oslSocketAddr pAddr
= 0;
553 /* is it an internet-Addr? */
554 if (Family
== osl_Socket_FamilyInet
)
556 pAddr
= __osl_createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
560 pAddr
= __osl_createSocketAddrWithFamily( Family
, 0 , 0 );
566 /*****************************************************************************/
567 /* osl_copySocketAddr */
568 /*****************************************************************************/
569 // @deprecated, to be removed
570 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
572 oslSocketAddr pCopy
= 0;
575 pCopy
= __osl_createSocketAddr();
578 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
583 /*****************************************************************************/
584 /* osl_isEqualSocketAddr */
585 /*****************************************************************************/
586 sal_Bool SAL_CALL
osl_isEqualSocketAddr(oslSocketAddr Addr1
, oslSocketAddr Addr2
)
588 struct sockaddr
* pAddr1
= &(Addr1
->m_sockaddr
);
589 struct sockaddr
* pAddr2
= &(Addr2
->m_sockaddr
);
594 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
596 switch (pAddr1
->sa_family
)
600 struct sockaddr_in
* pInetAddr1
= (struct sockaddr_in
*)pAddr1
;
601 struct sockaddr_in
* pInetAddr2
= (struct sockaddr_in
*)pAddr2
;
603 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
604 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
605 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
611 return (memcmp(pAddr1
, Addr2
, sizeof(struct sockaddr
)) == 0);
619 /*****************************************************************************/
620 /* osl_createInetBroadcastAddr */
621 /*****************************************************************************/
622 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
623 rtl_uString
*strDottedAddr
,
626 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
628 if (strDottedAddr
&& strDottedAddr
->length
)
630 /* Dotted host address for limited broadcast */
631 rtl_String
*pDottedAddr
= NULL
;
634 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
635 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
637 nAddr
= inet_addr (pDottedAddr
->buffer
);
638 rtl_string_release (pDottedAddr
);
641 if (nAddr
!= OSL_INADDR_NONE
)
643 /* Limited broadcast */
644 nAddr
= ntohl(nAddr
);
645 if (IN_CLASSA(nAddr
))
647 nAddr
&= IN_CLASSA_NET
;
648 nAddr
|= IN_CLASSA_HOST
;
650 else if (IN_CLASSB(nAddr
))
652 nAddr
&= IN_CLASSB_NET
;
653 nAddr
|= IN_CLASSB_HOST
;
655 else if (IN_CLASSC(nAddr
))
657 nAddr
&= IN_CLASSC_NET
;
658 nAddr
|= IN_CLASSC_HOST
;
662 /* No broadcast in class D */
663 return ((oslSocketAddr
)NULL
);
665 nAddr
= htonl(nAddr
);
668 oslSocketAddr pAddr
=
669 __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons( (sal_uInt16
) Port
), nAddr
);
673 /*****************************************************************************/
674 /* osl_createInetSocketAddr */
675 /*****************************************************************************/
676 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
677 rtl_uString
*strDottedAddr
,
681 rtl_String
*pDottedAddr
=NULL
;
684 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
685 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
687 Addr
= inet_addr (pDottedAddr
->buffer
);
688 rtl_string_release (pDottedAddr
);
690 oslSocketAddr pAddr
= 0;
693 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons( (sal_uInt16
)Port
), Addr
);
698 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
701 OSL_ASSERT( pByteSeq
);
703 oslSocketResult res
= osl_Socket_Error
;
704 if( pAddr
&& pByteSeq
)
706 OSL_ASSERT( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
707 OSL_ASSERT( pByteSeq
->nElements
== 4 );
708 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
709 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
715 /** Returns the addr field in the struct sockaddr. ppByteSeq is in network byteorder. *ppByteSeq may
716 either be 0 or contain a constructed sal_Sequence.
718 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
721 OSL_ASSERT( ppByteSeq
);
723 oslSocketResult res
= osl_Socket_Error
;
724 if( pAddr
&& ppByteSeq
)
726 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
727 rtl_byte_sequence_constructFromArray( ppByteSeq
, (sal_Int8
*) &(pSystemInetAddr
->sin_addr
),4);
733 /*****************************************************************************/
735 /*****************************************************************************/
736 struct oslHostAddrImpl
{
737 rtl_uString
*pHostName
;
738 oslSocketAddr pSockAddr
;
741 static oslHostAddr
__osl_hostentToHostAddr (const struct hostent
*he
)
743 oslHostAddr pAddr
= NULL
;
744 oslSocketAddr pSocketAddr
= 0;
746 rtl_uString
*cn
= NULL
;
748 if ((he
== NULL
) || (he
->h_name
== NULL
) || (he
->h_addr_list
[0] == NULL
))
749 return ((oslHostAddr
)NULL
);
752 &cn
, he
->h_name
, strlen(he
->h_name
),
753 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
756 pSocketAddr
= __osl_createSocketAddr();
758 if (pSocketAddr
== NULL
)
760 rtl_uString_release(cn
);
761 return ((oslHostAddr
)NULL
);
764 pSocketAddr
->m_sockaddr
.sa_family
= he
->h_addrtype
;
765 if (pSocketAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
767 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&(pSocketAddr
->m_sockaddr
);
769 &(sin
->sin_addr
.s_addr
),
775 /* unknown address family */
776 /* future extensions for new families might be implemented here */
778 OSL_TRACE("_osl_hostentToHostAddr(): unknown address family.\n");
779 OSL_ASSERT(sal_False
);
781 __osl_destroySocketAddr( pSocketAddr
);
782 rtl_uString_release(cn
);
783 return ((oslHostAddr
)NULL
);
786 pAddr
= (oslHostAddr
)rtl_allocateMemory (sizeof (struct oslHostAddrImpl
));
790 __osl_destroySocketAddr( pSocketAddr
);
791 rtl_uString_release(cn
);
792 return ((oslHostAddr
)NULL
);
795 pAddr
->pHostName
= cn
;
796 pAddr
->pSockAddr
= pSocketAddr
;
801 /*****************************************************************************/
802 /* osl_createHostAddr */
803 /*****************************************************************************/
804 oslHostAddr SAL_CALL
osl_createHostAddr (
805 rtl_uString
*strHostname
,
806 const oslSocketAddr pSocketAddr
)
809 rtl_uString
*cn
= NULL
;
811 if ((strHostname
== NULL
) || (strHostname
->length
== 0) || (pSocketAddr
== NULL
))
812 return ((oslHostAddr
)NULL
);
814 rtl_uString_newFromString( &cn
, strHostname
);
818 rtl_uString_release(cn
);
819 return ((oslHostAddr
)NULL
);
822 pAddr
= (oslHostAddr
)rtl_allocateMemory (sizeof (struct oslHostAddrImpl
));
826 rtl_uString_release(cn
);
827 return ((oslHostAddr
)NULL
);
830 pAddr
->pHostName
= cn
;
831 pAddr
->pSockAddr
= osl_copySocketAddr( pSocketAddr
);
833 return ((oslHostAddr
)pAddr
);
836 /*****************************************************************************/
837 /* osl_createHostAddrByName */
838 /*****************************************************************************/
839 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*strHostname
)
841 if ((strHostname
== NULL
) || (strHostname
->length
== 0))
842 return ((oslHostAddr
)NULL
);
844 if (__osl_attemptSocketDialupImpl())
847 rtl_String
*Hostname
= NULL
;
850 &Hostname
, strHostname
->buffer
, strHostname
->length
,
851 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
853 he
= gethostbyname (Hostname
->buffer
);
855 rtl_string_release (Hostname
);
856 return __osl_hostentToHostAddr (he
);
858 return ((oslHostAddr
)NULL
);
861 /*****************************************************************************/
862 /* osl_createHostAddrByAddr */
863 /*****************************************************************************/
864 oslHostAddr SAL_CALL
osl_createHostAddrByAddr(const oslSocketAddr pAddr
)
867 return ((oslHostAddr
)NULL
);
869 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
871 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
873 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
874 return ((oslHostAddr
)NULL
);
876 if (__osl_attemptSocketDialupImpl())
879 he
= gethostbyaddr ((const sal_Char
*)&(sin
->sin_addr
),
880 sizeof (sin
->sin_addr
),
882 return __osl_hostentToHostAddr (he
);
886 return ((oslHostAddr
)NULL
);
889 /*****************************************************************************/
890 /* osl_copyHostAddr */
891 /*****************************************************************************/
892 oslHostAddr SAL_CALL
osl_copyHostAddr(const oslHostAddr Addr
)
894 oslHostAddr pAddr
= (oslHostAddr
)Addr
;
897 return osl_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
899 return ((oslHostAddr
)NULL
);
902 /*****************************************************************************/
903 /* osl_getHostnameOfHostAddr */
904 /*****************************************************************************/
905 void SAL_CALL
osl_getHostnameOfHostAddr(
906 const oslHostAddr pAddr
, rtl_uString
**strHostname
)
909 rtl_uString_assign (strHostname
, pAddr
->pHostName
);
911 rtl_uString_new (strHostname
);
914 /*****************************************************************************/
915 /* osl_getSocketAddrOfHostAddr */
916 /*****************************************************************************/
917 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr
)
920 return (const oslSocketAddr
)(pAddr
->pSockAddr
);
925 /*****************************************************************************/
926 /* osl_destroyHostAddr */
927 /*****************************************************************************/
928 void SAL_CALL
osl_destroyHostAddr(oslHostAddr pAddr
)
932 if (pAddr
->pHostName
)
933 rtl_uString_release (pAddr
->pHostName
);
934 if (pAddr
->pSockAddr
)
935 osl_destroySocketAddr( pAddr
->pSockAddr
);
937 rtl_freeMemory (pAddr
);
941 /*****************************************************************************/
942 /* osl_getLocalHostname */
943 /*****************************************************************************/
944 oslSocketResult SAL_CALL
osl_getLocalHostname (rtl_uString
**strLocalHostname
)
946 static sal_Unicode LocalHostname
[256] = {0};
948 if (rtl_ustr_getLength(LocalHostname
) == 0)
950 sal_Char Host
[256]= "";
951 if (gethostname(Host
, sizeof(Host
)) == 0)
953 /* check if we have an FQDN */
954 if (strchr(Host
, '.') == NULL
)
957 rtl_uString
*hostName
= NULL
;
960 &hostName
, Host
, strlen(Host
),
961 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
962 OSL_ASSERT(hostName
!= 0);
964 /* no, determine it via dns */
965 pAddr
= osl_createHostAddrByName(hostName
);
966 rtl_uString_release (hostName
);
968 if (pAddr
&& pAddr
->pHostName
)
969 memcpy(LocalHostname
, pAddr
->pHostName
->buffer
, sizeof(sal_Unicode
)*(rtl_ustr_getLength(pAddr
->pHostName
->buffer
)+1));
971 memset(LocalHostname
, 0, sizeof(LocalHostname
));
973 osl_destroyHostAddr ((oslHostAddr
)pAddr
);
978 if (rtl_ustr_getLength(LocalHostname
) > 0)
980 rtl_uString_newFromStr (strLocalHostname
, LocalHostname
);
981 return osl_Socket_Ok
;
984 return osl_Socket_Error
;
987 /*****************************************************************************/
988 /* osl_resolveHostname */
989 /*****************************************************************************/
990 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
* strHostname
)
993 (oslHostAddr
)osl_createHostAddrByName (strHostname
);
996 oslSocketAddr SockAddr
= osl_copySocketAddr( pAddr
->pSockAddr
);
997 osl_destroyHostAddr(pAddr
);
1000 return ((oslSocketAddr
)NULL
);
1003 /*****************************************************************************/
1004 /* osl_getServicePort */
1005 /*****************************************************************************/
1006 sal_Int32 SAL_CALL
osl_getServicePort (
1007 rtl_uString
* strServicename
,
1008 rtl_uString
* strProtocol
)
1012 rtl_String
*str_Servicename
=NULL
;
1013 rtl_String
*str_Protocol
=NULL
;
1017 rtl_uString_getStr(strServicename
),
1018 rtl_uString_getLength(strServicename
),
1019 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
1022 rtl_uString_getStr(strProtocol
),
1023 rtl_uString_getLength(strProtocol
),
1024 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
1027 rtl_string_getStr(str_Servicename
),
1028 rtl_string_getStr(str_Protocol
));
1030 rtl_string_release( str_Servicename
);
1031 rtl_string_release( str_Protocol
);
1034 return ntohs(ps
->s_port
);
1036 return OSL_INVALID_PORT
;
1039 /*****************************************************************************/
1040 /* osl_destroySocketAddr */
1041 /*****************************************************************************/
1042 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
1044 __osl_destroySocketAddr( pAddr
);
1047 /*****************************************************************************/
1048 /* osl_getFamilyOfSocketAddr */
1049 /*****************************************************************************/
1050 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
1053 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1055 return osl_Socket_FamilyInvalid
;
1058 /*****************************************************************************/
1059 /* osl_getInetPortOfSocketAddr */
1060 /*****************************************************************************/
1061 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
1065 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1067 if ( (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
)))
1068 return ntohs(pSystemInetAddr
->sin_port
);
1070 return OSL_INVALID_PORT
;
1073 /*****************************************************************************/
1074 /* osl_setInetPortOfSocketAddr */
1075 /*****************************************************************************/
1076 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr (
1077 oslSocketAddr pAddr
,
1083 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1085 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1088 pSystemInetAddr
->sin_port
= htons((short)Port
);
1092 /*****************************************************************************/
1093 /* osl_getHostnameOfSocketAddr */
1094 /*****************************************************************************/
1095 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr (
1097 rtl_uString
**strHostName
)
1099 oslHostAddr pAddr
= osl_createHostAddrByAddr (Addr
);
1103 rtl_uString_newFromString(strHostName
, pAddr
->pHostName
);
1105 osl_destroyHostAddr(pAddr
);
1107 return osl_Socket_Ok
;
1110 return osl_Socket_Error
;
1113 /*****************************************************************************/
1114 /* osl_getDottedInetAddrOfSocketAddr */
1115 /*****************************************************************************/
1116 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr (
1117 oslSocketAddr pAddr
,
1118 rtl_uString
**strDottedInetAddr
)
1123 return osl_Socket_Error
;
1125 struct sockaddr_in
*pSystemInetAddr
= (struct sockaddr_in
*) &(pAddr
->m_sockaddr
);
1126 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1127 return osl_Socket_Error
;
1129 pDotted
= inet_ntoa (pSystemInetAddr
->sin_addr
);
1131 strDottedInetAddr
, pDotted
, strlen (pDotted
),
1132 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
1133 OSL_ASSERT(*strDottedInetAddr
!= 0);
1135 return osl_Socket_Ok
;
1138 /*****************************************************************************/
1139 /* osl_createSocket */
1140 /*****************************************************************************/
1141 oslSocket SAL_CALL
osl_createSocket (
1142 oslAddrFamily Family
,
1144 oslProtocol Protocol
)
1147 oslSocket pSocket
= __osl_createSocketImpl(0);
1149 if (pSocket
== NULL
)
1153 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
1154 TYPE_TO_NATIVE(Type
),
1155 PROTOCOL_TO_NATIVE(Protocol
));
1157 /* creation failed => free memory */
1158 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
1160 __osl_destroySocketImpl(pSocket
);
1165 pSocket
->m_Flags
= 0;
1166 pSocket
->m_CloseCallback
= NULL
;
1167 pSocket
->m_CallbackArg
= NULL
;
1173 void SAL_CALL
osl_acquireSocket( oslSocket pSocket
)
1175 osl_incrementInterlockedCount( &(pSocket
->m_nRefCount
) );
1178 void SAL_CALL
osl_releaseSocket( oslSocket pSocket
)
1180 if( pSocket
&& 0 == osl_decrementInterlockedCount( &(pSocket
->m_nRefCount
) ) )
1182 osl_closeSocket( pSocket
);
1183 __osl_destroySocketImpl( pSocket
);
1187 /*****************************************************************************/
1188 /* osl_closeSocket */
1189 /*****************************************************************************/
1190 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
1192 /* socket already invalid */
1197 closesocket(pSocket
->m_Socket
);
1199 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1201 /* registrierten Callback ausfuehren */
1202 if (pSocket
->m_CloseCallback
!= NULL
)
1204 pSocket
->m_CloseCallback(pSocket
->m_CallbackArg
);
1208 /*****************************************************************************/
1209 /* osl_getLocalAddrOfSocket */
1210 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1211 /* are the same! I don't like it very much but see no other easy way */
1212 /* to conceal the struct sockaddr from the eyes of the user. */
1213 /*****************************************************************************/
1214 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
1216 struct sockaddr Addr
;
1219 if (pSocket
== NULL
) /* ENOTSOCK */
1220 return ((oslSocketAddr
)NULL
);
1222 AddrLen
= sizeof(struct sockaddr
);
1224 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1225 return ((oslSocketAddr
)NULL
);
1227 oslSocketAddr pAddr
= __osl_createSocketAddrFromSystem( &Addr
);
1231 /*****************************************************************************/
1232 /* osl_getPeerAddrOfSocket */
1233 /*****************************************************************************/
1234 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1236 struct sockaddr Addr
;
1239 if (pSocket
== NULL
) /* ENOTSOCK */
1240 return ((oslSocketAddr
)NULL
);
1242 AddrLen
= sizeof(struct sockaddr
);
1244 if (getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1245 return ((oslSocketAddr
)NULL
);
1247 oslSocketAddr pAddr
= __osl_createSocketAddrFromSystem( &Addr
);
1251 /*****************************************************************************/
1252 /* osl_bindAddrToSocket */
1253 /*****************************************************************************/
1254 sal_Bool SAL_CALL
osl_bindAddrToSocket ( oslSocket pSocket
, oslSocketAddr pAddr
)
1256 OSL_ASSERT( pAddr
);
1258 if (pSocket
== NULL
) /* ENOTSOCK */
1261 return (bind(pSocket
->m_Socket
,
1262 &(pAddr
->m_sockaddr
),
1263 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
);
1266 /*****************************************************************************/
1267 /* osl_connectSocketTo */
1268 /*****************************************************************************/
1269 oslSocketResult SAL_CALL
osl_connectSocketTo (
1271 oslSocketAddr pAddr
,
1272 const TimeValue
* pTimeout
)
1275 if (pSocket
== NULL
) /* ENOTSOCK */
1276 return osl_Socket_Error
;
1278 if (pAddr
== NULL
) /* EDESTADDRREQ */
1279 return osl_Socket_Error
;
1281 if (!__osl_attemptSocketDialupImpl()) /* ENETDOWN */
1282 return osl_Socket_Error
;
1284 if (pTimeout
== NULL
)
1286 if(connect(pSocket
->m_Socket
,
1287 &(pAddr
->m_sockaddr
),
1288 sizeof(struct sockaddr
)) == OSL_SOCKET_ERROR
)
1289 return osl_Socket_Error
;
1291 return osl_Socket_Ok
;
1298 unsigned long Param
;
1299 oslSocketResult Result
= osl_Socket_Ok
;
1301 if (pSocket
->m_Flags
& OSL_SOCKET_FLAGS_NONBLOCKING
)
1303 if (connect(pSocket
->m_Socket
,
1304 &(pAddr
->m_sockaddr
),
1305 sizeof(struct sockaddr
)) == OSL_SOCKET_ERROR
)
1307 switch (WSAGetLastError())
1309 case WSAEWOULDBLOCK
:
1310 case WSAEINPROGRESS
:
1311 return osl_Socket_InProgress
;
1314 return osl_Socket_Error
;
1318 return osl_Socket_Ok
;
1321 /* set socket temporarily to non-blocking */
1323 OSL_VERIFY(ioctlsocket(
1324 pSocket
->m_Socket
, FIONBIO
, &Param
) != OSL_SOCKET_ERROR
);
1326 /* initiate connect */
1327 if (connect(pSocket
->m_Socket
,
1328 &(pAddr
->m_sockaddr
),
1329 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1331 /* immediate connection */
1334 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1336 return osl_Socket_Ok
;
1340 error
= WSAGetLastError();
1342 /* really an error or just delayed? */
1343 if (error
!= WSAEWOULDBLOCK
&& error
!= WSAEINPROGRESS
)
1346 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1348 return osl_Socket_Error
;
1352 /* prepare select set for socket */
1354 FD_SET(pSocket
->m_Socket
, &fds
);
1356 /* divide milliseconds into seconds and microseconds */
1357 tv
.tv_sec
= pTimeout
->Seconds
;
1358 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1361 error
= select(pSocket
->m_Socket
+1,
1367 if (error
> 0) /* connected */
1370 FD_ISSET(pSocket
->m_Socket
, &fds
),
1371 "osl_connectSocketTo(): select returned but socket not set\n");
1373 Result
= osl_Socket_Ok
;
1376 else if(error
< 0) /* error */
1378 /* errno == EBADF: most probably interrupted by close() */
1379 if(WSAGetLastError() == WSAEBADF
)
1381 /* do not access pSockImpl because it is about to be or */
1382 /* already destroyed */
1383 return osl_Socket_Interrupted
;
1386 Result
= osl_Socket_Error
;
1390 Result
= osl_Socket_TimedOut
;
1395 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1401 /*****************************************************************************/
1402 /* osl_listenOnSocket */
1403 /*****************************************************************************/
1404 sal_Bool SAL_CALL
osl_listenOnSocket (
1406 sal_Int32 MaxPendingConnections
)
1408 if (pSocket
== NULL
) /* ENOTSOCK */
1411 return (listen(pSocket
->m_Socket
,
1412 MaxPendingConnections
== -1 ?
1414 MaxPendingConnections
) != OSL_SOCKET_ERROR
);
1417 /*****************************************************************************/
1418 /* osl_acceptConnectionOnSocket */
1419 /*****************************************************************************/
1420 oslSocket SAL_CALL
osl_acceptConnectionOnSocket (
1422 oslSocketAddr
* ppAddr
)
1424 if (pSocket
== NULL
) /* ENOTSOCK */
1425 return ((oslSocket
)NULL
);
1432 osl_destroySocketAddr( *ppAddr
);
1435 int AddrLen
= sizeof(struct sockaddr
);
1437 /* user wants to know peer Addr */
1438 struct sockaddr Addr
;
1440 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
1441 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
1443 if(Connection
!= OSL_SOCKET_ERROR
)
1444 *ppAddr
= __osl_createSocketAddrFromSystem(&Addr
);
1450 /* user is not interested in peer-addr */
1451 Connection
= accept(pSocket
->m_Socket
, 0, 0);
1454 /* accept failed? */
1455 if(Connection
== OSL_SOCKET_ERROR
)
1456 return ((oslSocket
)NULL
);
1459 oslSocket pConnectionSocket
;
1460 pConnectionSocket
= __osl_createSocketImpl(Connection
);
1462 pConnectionSocket
->m_Flags
= 0;
1463 pConnectionSocket
->m_CloseCallback
= NULL
;
1464 pConnectionSocket
->m_CallbackArg
= NULL
;
1466 return pConnectionSocket
;
1469 /*****************************************************************************/
1470 /* osl_receiveSocket */
1471 /*****************************************************************************/
1472 sal_Int32 SAL_CALL
osl_receiveSocket (
1475 sal_uInt32 BytesToRead
,
1476 oslSocketMsgFlag Flag
)
1478 if (pSocket
== NULL
) /* ENOTSOCK */
1479 return osl_Socket_Error
;
1481 return recv(pSocket
->m_Socket
,
1484 MSG_FLAG_TO_NATIVE(Flag
));
1487 /*****************************************************************************/
1488 /* osl_receiveFromSocket */
1489 /*****************************************************************************/
1490 sal_Int32 SAL_CALL
osl_receiveFromSocket (
1492 oslSocketAddr SenderAddr
,
1494 sal_uInt32 BufferSize
,
1495 oslSocketMsgFlag Flag
)
1497 struct sockaddr
*pSystemSockAddr
= 0;
1501 AddrLen
= sizeof( struct sockaddr
);
1502 pSystemSockAddr
= &(SenderAddr
->m_sockaddr
);
1505 if (pSocket
== NULL
) /* ENOTSOCK */
1506 return osl_Socket_Error
;
1508 return recvfrom(pSocket
->m_Socket
,
1511 MSG_FLAG_TO_NATIVE(Flag
),
1516 /*****************************************************************************/
1517 /* osl_sendSocket */
1518 /*****************************************************************************/
1519 sal_Int32 SAL_CALL
osl_sendSocket (
1521 const void* pBuffer
,
1522 sal_uInt32 BytesToSend
,
1523 oslSocketMsgFlag Flag
)
1525 if (pSocket
== NULL
) /* ENOTSOCK */
1526 return osl_Socket_Error
;
1528 return send(pSocket
->m_Socket
,
1531 MSG_FLAG_TO_NATIVE(Flag
));
1534 /*****************************************************************************/
1535 /* osl_sendToSocket */
1536 /*****************************************************************************/
1537 sal_Int32 SAL_CALL
osl_sendToSocket (
1539 oslSocketAddr ReceiverAddr
,
1540 const void* pBuffer
,
1541 sal_uInt32 BytesToSend
,
1542 oslSocketMsgFlag Flag
)
1544 if (pSocket
== NULL
) /* ENOTSOCK */
1545 return osl_Socket_Error
;
1547 /* ReceiverAddr might be 0 when used on a connected socket. */
1548 /* Then sendto should behave like send. */
1550 struct sockaddr
*pSystemSockAddr
= 0;
1552 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
1554 return sendto(pSocket
->m_Socket
,
1557 MSG_FLAG_TO_NATIVE(Flag
),
1559 pSystemSockAddr
== 0 ? 0 : sizeof(struct sockaddr
));
1562 /*****************************************************************************/
1563 /* osl_readSocket */
1564 /*****************************************************************************/
1565 sal_Int32 SAL_CALL
osl_readSocket( oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
1567 sal_uInt8
* Ptr
= (sal_uInt8
*)pBuffer
;
1569 OSL_ASSERT( pSocket
);
1571 /* loop until all desired bytes were read or an error occured */
1572 sal_uInt32 BytesRead
= 0;
1573 sal_uInt32 BytesToRead
= n
;
1574 while (BytesToRead
> 0)
1577 RetVal
= osl_receiveSocket(pSocket
,
1580 osl_Socket_MsgNormal
);
1582 /* error occured? */
1588 BytesToRead
-= RetVal
;
1589 BytesRead
+= RetVal
;
1596 /*****************************************************************************/
1597 /* osl_writeSocket */
1598 /*****************************************************************************/
1599 sal_Int32 SAL_CALL
osl_writeSocket( oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
1601 OSL_ASSERT( pSocket
);
1603 /* loop until all desired bytes were send or an error occured */
1604 sal_uInt32 BytesSend
= 0;
1605 sal_uInt32 BytesToSend
= n
;
1606 sal_uInt8
*Ptr
= ( sal_uInt8
* )pBuffer
;
1607 while (BytesToSend
> 0)
1611 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
1613 /* error occured? */
1619 BytesToSend
-= RetVal
;
1620 BytesSend
+= RetVal
;
1628 /*****************************************************************************/
1629 /* osl_isReceiveReady */
1630 /*****************************************************************************/
1631 sal_Bool SAL_CALL
osl_isReceiveReady (
1633 const TimeValue
* pTimeout
)
1638 if (pSocket
== NULL
) /* ENOTSOCK */
1642 FD_SET(pSocket
->m_Socket
, &fds
);
1646 tv
.tv_sec
= pTimeout
->Seconds
;
1647 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1650 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1651 &fds
, /* check read operations */
1652 0, /* check write ops */
1653 0, /* ckeck for OOB */
1654 (pTimeout
) ? &tv
: 0)==1); /* use timeout? */
1657 /*****************************************************************************/
1658 /* osl_isSendReady */
1659 /*****************************************************************************/
1660 sal_Bool SAL_CALL
osl_isSendReady (
1662 const TimeValue
* pTimeout
)
1667 if (pSocket
== NULL
) /* ENOTSOCK */
1671 FD_SET(pSocket
->m_Socket
, &fds
);
1675 tv
.tv_sec
= pTimeout
->Seconds
;
1676 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1679 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1680 0, /* check read operations */
1681 &fds
, /* check write ops */
1682 0, /* ckeck for OOB */
1683 (pTimeout
) ? &tv
: 0)==1); /* use timeout? */
1686 /*****************************************************************************/
1687 /* osl_isExceptionPending */
1688 /*****************************************************************************/
1689 sal_Bool SAL_CALL
osl_isExceptionPending (
1691 const TimeValue
* pTimeout
)
1696 if (pSocket
== NULL
) /* ENOTSOCK */
1700 FD_SET(pSocket
->m_Socket
, &fds
);
1704 tv
.tv_sec
= pTimeout
->Seconds
;
1705 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1708 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1709 0, /* check read operations */
1710 0, /* check write ops */
1711 &fds
, /* ckeck for OOB */
1712 (pTimeout
) ? &tv
: 0)==1); /* use timeout? */
1715 /*****************************************************************************/
1716 /* osl_shutdownSocket */
1717 /*****************************************************************************/
1718 sal_Bool SAL_CALL
osl_shutdownSocket (
1720 oslSocketDirection Direction
)
1722 if (pSocket
== NULL
) /* ENOTSOCK */
1725 return (shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
))==0);
1728 /*****************************************************************************/
1729 /* osl_getSocketOption */
1730 /*****************************************************************************/
1731 sal_Int32 SAL_CALL
osl_getSocketOption (
1733 oslSocketOptionLevel Level
,
1734 oslSocketOption Option
,
1736 sal_uInt32 BufferLen
)
1738 if (pSocket
== NULL
) /* ENOTSOCK */
1739 return osl_Socket_Error
;
1741 if (getsockopt(pSocket
->m_Socket
,
1742 OPTION_LEVEL_TO_NATIVE(Level
),
1743 OPTION_TO_NATIVE(Option
),
1745 (int*)&BufferLen
) == -1)
1750 return (sal_Int32
)BufferLen
;
1753 /*****************************************************************************/
1754 /* osl_setSocketOption */
1755 /*****************************************************************************/
1756 sal_Bool SAL_CALL
osl_setSocketOption (
1758 oslSocketOptionLevel Level
,
1759 oslSocketOption Option
,
1761 sal_uInt32 BufferLen
)
1763 if (pSocket
== NULL
) /* ENOTSOCK */
1766 return(setsockopt(pSocket
->m_Socket
,
1767 OPTION_LEVEL_TO_NATIVE(Level
),
1768 OPTION_TO_NATIVE(Option
),
1773 /*****************************************************************************/
1774 /* osl_enableNonBlockingMode */
1775 /*****************************************************************************/
1776 sal_Bool SAL_CALL
osl_enableNonBlockingMode ( oslSocket pSocket
, sal_Bool On
)
1778 unsigned long Param
= On
? 1 : 0;
1780 if (pSocket
== NULL
) /* ENOTSOCK */
1783 pSocket
->m_Flags
= Param
?
1784 (pSocket
->m_Flags
| OSL_SOCKET_FLAGS_NONBLOCKING
) :
1785 (pSocket
->m_Flags
& ~OSL_SOCKET_FLAGS_NONBLOCKING
) ;
1788 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
) != OSL_SOCKET_ERROR
);
1791 /*****************************************************************************/
1792 /* osl_isNonBlockingMode */
1793 /*****************************************************************************/
1794 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
1796 if (pSocket
== NULL
) /* ENOTSOCK */
1799 return (sal_Bool
)((pSocket
->m_Flags
& OSL_SOCKET_FLAGS_NONBLOCKING
) != 0);
1802 /*****************************************************************************/
1803 /* osl_getSocketType */
1804 /*****************************************************************************/
1805 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
1808 int TypeSize
= sizeof(Type
);
1810 if (pSocket
== NULL
) /* ENOTSOCK */
1811 return osl_Socket_TypeInvalid
;
1813 if(getsockopt(pSocket
->m_Socket
,
1814 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
1815 OPTION_TO_NATIVE(osl_Socket_OptionType
),
1820 return osl_Socket_TypeInvalid
;
1823 return TYPE_FROM_NATIVE(Type
);
1826 /*****************************************************************************/
1827 /* osl_getLastSocketErrorDescription */
1828 /*****************************************************************************/
1829 void SAL_CALL
osl_getLastSocketErrorDescription (
1830 oslSocket
/*Socket*/,
1831 rtl_uString
**strError
)
1835 switch(error
= WSAGetLastError())
1838 rtl_uString_newFromAscii (strError
, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1841 case WSAEDESTADDRREQ
:
1842 rtl_uString_newFromAscii (strError
, "WSAEDESTADDRREQ, Destination Addr required");
1846 rtl_uString_newFromAscii (strError
, "WSAEMSGSIZE, Message too long");
1850 rtl_uString_newFromAscii (strError
, "WSAEPROTOTYPE, Protocol wrong type for socket");
1853 case WSAENOPROTOOPT
:
1854 rtl_uString_newFromAscii (strError
, "WSAENOPROTOOPT, Protocol not available");
1857 case WSAEPROTONOSUPPORT
:
1858 rtl_uString_newFromAscii (strError
, "WSAEPROTONOSUPPORT, Protocol not supported");
1861 case WSAESOCKTNOSUPPORT
:
1862 rtl_uString_newFromAscii (strError
, "WSAESOCKTNOSUPPORT, Socket type not supported");
1866 rtl_uString_newFromAscii (strError
, "WSAEOPNOTSUPP, Operation not supported on socket");
1869 case WSAEPFNOSUPPORT
:
1870 rtl_uString_newFromAscii (strError
, "WSAEPFNOSUPPORT, Protocol family not supported");
1873 case WSAEAFNOSUPPORT
:
1874 rtl_uString_newFromAscii (strError
, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1878 rtl_uString_newFromAscii (strError
, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1881 case WSAEADDRNOTAVAIL
:
1882 rtl_uString_newFromAscii (strError
, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1886 rtl_uString_newFromAscii (strError
, "WSAENETDOWN, Network is down");
1889 case WSAENETUNREACH
:
1890 rtl_uString_newFromAscii (strError
, "WSAENETUNREACH, Network is unreachable");
1894 rtl_uString_newFromAscii (strError
, "WSAENETRESET, Network dropped connection or reset");
1897 case WSAECONNABORTED
:
1898 rtl_uString_newFromAscii (strError
, "WSAECONNABORTED, Software caused connection abort");
1902 rtl_uString_newFromAscii (strError
, "WSAECONNRESET, Connection reset by peer");
1906 rtl_uString_newFromAscii (strError
, "WSAENOBUFS, No buffer space available.");
1910 rtl_uString_newFromAscii (strError
, "WSAEISCONN, Socket is already connected");
1914 rtl_uString_newFromAscii (strError
, "WSAENOTCONN, Socket is not connected");
1918 rtl_uString_newFromAscii (strError
, "WSAESHUTDOWN, Can't send after socket shutdown");
1922 rtl_uString_newFromAscii (strError
, "WSAETIMEDOUT, Connection timed out");
1925 case WSAECONNREFUSED
:
1926 rtl_uString_newFromAscii (strError
, "WSAECONNREFUSED, Connection refused");
1930 rtl_uString_newFromAscii (strError
, "WSAEHOSTDOWN, Networking subsystem not started");
1933 case WSAEHOSTUNREACH
:
1934 rtl_uString_newFromAscii (strError
, "WSAEHOSTUNREACH, No route to host");
1937 case WSAEWOULDBLOCK
:
1938 rtl_uString_newFromAscii (strError
, "WSAEWOULDBLOCK, Operation would block");
1941 case WSAEINPROGRESS
:
1942 rtl_uString_newFromAscii (strError
, "WSAEINPROGRESS, Operation now in progress");
1946 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation already in progress");
1950 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation was interrupted");
1954 rtl_uString_newFromAscii (strError
, "WSAEBADF, Bad file number");
1958 rtl_uString_newFromAscii (strError
, "WSAEACCES, Access is denied");
1962 rtl_uString_newFromAscii (strError
, "WSAEFAULT, Bad memory Addr");
1966 rtl_uString_newFromAscii (strError
, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1970 rtl_uString_newFromAscii (strError
, "WSAEMFILE, No more file descriptors are available");
1973 case WSAETOOMANYREFS
:
1974 rtl_uString_newFromAscii (strError
, "WSAETOOMANYREFS, Undocumented WinSock error");
1977 case WSAENAMETOOLONG
:
1978 rtl_uString_newFromAscii (strError
, "WSAENAMETOOLONG, Undocumented WinSock error");
1982 rtl_uString_newFromAscii (strError
, "WSAENOTEMPTY, Undocumented WinSock error");
1986 rtl_uString_newFromAscii (strError
, "WSAEPROCLIM, Undocumented WinSock error");
1990 rtl_uString_newFromAscii (strError
, "WSAEUSERS, Undocumented WinSock error");
1994 rtl_uString_newFromAscii (strError
, "WSAEDQUOT, Undocumented WinSock error");
1998 rtl_uString_newFromAscii (strError
, "WSAESTALE, Undocumented WinSock error");
2002 rtl_uString_newFromAscii (strError
, "WSAEREMOTE, Undocumented WinSock error");
2006 rtl_uString_newFromAscii (strError
, "WSAEDISCON, Circuit was gracefully terminated");
2009 case WSASYSNOTREADY
:
2010 rtl_uString_newFromAscii (strError
, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
2013 case WSAVERNOTSUPPORTED
:
2014 rtl_uString_newFromAscii (strError
, "WSAVERNOTSUPPORTED, The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation");
2017 case WSANOTINITIALISED
:
2018 rtl_uString_newFromAscii (strError
, "WSANOTINITIALISED, WSAStartup() has not been called");
2021 case WSAHOST_NOT_FOUND
:
2022 rtl_uString_newFromAscii (strError
, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
2026 rtl_uString_newFromAscii (strError
, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
2029 case WSANO_RECOVERY
:
2030 rtl_uString_newFromAscii (strError
, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
2034 rtl_uString_newFromAscii (strError
, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
2039 sal_Unicode message
[128];
2041 wsprintfW(reinterpret_cast<LPWSTR
>(message
), L
"Unknown WinSock Error Number %d", error
);
2042 rtl_uString_newFromStr (strError
, message
);
2050 /*****************************************************************************/
2051 /* osl_getLastSocketError */
2052 /*****************************************************************************/
2053 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket
/*Socket*/)
2055 return ERROR_FROM_NATIVE(WSAGetLastError());
2058 /*****************************************************************************/
2060 /*****************************************************************************/
2061 typedef struct _TSocketSetImpl
2063 fd_set m_Set
; /* the set of descriptors */
2067 /*****************************************************************************/
2068 /* osl_createSocketSet */
2069 /*****************************************************************************/
2070 oslSocketSet SAL_CALL
osl_createSocketSet()
2072 TSocketSetImpl
* pSet
;
2074 pSet
= (TSocketSetImpl
*) rtl_allocateMemory(sizeof(TSocketSetImpl
));
2078 FD_ZERO(&pSet
->m_Set
);
2081 return (oslSocketSet
)pSet
;
2084 /*****************************************************************************/
2085 /* osl_destroySocketSet */
2086 /*****************************************************************************/
2087 void SAL_CALL
osl_destroySocketSet (oslSocketSet Set
)
2090 rtl_freeMemory(Set
);
2093 /*****************************************************************************/
2094 /* osl_clearSocketSet */
2095 /*****************************************************************************/
2096 void SAL_CALL
osl_clearSocketSet (oslSocketSet Set
)
2098 TSocketSetImpl
* pSet
;
2100 pSet
= (TSocketSetImpl
*)Set
;
2103 FD_ZERO(&pSet
->m_Set
);
2106 /*****************************************************************************/
2107 /* osl_addToSocketSet */
2108 /*****************************************************************************/
2109 void SAL_CALL
osl_addToSocketSet (
2113 TSocketSetImpl
* pSet
;
2114 oslSocketImpl
* pSockImpl
;
2116 pSet
= (TSocketSetImpl
*)Set
;
2117 pSockImpl
= (oslSocketImpl
*)Socket
;
2119 if (pSet
&& pSockImpl
)
2120 FD_SET(pSockImpl
->m_Socket
, &pSet
->m_Set
);
2123 /*****************************************************************************/
2124 /* osl_removeFromSocketSet */
2125 /*****************************************************************************/
2126 void SAL_CALL
osl_removeFromSocketSet (
2130 TSocketSetImpl
* pSet
;
2131 oslSocketImpl
* pSockImpl
;
2133 pSet
= (TSocketSetImpl
*)Set
;
2134 pSockImpl
= (oslSocketImpl
*)Socket
;
2136 if (pSet
&& pSockImpl
)
2137 FD_CLR(pSockImpl
->m_Socket
, &pSet
->m_Set
);
2140 /*****************************************************************************/
2141 /* osl_isInSocketSet */
2142 /*****************************************************************************/
2143 sal_Bool SAL_CALL
osl_isInSocketSet (
2147 TSocketSetImpl
* pSet
;
2148 oslSocketImpl
* pSockImpl
;
2150 pSet
= (TSocketSetImpl
*)Set
;
2151 pSockImpl
= (oslSocketImpl
*)Socket
;
2153 if (pSet
&& pSockImpl
)
2154 return (FD_ISSET(pSockImpl
->m_Socket
, &pSet
->m_Set
) != 0);
2159 /*****************************************************************************/
2160 /* osl_demultiplexSocketEvents */
2161 /*****************************************************************************/
2162 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents (
2163 oslSocketSet IncomingSet
,
2164 oslSocketSet OutgoingSet
,
2165 oslSocketSet OutOfBandSet
,
2166 const TimeValue
* pTimeout
)
2170 TSocketSetImpl
* pInSet
;
2171 TSocketSetImpl
* pOutSet
;
2172 TSocketSetImpl
* pOOBSet
;
2176 /* divide milliseconds into seconds and microseconds */
2177 tv
.tv_sec
= pTimeout
->Seconds
;
2178 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
2181 /* map opaque data to impl-types */
2182 pInSet
= (TSocketSetImpl
*)IncomingSet
;
2183 pOutSet
= (TSocketSetImpl
*)OutgoingSet
;
2184 pOOBSet
= (TSocketSetImpl
*)OutOfBandSet
;
2186 return select(MaxHandle
, /* redundant in WIN32 */
2187 pInSet
? &pInSet
->m_Set
: 0,
2188 pOutSet
? &pOutSet
->m_Set
: 0,
2189 pOOBSet
? &pOOBSet
->m_Set
: 0,
2190 pTimeout
? &tv
: 0);