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 .
20 #include <sal/config.h>
26 #include <osl/socket.h>
27 #include <osl/thread.h>
28 #include <osl/diagnose.h>
29 #include <rtl/alloc.h>
30 #include <rtl/byteseq.h>
31 #include <sal/log.hxx>
32 #include <o3tl/char16_t2wchar_t.hxx>
33 #include <comphelper/windowserrorstring.hxx>
35 #include "sockimpl.hxx"
38 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
39 I refrained from using sockaddr_in because of possible further
40 extensions of this socket-interface (IP-NG?).
41 The intention was to hide all Berkeley data-structures from
42 direct access past the osl-interface.
44 The current implementation is internet (IP) centered. All
45 the constructor-functions (osl_create...) take parameters
46 that will probably make sense only in the IP-environment
47 (e.g. because of using the dotted-Addr-format).
49 If the interface will be extended to host other protocol-
50 families, I expect no externally visible changes in the
51 existing functions. You'll probably need only new
52 constructor-functions who take the different Addr
53 formats into consideration (maybe a long dotted Addr
58 _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr
59 are the same! I don't like it very much but see no other easy way to
60 conceal the struct sockaddr from the eyes of the user.
63 #define OSL_INVALID_SOCKET INVALID_SOCKET /* WIN32 */
64 #define OSL_SOCKET_ERROR SOCKET_ERROR /* WIN32 */
66 static DWORD FamilyMap
[]= {
67 AF_INET
, /* osl_Socket_FamilyInet */
68 AF_IPX
, /* osl_Socket_FamilyIpx */
69 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
= static_cast<oslAddrFamily
>( static_cast<int>(i
) + 1);
84 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
85 #define FAMILY_TO_NATIVE(x) static_cast<short>(FamilyMap[x])
87 static DWORD ProtocolMap
[]= {
88 0, /* osl_Socket_FamilyInet */
89 NSPROTO_IPX
, /* osl_Socket_FamilyIpx */
90 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
91 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpx_ii */
92 0 /* osl_Socket_ProtocolInvalid */
95 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
97 static DWORD TypeMap
[]= {
98 SOCK_STREAM
, /* osl_Socket_TypeStream */
99 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
100 SOCK_RAW
, /* osl_Socket_TypeRaw */
101 SOCK_RDM
, /* osl_Socket_TypeRdm */
102 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
103 0 /* osl_Socket_TypeInvalid */
106 static oslSocketType
osl_SocketTypeFromNative(DWORD nativeType
)
108 oslSocketType i
= oslSocketType(0);
109 while(i
!= osl_Socket_TypeInvalid
)
111 if(TypeMap
[i
] == nativeType
)
113 i
= static_cast<oslSocketType
>(static_cast<int>(i
)+1);
118 #define TYPE_TO_NATIVE(x) TypeMap[x]
119 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
121 static DWORD OptionMap
[]= {
122 SO_DEBUG
, /* osl_Socket_OptionDebug */
123 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
124 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
125 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
126 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
127 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
128 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
129 SO_LINGER
, /* osl_Socket_OptionLinger */
130 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
131 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
132 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
133 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
134 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
135 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
136 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
137 SO_ERROR
, /* osl_Socket_OptionError */
138 SO_TYPE
, /* osl_Socket_OptionType */
139 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
140 0 /* osl_Socket_OptionInvalid */
143 #define OPTION_TO_NATIVE(x) OptionMap[x]
145 static DWORD OptionLevelMap
[]= {
146 SOL_SOCKET
, /* osl_Socket_LevelSocket */
147 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
148 0 /* osl_invalid_SocketLevel */
151 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
153 static DWORD SocketMsgFlagMap
[]= {
154 0, /* osl_Socket_MsgNormal */
155 MSG_OOB
, /* osl_Socket_MsgOOB */
156 MSG_PEEK
, /* osl_Socket_MsgPeek */
157 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
158 MSG_MAXIOVLEN
/* osl_Socket_MsgMaxIOVLen */
161 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
163 static DWORD SocketDirection
[]= {
164 SD_RECEIVE
, /* osl_Socket_DirRead */
165 SD_SEND
, /* osl_Socket_DirWrite */
166 SD_BOTH
/* osl_Socket_DirReadwrite */
169 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
171 static int SocketError
[]= {
173 WSAENOTSOCK
, /* Socket operation on non-socket */
174 WSAEDESTADDRREQ
, /* Destination address required */
175 WSAEMSGSIZE
, /* Message too long */
176 WSAEPROTOTYPE
, /* Protocol wrong type for socket */
177 WSAENOPROTOOPT
, /* Protocol not available */
178 WSAEPROTONOSUPPORT
, /* Protocol not supported */
179 WSAESOCKTNOSUPPORT
, /* Socket type not supported */
180 WSAEOPNOTSUPP
, /* Operation not supported on socket */
181 WSAEPFNOSUPPORT
, /* Protocol family not supported */
182 WSAEAFNOSUPPORT
, /* Address family not supported by protocol family */
183 WSAEADDRINUSE
, /* Address already in use */
184 WSAEADDRNOTAVAIL
, /* Can't assign requested address */
185 WSAENETDOWN
, /* Network is down */
186 WSAENETUNREACH
, /* Network is unreachable */
187 WSAENETRESET
, /* Network dropped connection because of reset */
188 WSAECONNABORTED
, /* Software caused connection abort */
189 WSAECONNRESET
, /* Connection reset by peer */
190 WSAENOBUFS
, /* No buffer space available */
191 WSAEISCONN
, /* Socket is already connected */
192 WSAENOTCONN
, /* Socket is not connected */
193 WSAESHUTDOWN
, /* Can't send after socket shutdown */
194 WSAETOOMANYREFS
, /* Too many references: can't splice */
195 WSAETIMEDOUT
, /* Connection timed out */
196 WSAECONNREFUSED
, /* Connection refused */
197 WSAEHOSTDOWN
, /* Host is down */
198 WSAEHOSTUNREACH
, /* No route to host */
199 WSAEWOULDBLOCK
, /* call would block on non-blocking socket */
200 WSAEALREADY
, /* operation already in progress */
201 WSAEINPROGRESS
/* operation now in progress */
204 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
206 oslSocketError i
= oslSocketError(0);
208 while(i
!= osl_Socket_E_InvalidError
)
210 if(SocketError
[i
] == nativeType
)
213 i
= static_cast<oslSocketError
>( static_cast<int>(i
) + 1);
218 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
220 #if OSL_DEBUG_LEVEL > 0
221 static sal_uInt32 g_nSocketAddr
= 0;
226 SAL_WARN_IF( g_nSocketAddr
, "sal.osl", "sal_socket: " << g_nSocketAddr
<< " socket address instances leak" );
229 static LeakWarning socketWarning
;
232 static oslSocket
createSocketImpl(SOCKET Socket
)
234 oslSocket pSockImpl
= static_cast<oslSocket
>(rtl_allocateZeroMemory( sizeof(struct oslSocketImpl
)));
235 pSockImpl
->m_Socket
= Socket
;
236 pSockImpl
->m_nRefCount
= 1;
240 static void destroySocketImpl(oslSocketImpl
*pImpl
)
248 static oslSocketAddr
createSocketAddr( )
250 oslSocketAddr pAddr
= static_cast<oslSocketAddr
>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
)));
251 pAddr
->m_nRefCount
= 1;
252 #if OSL_DEBUG_LEVEL > 0
258 static oslSocketAddr
createSocketAddrWithFamily(
259 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
261 OSL_ASSERT( family
== osl_Socket_FamilyInet
);
263 oslSocketAddr pAddr
= createSocketAddr();
266 case osl_Socket_FamilyInet
:
268 struct sockaddr_in
* pInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
270 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
271 pInetAddr
->sin_addr
.s_addr
= nAddr
;
272 pInetAddr
->sin_port
= static_cast<sal_uInt16
>(port
&0xffff);
276 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
281 static oslSocketAddr
createSocketAddFromSystem( struct sockaddr
*pSystemSockAddr
)
283 oslSocketAddr pAddr
= createSocketAddr();
284 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( sockaddr
) );
288 static void destroySocketAddr( oslSocketAddr addr
)
290 #if OSL_DEBUG_LEVEL > 0
296 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
298 oslSocketAddr pAddr
= nullptr;
300 /* is it an internet-Addr? */
301 if (Family
== osl_Socket_FamilyInet
)
302 pAddr
= createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
304 pAddr
= createSocketAddrWithFamily( Family
, 0 , 0 );
309 /** @deprecated, to be removed */
310 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
312 oslSocketAddr pCopy
= nullptr;
315 pCopy
= createSocketAddr();
318 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
323 sal_Bool SAL_CALL
osl_isEqualSocketAddr(oslSocketAddr Addr1
, oslSocketAddr Addr2
)
327 struct sockaddr
* pAddr1
= &(Addr1
->m_sockaddr
);
328 struct sockaddr
* pAddr2
= &(Addr2
->m_sockaddr
);
333 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
335 switch (pAddr1
->sa_family
)
339 struct sockaddr_in
* pInetAddr1
= reinterpret_cast<struct sockaddr_in
*>(pAddr1
);
340 struct sockaddr_in
* pInetAddr2
= reinterpret_cast<struct sockaddr_in
*>(pAddr2
);
342 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
343 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
344 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
351 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
359 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
360 rtl_uString
*strDottedAddr
,
363 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
365 if (strDottedAddr
&& strDottedAddr
->length
)
368 INT ret
= InetPtonW(AF_INET
, o3tl::toW(strDottedAddr
->buffer
), & addr
);
371 nAddr
= addr
.S_un
.S_addr
;
375 if (nAddr
!= OSL_INADDR_NONE
)
377 /* Limited broadcast */
378 nAddr
= ntohl(nAddr
);
379 if (IN_CLASSA(nAddr
))
381 nAddr
&= IN_CLASSA_NET
;
382 nAddr
|= IN_CLASSA_HOST
;
384 else if (IN_CLASSB(nAddr
))
386 nAddr
&= IN_CLASSB_NET
;
387 nAddr
|= IN_CLASSB_HOST
;
389 else if (IN_CLASSC(nAddr
))
391 nAddr
&= IN_CLASSC_NET
;
392 nAddr
|= IN_CLASSC_HOST
;
396 /* No broadcast in class D */
399 nAddr
= htonl(nAddr
);
402 oslSocketAddr pAddr
=
403 createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons( static_cast<sal_uInt16
>(Port
)), nAddr
);
407 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
408 rtl_uString
*strDottedAddr
,
414 INT ret
= InetPtonW(AF_INET
, o3tl::toW(strDottedAddr
->buffer
), & addr
);
415 Addr
= ret
== 1 ? addr
.S_un
.S_addr
: OSL_INADDR_NONE
;
417 oslSocketAddr pAddr
= nullptr;
418 if(Addr
!= OSL_INADDR_NONE
)
420 pAddr
= createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons( static_cast<sal_uInt16
>(Port
)), Addr
);
425 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
428 OSL_ASSERT( pByteSeq
);
430 oslSocketResult res
= osl_Socket_Error
;
431 if( pAddr
&& pByteSeq
)
433 OSL_ASSERT( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
434 OSL_ASSERT( pByteSeq
->nElements
== 4 );
435 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
436 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
442 /** Returns the addr field in the struct sockaddr. ppByteSeq is in network byteorder. *ppByteSeq may
443 either be 0 or contain a constructed sal_Sequence.
445 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
448 OSL_ASSERT( ppByteSeq
);
450 oslSocketResult res
= osl_Socket_Error
;
451 if( pAddr
&& ppByteSeq
)
453 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
454 rtl_byte_sequence_constructFromArray( ppByteSeq
, reinterpret_cast<sal_Int8
*>(&pSystemInetAddr
->sin_addr
),4);
460 struct oslHostAddrImpl
{
461 rtl_uString
*pHostName
;
462 oslSocketAddr pSockAddr
;
465 oslHostAddr SAL_CALL
osl_createHostAddr (
466 rtl_uString
*strHostname
,
467 const oslSocketAddr pSocketAddr
)
470 rtl_uString
*cn
= nullptr;
472 if ((strHostname
== nullptr) || (strHostname
->length
== 0) || (pSocketAddr
== nullptr))
475 rtl_uString_newFromString( &cn
, strHostname
);
477 pAddr
= static_cast<oslHostAddr
>(malloc (sizeof (struct oslHostAddrImpl
)));
479 if (pAddr
== nullptr)
481 rtl_uString_release(cn
);
485 pAddr
->pHostName
= cn
;
486 pAddr
->pSockAddr
= osl_copySocketAddr( pSocketAddr
);
491 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*strHostname
)
493 if ((strHostname
== nullptr) || (strHostname
->length
== 0))
496 PADDRINFOW pAddrInfo
= nullptr;
497 int ret
= GetAddrInfoW(
498 o3tl::toW(strHostname
->buffer
), nullptr, nullptr, & pAddrInfo
);
501 oslHostAddr pRet
= nullptr;
502 for (PADDRINFOW pIter
= pAddrInfo
; pIter
; pIter
= pIter
->ai_next
)
504 if (AF_INET
== pIter
->ai_family
)
506 pRet
= static_cast<oslHostAddr
>(
507 rtl_allocateZeroMemory(sizeof(struct oslHostAddrImpl
)));
508 rtl_uString_newFromStr(&pRet
->pHostName
, o3tl::toU(pIter
->ai_canonname
));
509 pRet
->pSockAddr
= createSocketAddr();
510 memcpy(& pRet
->pSockAddr
->m_sockaddr
,
511 pIter
->ai_addr
, pIter
->ai_addrlen
);
512 break; // ignore other results
515 FreeAddrInfoW(pAddrInfo
);
520 SAL_INFO("sal.osl", "GetAddrInfoW failed: " << WSAGetLastError());
525 oslHostAddr SAL_CALL
osl_createHostAddrByAddr(const oslSocketAddr pAddr
)
527 if (pAddr
== nullptr)
530 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
532 const struct sockaddr_in
*sin
= reinterpret_cast<const struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
534 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
537 WCHAR buf
[NI_MAXHOST
];
538 int ret
= GetNameInfoW(
539 & pAddr
->m_sockaddr
, sizeof(struct sockaddr
),
544 oslHostAddr pRet
= static_cast<oslHostAddr
>(
545 rtl_allocateZeroMemory(sizeof(struct oslHostAddrImpl
)));
546 rtl_uString_newFromStr(&pRet
->pHostName
, o3tl::toU(buf
));
547 pRet
->pSockAddr
= createSocketAddr();
548 memcpy(& pRet
->pSockAddr
->m_sockaddr
,
549 & pAddr
->m_sockaddr
, sizeof(struct sockaddr
));
554 SAL_INFO("sal.osl", "GetNameInfoW failed: " << WSAGetLastError());
561 oslHostAddr SAL_CALL
osl_copyHostAddr(const oslHostAddr Addr
)
563 oslHostAddr pAddr
= Addr
;
566 return osl_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
571 void SAL_CALL
osl_getHostnameOfHostAddr(
572 const oslHostAddr pAddr
, rtl_uString
**strHostname
)
575 rtl_uString_assign (strHostname
, pAddr
->pHostName
);
577 rtl_uString_new (strHostname
);
580 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr
)
583 return pAddr
->pSockAddr
;
588 void SAL_CALL
osl_destroyHostAddr(oslHostAddr pAddr
)
592 if (pAddr
->pHostName
)
593 rtl_uString_release (pAddr
->pHostName
);
594 if (pAddr
->pSockAddr
)
595 osl_destroySocketAddr( pAddr
->pSockAddr
);
601 oslSocketResult SAL_CALL
osl_getLocalHostname (rtl_uString
**strLocalHostname
)
603 static auto const init
= []() -> std::pair
<oslSocketResult
, OUString
> {
604 sal_Unicode LocalHostname
[256] = {0};
606 sal_Char Host
[256]= "";
607 if (gethostname(Host
, sizeof(Host
)) == 0)
609 /* check if we have an FQDN; if not, try to determine it via dns first: */
610 if (strchr(Host
, '.') == nullptr)
613 rtl_uString
*hostName
= nullptr;
616 &hostName
, Host
, strlen(Host
),
617 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
618 OSL_ASSERT(hostName
!= nullptr);
620 pAddr
= osl_createHostAddrByName(hostName
);
621 rtl_uString_release (hostName
);
623 if (pAddr
&& pAddr
->pHostName
)
624 memcpy(LocalHostname
, pAddr
->pHostName
->buffer
, sizeof(sal_Unicode
)*(rtl_ustr_getLength(pAddr
->pHostName
->buffer
)+1));
626 memset(LocalHostname
, 0, sizeof(LocalHostname
));
628 osl_destroyHostAddr (pAddr
);
630 if (LocalHostname
[0] == u
'\0')
633 if (rtl_convertStringToUString(
634 &u
.pData
, Host
, strlen(Host
), osl_getThreadTextEncoding(),
635 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
636 | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
637 | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR
))
638 && sal_uInt32(u
.getLength()) < SAL_N_ELEMENTS(LocalHostname
))
640 memcpy(LocalHostname
, u
.getStr(), (u
.getLength() + 1) * sizeof (sal_Unicode
));
645 if (rtl_ustr_getLength(LocalHostname
) > 0)
647 return {osl_Socket_Ok
, LocalHostname
};
650 return {osl_Socket_Error
, OUString()};
653 rtl_uString_assign (strLocalHostname
, init
.second
.pData
);
658 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
* strHostname
)
660 oslHostAddr pAddr
= osl_createHostAddrByName (strHostname
);
663 oslSocketAddr SockAddr
= osl_copySocketAddr( pAddr
->pSockAddr
);
664 osl_destroyHostAddr(pAddr
);
670 sal_Int32 SAL_CALL
osl_getServicePort (
671 rtl_uString
* strServicename
,
672 rtl_uString
* strProtocol
)
676 rtl_String
*str_Servicename
=nullptr;
677 rtl_String
*str_Protocol
=nullptr;
681 rtl_uString_getStr(strServicename
),
682 rtl_uString_getLength(strServicename
),
683 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
686 rtl_uString_getStr(strProtocol
),
687 rtl_uString_getLength(strProtocol
),
688 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
691 rtl_string_getStr(str_Servicename
),
692 rtl_string_getStr(str_Protocol
));
694 rtl_string_release( str_Servicename
);
695 rtl_string_release( str_Protocol
);
698 return ntohs(ps
->s_port
);
700 return OSL_INVALID_PORT
;
703 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
705 destroySocketAddr( pAddr
);
708 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
711 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
713 return osl_Socket_FamilyInvalid
;
716 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
720 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
722 if (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
723 return ntohs(pSystemInetAddr
->sin_port
);
725 return OSL_INVALID_PORT
;
728 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr (
732 if (pAddr
== nullptr)
735 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
737 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
740 pSystemInetAddr
->sin_port
= htons(static_cast<short>(Port
));
744 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr (
746 rtl_uString
**strHostName
)
748 oslHostAddr pAddr
= osl_createHostAddrByAddr (Addr
);
752 rtl_uString_newFromString(strHostName
, pAddr
->pHostName
);
754 osl_destroyHostAddr(pAddr
);
756 return osl_Socket_Ok
;
759 return osl_Socket_Error
;
762 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr (
764 rtl_uString
**strDottedInetAddr
)
766 if (pAddr
== nullptr)
767 return osl_Socket_Error
;
769 struct sockaddr_in
*pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
770 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
771 return osl_Socket_Error
;
773 *strDottedInetAddr
= nullptr;
774 WCHAR buf
[16]; // 16 for IPV4, 46 for IPV6
775 PCWSTR ret
= InetNtopW(
776 AF_INET
, & pSystemInetAddr
->sin_addr
,
777 buf
, SAL_N_ELEMENTS(buf
));
780 SAL_INFO("sal.osl", "InetNtopW failed: " << WSAGetLastError());
781 return osl_Socket_Error
;
783 rtl_uString_newFromStr(strDottedInetAddr
, o3tl::toU(ret
));
784 OSL_ASSERT(*strDottedInetAddr
!= nullptr);
786 return osl_Socket_Ok
;
789 oslSocket SAL_CALL
osl_createSocket(
790 oslAddrFamily Family
,
792 oslProtocol Protocol
)
795 oslSocket pSocket
= createSocketImpl(0);
797 if (pSocket
== nullptr)
801 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
802 TYPE_TO_NATIVE(Type
),
803 PROTOCOL_TO_NATIVE(Protocol
));
805 /* creation failed => free memory */
806 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
808 int nErrno
= WSAGetLastError();
809 SAL_WARN("sal.osl", "socket creation failed: (" << nErrno
<< "): " << WindowsErrorString(nErrno
));
811 destroySocketImpl(pSocket
);
816 pSocket
->m_Flags
= 0;
822 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
824 osl_atomic_increment(&(pSocket
->m_nRefCount
));
827 void SAL_CALL
osl_releaseSocket(oslSocket pSocket
)
829 if (pSocket
&& osl_atomic_decrement(&(pSocket
->m_nRefCount
)) == 0)
831 osl_closeSocket(pSocket
);
832 destroySocketImpl(pSocket
);
836 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
838 /* socket already invalid */
843 closesocket(pSocket
->m_Socket
);
845 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
849 Note that I rely on the fact that oslSocketAddr and struct sockaddr
850 are the same! I don't like it very much but see no other easy way
851 to conceal the struct sockaddr from the eyes of the user.
853 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
855 struct sockaddr Addr
;
858 if (pSocket
== nullptr) /* ENOTSOCK */
861 AddrLen
= sizeof(struct sockaddr
);
863 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
866 oslSocketAddr pAddr
= createSocketAddFromSystem( &Addr
);
870 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
872 struct sockaddr Addr
;
875 if (pSocket
== nullptr) /* ENOTSOCK */
878 AddrLen
= sizeof(struct sockaddr
);
880 if (getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
883 oslSocketAddr pAddr
= createSocketAddFromSystem( &Addr
);
887 sal_Bool SAL_CALL
osl_bindAddrToSocket ( oslSocket pSocket
, oslSocketAddr pAddr
)
891 if (pSocket
== nullptr) /* ENOTSOCK */
894 return (bind(pSocket
->m_Socket
,
895 &(pAddr
->m_sockaddr
),
896 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
);
899 oslSocketResult SAL_CALL
osl_connectSocketTo (
902 const TimeValue
* pTimeout
)
905 if (pSocket
== nullptr) /* ENOTSOCK */
906 return osl_Socket_Error
;
908 if (pAddr
== nullptr) /* EDESTADDRREQ */
909 return osl_Socket_Error
;
911 if (pTimeout
== nullptr)
913 if(connect(pSocket
->m_Socket
,
914 &(pAddr
->m_sockaddr
),
915 sizeof(struct sockaddr
)) == OSL_SOCKET_ERROR
)
916 return osl_Socket_Error
;
918 return osl_Socket_Ok
;
926 oslSocketResult Result
= osl_Socket_Ok
;
928 if (pSocket
->m_Flags
& OSL_SOCKET_FLAGS_NONBLOCKING
)
930 if (connect(pSocket
->m_Socket
,
931 &(pAddr
->m_sockaddr
),
932 sizeof(struct sockaddr
)) == OSL_SOCKET_ERROR
)
934 switch (WSAGetLastError())
938 return osl_Socket_InProgress
;
941 return osl_Socket_Error
;
945 return osl_Socket_Ok
;
948 /* set socket temporarily to non-blocking */
950 OSL_VERIFY(ioctlsocket(
951 pSocket
->m_Socket
, FIONBIO
, &Param
) != OSL_SOCKET_ERROR
);
953 /* initiate connect */
954 if (connect(pSocket
->m_Socket
,
955 &(pAddr
->m_sockaddr
),
956 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
958 /* immediate connection */
961 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
963 return osl_Socket_Ok
;
967 error
= WSAGetLastError();
969 /* really an error or just delayed? */
970 if (error
!= WSAEWOULDBLOCK
&& error
!= WSAEINPROGRESS
)
973 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
975 return osl_Socket_Error
;
979 /* prepare select set for socket */
981 FD_SET(pSocket
->m_Socket
, &fds
);
983 /* divide milliseconds into seconds and microseconds */
984 tv
.tv_sec
= pTimeout
->Seconds
;
985 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
988 error
= select(pSocket
->m_Socket
+1,
994 if (error
> 0) /* connected */
997 !FD_ISSET(pSocket
->m_Socket
, &fds
),
999 "osl_connectSocketTo(): select returned but socket not set");
1001 Result
= osl_Socket_Ok
;
1004 else if(error
< 0) /* error */
1006 /* errno == EBADF: most probably interrupted by close() */
1007 if(WSAGetLastError() == WSAEBADF
)
1009 /* do not access pSockImpl because it is about to be or */
1010 /* already destroyed */
1011 return osl_Socket_Interrupted
;
1014 Result
= osl_Socket_Error
;
1018 Result
= osl_Socket_TimedOut
;
1022 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1028 sal_Bool SAL_CALL
osl_listenOnSocket (
1030 sal_Int32 MaxPendingConnections
)
1032 if (pSocket
== nullptr) /* ENOTSOCK */
1035 return (listen(pSocket
->m_Socket
,
1036 MaxPendingConnections
== -1 ?
1038 MaxPendingConnections
) != OSL_SOCKET_ERROR
);
1041 oslSocket SAL_CALL
osl_acceptConnectionOnSocket (
1043 oslSocketAddr
* ppAddr
)
1045 if (pSocket
== nullptr) /* ENOTSOCK */
1053 osl_destroySocketAddr( *ppAddr
);
1056 int AddrLen
= sizeof(struct sockaddr
);
1058 /* user wants to know peer Addr */
1059 struct sockaddr Addr
;
1061 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
1062 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
1064 if(Connection
!= static_cast<SOCKET
>(OSL_SOCKET_ERROR
))
1065 *ppAddr
= createSocketAddFromSystem(&Addr
);
1071 /* user is not interested in peer-addr */
1072 Connection
= accept(pSocket
->m_Socket
, nullptr, nullptr);
1075 /* accept failed? */
1076 if(Connection
== static_cast<SOCKET
>(OSL_SOCKET_ERROR
))
1080 oslSocket pConnectionSocket
;
1081 pConnectionSocket
= createSocketImpl(Connection
);
1083 pConnectionSocket
->m_Flags
= 0;
1085 return pConnectionSocket
;
1088 sal_Int32 SAL_CALL
osl_receiveSocket (
1091 sal_uInt32 BytesToRead
,
1092 oslSocketMsgFlag Flag
)
1094 if (pSocket
== nullptr) /* ENOTSOCK */
1095 return osl_Socket_Error
;
1097 return recv(pSocket
->m_Socket
,
1098 static_cast<sal_Char
*>(pBuffer
),
1100 MSG_FLAG_TO_NATIVE(Flag
));
1103 sal_Int32 SAL_CALL
osl_receiveFromSocket (
1105 oslSocketAddr SenderAddr
,
1107 sal_uInt32 BufferSize
,
1108 oslSocketMsgFlag Flag
)
1110 struct sockaddr
*pSystemSockAddr
= nullptr;
1114 AddrLen
= sizeof( struct sockaddr
);
1115 pSystemSockAddr
= &(SenderAddr
->m_sockaddr
);
1118 if (pSocket
== nullptr) /* ENOTSOCK */
1119 return osl_Socket_Error
;
1121 return recvfrom(pSocket
->m_Socket
,
1122 static_cast<sal_Char
*>(pBuffer
),
1124 MSG_FLAG_TO_NATIVE(Flag
),
1129 sal_Int32 SAL_CALL
osl_sendSocket (
1131 const void* pBuffer
,
1132 sal_uInt32 BytesToSend
,
1133 oslSocketMsgFlag Flag
)
1135 if (pSocket
== nullptr) /* ENOTSOCK */
1136 return osl_Socket_Error
;
1138 return send(pSocket
->m_Socket
,
1139 static_cast<sal_Char
const *>(pBuffer
),
1141 MSG_FLAG_TO_NATIVE(Flag
));
1144 sal_Int32 SAL_CALL
osl_sendToSocket (
1146 oslSocketAddr ReceiverAddr
,
1147 const void* pBuffer
,
1148 sal_uInt32 BytesToSend
,
1149 oslSocketMsgFlag Flag
)
1151 if (pSocket
== nullptr) /* ENOTSOCK */
1152 return osl_Socket_Error
;
1154 /* ReceiverAddr might be 0 when used on a connected socket. */
1155 /* Then sendto should behave like send. */
1157 struct sockaddr
*pSystemSockAddr
= nullptr;
1159 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
1161 return sendto(pSocket
->m_Socket
,
1162 static_cast<sal_Char
const *>(pBuffer
),
1164 MSG_FLAG_TO_NATIVE(Flag
),
1166 pSystemSockAddr
== nullptr ? 0 : sizeof(struct sockaddr
));
1169 sal_Int32 SAL_CALL
osl_readSocket( oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
1171 sal_uInt8
* Ptr
= static_cast<sal_uInt8
*>(pBuffer
);
1173 OSL_ASSERT( pSocket
);
1175 /* loop until all desired bytes were read or an error occurred */
1176 sal_uInt32 BytesRead
= 0;
1177 sal_uInt32 BytesToRead
= n
;
1178 while (BytesToRead
> 0)
1181 RetVal
= osl_receiveSocket(pSocket
,
1184 osl_Socket_MsgNormal
);
1186 /* error occurred? */
1192 BytesToRead
-= RetVal
;
1193 BytesRead
+= RetVal
;
1200 sal_Int32 SAL_CALL
osl_writeSocket( oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
1202 OSL_ASSERT( pSocket
);
1204 /* loop until all desired bytes were send or an error occurred */
1205 sal_uInt32 BytesSend
= 0;
1206 sal_uInt32 BytesToSend
= n
;
1207 sal_uInt8
const *Ptr
= static_cast<sal_uInt8
const *>(pBuffer
);
1208 while (BytesToSend
> 0)
1212 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
1214 /* error occurred? */
1220 BytesToSend
-= RetVal
;
1221 BytesSend
+= RetVal
;
1228 sal_Bool SAL_CALL
osl_isReceiveReady (
1230 const TimeValue
* pTimeout
)
1235 if (pSocket
== nullptr) /* ENOTSOCK */
1239 FD_SET(pSocket
->m_Socket
, &fds
);
1243 tv
.tv_sec
= pTimeout
->Seconds
;
1244 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1247 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1248 &fds
, /* check read operations */
1249 nullptr, /* check write ops */
1250 nullptr, /* ckeck for OOB */
1251 pTimeout
? &tv
: nullptr)==1); /* use timeout? */
1254 /*****************************************************************************/
1255 /* osl_isSendReady */
1256 /*****************************************************************************/
1257 sal_Bool SAL_CALL
osl_isSendReady (
1259 const TimeValue
* pTimeout
)
1264 if (pSocket
== nullptr) /* ENOTSOCK */
1268 FD_SET(pSocket
->m_Socket
, &fds
);
1272 tv
.tv_sec
= pTimeout
->Seconds
;
1273 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1276 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1277 nullptr, /* check read operations */
1278 &fds
, /* check write ops */
1279 nullptr, /* ckeck for OOB */
1280 pTimeout
? &tv
: nullptr)==1); /* use timeout? */
1283 sal_Bool SAL_CALL
osl_isExceptionPending (
1285 const TimeValue
* pTimeout
)
1290 if (pSocket
== nullptr) /* ENOTSOCK */
1294 FD_SET(pSocket
->m_Socket
, &fds
);
1298 tv
.tv_sec
= pTimeout
->Seconds
;
1299 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1302 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1303 nullptr, /* check read operations */
1304 nullptr, /* check write ops */
1305 &fds
, /* ckeck for OOB */
1306 pTimeout
? &tv
: nullptr)==1); /* use timeout? */
1309 sal_Bool SAL_CALL
osl_shutdownSocket (
1311 oslSocketDirection Direction
)
1313 if (pSocket
== nullptr) /* ENOTSOCK */
1316 return (shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
))==0);
1319 sal_Int32 SAL_CALL
osl_getSocketOption (
1321 oslSocketOptionLevel Level
,
1322 oslSocketOption Option
,
1324 sal_uInt32 BufferLen
)
1326 if (pSocket
== nullptr) /* ENOTSOCK */
1327 return osl_Socket_Error
;
1329 int len
= BufferLen
;
1330 if (getsockopt(pSocket
->m_Socket
,
1331 OPTION_LEVEL_TO_NATIVE(Level
),
1332 OPTION_TO_NATIVE(Option
),
1333 static_cast<char *>(pBuffer
),
1342 sal_Bool SAL_CALL
osl_setSocketOption (
1344 oslSocketOptionLevel Level
,
1345 oslSocketOption Option
,
1347 sal_uInt32 BufferLen
)
1349 if (pSocket
== nullptr) /* ENOTSOCK */
1352 return(setsockopt(pSocket
->m_Socket
,
1353 OPTION_LEVEL_TO_NATIVE(Level
),
1354 OPTION_TO_NATIVE(Option
),
1355 static_cast<sal_Char
*>(pBuffer
),
1359 sal_Bool SAL_CALL
osl_enableNonBlockingMode ( oslSocket pSocket
, sal_Bool On
)
1361 unsigned long Param
= On
? 1 : 0;
1363 if (pSocket
== nullptr) /* ENOTSOCK */
1366 pSocket
->m_Flags
= Param
?
1367 (pSocket
->m_Flags
| OSL_SOCKET_FLAGS_NONBLOCKING
) :
1368 (pSocket
->m_Flags
& ~OSL_SOCKET_FLAGS_NONBLOCKING
) ;
1371 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
) != OSL_SOCKET_ERROR
);
1374 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
1376 if (pSocket
== nullptr) /* ENOTSOCK */
1379 return (pSocket
->m_Flags
& OSL_SOCKET_FLAGS_NONBLOCKING
) != 0;
1382 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
1385 int TypeSize
= sizeof(Type
);
1387 if (pSocket
== nullptr) /* ENOTSOCK */
1388 return osl_Socket_TypeInvalid
;
1390 if(getsockopt(pSocket
->m_Socket
,
1391 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
1392 OPTION_TO_NATIVE(osl_Socket_OptionType
),
1393 reinterpret_cast<char *>(&Type
),
1397 return osl_Socket_TypeInvalid
;
1400 return TYPE_FROM_NATIVE(Type
);
1403 void SAL_CALL
osl_getLastSocketErrorDescription (
1404 oslSocket
/*Socket*/,
1405 rtl_uString
**strError
)
1409 switch(error
= WSAGetLastError())
1412 rtl_uString_newFromAscii (strError
, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1415 case WSAEDESTADDRREQ
:
1416 rtl_uString_newFromAscii (strError
, "WSAEDESTADDRREQ, Destination Addr required");
1420 rtl_uString_newFromAscii (strError
, "WSAEMSGSIZE, Message too long");
1424 rtl_uString_newFromAscii (strError
, "WSAEPROTOTYPE, Protocol wrong type for socket");
1427 case WSAENOPROTOOPT
:
1428 rtl_uString_newFromAscii (strError
, "WSAENOPROTOOPT, Protocol not available");
1431 case WSAEPROTONOSUPPORT
:
1432 rtl_uString_newFromAscii (strError
, "WSAEPROTONOSUPPORT, Protocol not supported");
1435 case WSAESOCKTNOSUPPORT
:
1436 rtl_uString_newFromAscii (strError
, "WSAESOCKTNOSUPPORT, Socket type not supported");
1440 rtl_uString_newFromAscii (strError
, "WSAEOPNOTSUPP, Operation not supported on socket");
1443 case WSAEPFNOSUPPORT
:
1444 rtl_uString_newFromAscii (strError
, "WSAEPFNOSUPPORT, Protocol family not supported");
1447 case WSAEAFNOSUPPORT
:
1448 rtl_uString_newFromAscii (strError
, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1452 rtl_uString_newFromAscii (strError
, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1455 case WSAEADDRNOTAVAIL
:
1456 rtl_uString_newFromAscii (strError
, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1460 rtl_uString_newFromAscii (strError
, "WSAENETDOWN, Network is down");
1463 case WSAENETUNREACH
:
1464 rtl_uString_newFromAscii (strError
, "WSAENETUNREACH, Network is unreachable");
1468 rtl_uString_newFromAscii (strError
, "WSAENETRESET, Network dropped connection or reset");
1471 case WSAECONNABORTED
:
1472 rtl_uString_newFromAscii (strError
, "WSAECONNABORTED, Software caused connection abort");
1476 rtl_uString_newFromAscii (strError
, "WSAECONNRESET, Connection reset by peer");
1480 rtl_uString_newFromAscii (strError
, "WSAENOBUFS, No buffer space available.");
1484 rtl_uString_newFromAscii (strError
, "WSAEISCONN, Socket is already connected");
1488 rtl_uString_newFromAscii (strError
, "WSAENOTCONN, Socket is not connected");
1492 rtl_uString_newFromAscii (strError
, "WSAESHUTDOWN, Can't send after socket shutdown");
1496 rtl_uString_newFromAscii (strError
, "WSAETIMEDOUT, Connection timed out");
1499 case WSAECONNREFUSED
:
1500 rtl_uString_newFromAscii (strError
, "WSAECONNREFUSED, Connection refused");
1504 rtl_uString_newFromAscii (strError
, "WSAEHOSTDOWN, Networking subsystem not started");
1507 case WSAEHOSTUNREACH
:
1508 rtl_uString_newFromAscii (strError
, "WSAEHOSTUNREACH, No route to host");
1511 case WSAEWOULDBLOCK
:
1512 rtl_uString_newFromAscii (strError
, "WSAEWOULDBLOCK, Operation would block");
1515 case WSAEINPROGRESS
:
1516 rtl_uString_newFromAscii (strError
, "WSAEINPROGRESS, Operation now in progress");
1520 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation already in progress");
1524 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation was interrupted");
1528 rtl_uString_newFromAscii (strError
, "WSAEBADF, Bad file number");
1532 rtl_uString_newFromAscii (strError
, "WSAEACCES, Access is denied");
1536 rtl_uString_newFromAscii (strError
, "WSAEFAULT, Bad memory Addr");
1540 rtl_uString_newFromAscii (strError
, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1544 rtl_uString_newFromAscii (strError
, "WSAEMFILE, No more file descriptors are available");
1547 case WSAETOOMANYREFS
:
1548 rtl_uString_newFromAscii (strError
, "WSAETOOMANYREFS, Undocumented WinSock error");
1551 case WSAENAMETOOLONG
:
1552 rtl_uString_newFromAscii (strError
, "WSAENAMETOOLONG, Undocumented WinSock error");
1556 rtl_uString_newFromAscii (strError
, "WSAENOTEMPTY, Undocumented WinSock error");
1560 rtl_uString_newFromAscii (strError
, "WSAEPROCLIM, Undocumented WinSock error");
1564 rtl_uString_newFromAscii (strError
, "WSAEUSERS, Undocumented WinSock error");
1568 rtl_uString_newFromAscii (strError
, "WSAEDQUOT, Undocumented WinSock error");
1572 rtl_uString_newFromAscii (strError
, "WSAESTALE, Undocumented WinSock error");
1576 rtl_uString_newFromAscii (strError
, "WSAEREMOTE, Undocumented WinSock error");
1580 rtl_uString_newFromAscii (strError
, "WSAEDISCON, Circuit was gracefully terminated");
1583 case WSASYSNOTREADY
:
1584 rtl_uString_newFromAscii (strError
, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
1587 case WSAVERNOTSUPPORTED
:
1588 rtl_uString_newFromAscii (strError
, "WSAVERNOTSUPPORTED, The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation");
1591 case WSANOTINITIALISED
:
1592 rtl_uString_newFromAscii (strError
, "WSANOTINITIALISED, WSAStartup() has not been called");
1595 case WSAHOST_NOT_FOUND
:
1596 rtl_uString_newFromAscii (strError
, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
1600 rtl_uString_newFromAscii (strError
, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
1603 case WSANO_RECOVERY
:
1604 rtl_uString_newFromAscii (strError
, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1608 rtl_uString_newFromAscii (strError
, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
1613 sal_Unicode message
[128];
1615 wsprintfW(o3tl::toW(message
), L
"Unknown WinSock Error Number %d", error
);
1616 rtl_uString_newFromStr (strError
, message
);
1624 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket
/*Socket*/)
1626 return ERROR_FROM_NATIVE(WSAGetLastError());
1629 struct oslSocketSetImpl
1631 fd_set m_Set
; /* the set of descriptors */
1635 oslSocketSet SAL_CALL
osl_createSocketSet()
1637 oslSocketSetImpl
* pSet
;
1639 pSet
= static_cast<oslSocketSetImpl
*>(malloc(sizeof(oslSocketSetImpl
)));
1643 FD_ZERO(&pSet
->m_Set
);
1649 void SAL_CALL
osl_destroySocketSet (oslSocketSet Set
)
1655 void SAL_CALL
osl_clearSocketSet (oslSocketSet Set
)
1658 FD_ZERO(&Set
->m_Set
);
1661 void SAL_CALL
osl_addToSocketSet (
1666 FD_SET(Socket
->m_Socket
, &Set
->m_Set
);
1669 void SAL_CALL
osl_removeFromSocketSet (
1674 FD_CLR(Socket
->m_Socket
, &Set
->m_Set
);
1677 sal_Bool SAL_CALL
osl_isInSocketSet (
1682 return (FD_ISSET(Socket
->m_Socket
, &Set
->m_Set
) != 0);
1687 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents (
1688 oslSocketSet IncomingSet
,
1689 oslSocketSet OutgoingSet
,
1690 oslSocketSet OutOfBandSet
,
1691 const TimeValue
* pTimeout
)
1697 /* divide milliseconds into seconds and microseconds */
1698 tv
.tv_sec
= pTimeout
->Seconds
;
1699 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1702 return select(0, /* redundant in WIN32 */
1703 IncomingSet
? &IncomingSet
->m_Set
: nullptr,
1704 OutgoingSet
? &OutgoingSet
->m_Set
: nullptr,
1705 OutOfBandSet
? &OutOfBandSet
->m_Set
: nullptr,
1706 pTimeout
? &tv
: nullptr);
1709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */