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 .
22 #include <osl/socket.h>
23 #include <osl/diagnose.h>
24 #include <rtl/alloc.h>
25 #include <rtl/byteseq.h>
26 #include <sal/log.hxx>
27 #include <o3tl/char16_t2wchar_t.hxx>
28 #include <comphelper/windowserrorstring.hxx>
30 #include "sockimpl.hxx"
33 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
34 I refrained from using sockaddr_in because of possible further
35 extensions of this socket-interface (IP-NG?).
36 The intention was to hide all Berkeley data-structures from
37 direct access past the osl-interface.
39 The current implementation is internet (IP) centered. All
40 the constructor-functions (osl_create...) take parameters
41 that will probably make sense only in the IP-environment
42 (e.g. because of using the dotted-Addr-format).
44 If the interface will be extended to host other protocol-
45 families, I expect no externally visible changes in the
46 existing functions. You'll probably need only new
47 constructor-functions who take the different Addr
48 formats into consideration (maybe a long dotted Addr
53 _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr
54 are the same! I don't like it very much but see no other easy way to
55 conceal the struct sockaddr from the eyes of the user.
58 #define OSL_INVALID_SOCKET INVALID_SOCKET /* WIN32 */
59 #define OSL_SOCKET_ERROR SOCKET_ERROR /* WIN32 */
61 static DWORD FamilyMap
[]= {
62 AF_INET
, /* osl_Socket_FamilyInet */
63 AF_IPX
, /* osl_Socket_FamilyIpx */
64 0 /* osl_Socket_FamilyInvalid */
67 static oslAddrFamily
osl_AddrFamilyFromNative(DWORD nativeType
)
69 oslAddrFamily i
= oslAddrFamily(0);
70 while(i
!= osl_Socket_FamilyInvalid
)
72 if(FamilyMap
[i
] == nativeType
)
74 i
= static_cast<oslAddrFamily
>( static_cast<int>(i
) + 1);
79 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
80 #define FAMILY_TO_NATIVE(x) static_cast<short>(FamilyMap[x])
82 static DWORD ProtocolMap
[]= {
83 0, /* osl_Socket_FamilyInet */
84 NSPROTO_IPX
, /* osl_Socket_FamilyIpx */
85 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
86 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpx_ii */
87 0 /* osl_Socket_ProtocolInvalid */
90 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
92 static DWORD TypeMap
[]= {
93 SOCK_STREAM
, /* osl_Socket_TypeStream */
94 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
95 SOCK_RAW
, /* osl_Socket_TypeRaw */
96 SOCK_RDM
, /* osl_Socket_TypeRdm */
97 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
98 0 /* osl_Socket_TypeInvalid */
101 static oslSocketType
osl_SocketTypeFromNative(DWORD nativeType
)
103 oslSocketType i
= oslSocketType(0);
104 while(i
!= osl_Socket_TypeInvalid
)
106 if(TypeMap
[i
] == nativeType
)
108 i
= static_cast<oslSocketType
>(static_cast<int>(i
)+1);
113 #define TYPE_TO_NATIVE(x) TypeMap[x]
114 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
116 static DWORD OptionMap
[]= {
117 SO_DEBUG
, /* osl_Socket_OptionDebug */
118 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
119 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
120 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
121 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
122 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
123 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
124 SO_LINGER
, /* osl_Socket_OptionLinger */
125 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
126 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
127 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
128 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
129 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
130 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
131 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
132 SO_ERROR
, /* osl_Socket_OptionError */
133 SO_TYPE
, /* osl_Socket_OptionType */
134 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
135 0 /* osl_Socket_OptionInvalid */
138 #define OPTION_TO_NATIVE(x) OptionMap[x]
140 static DWORD OptionLevelMap
[]= {
141 SOL_SOCKET
, /* osl_Socket_LevelSocket */
142 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
143 0 /* osl_invalid_SocketLevel */
146 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
148 static DWORD SocketMsgFlagMap
[]= {
149 0, /* osl_Socket_MsgNormal */
150 MSG_OOB
, /* osl_Socket_MsgOOB */
151 MSG_PEEK
, /* osl_Socket_MsgPeek */
152 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
153 MSG_MAXIOVLEN
/* osl_Socket_MsgMaxIOVLen */
156 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
158 static DWORD SocketDirection
[]= {
159 SD_RECEIVE
, /* osl_Socket_DirRead */
160 SD_SEND
, /* osl_Socket_DirWrite */
161 SD_BOTH
/* osl_Socket_DirReadwrite */
164 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
166 static int SocketError
[]= {
168 WSAENOTSOCK
, /* Socket operation on non-socket */
169 WSAEDESTADDRREQ
, /* Destination address required */
170 WSAEMSGSIZE
, /* Message too long */
171 WSAEPROTOTYPE
, /* Protocol wrong type for socket */
172 WSAENOPROTOOPT
, /* Protocol not available */
173 WSAEPROTONOSUPPORT
, /* Protocol not supported */
174 WSAESOCKTNOSUPPORT
, /* Socket type not supported */
175 WSAEOPNOTSUPP
, /* Operation not supported on socket */
176 WSAEPFNOSUPPORT
, /* Protocol family not supported */
177 WSAEAFNOSUPPORT
, /* Address family not supported by protocol family */
178 WSAEADDRINUSE
, /* Address already in use */
179 WSAEADDRNOTAVAIL
, /* Can't assign requested address */
180 WSAENETDOWN
, /* Network is down */
181 WSAENETUNREACH
, /* Network is unreachable */
182 WSAENETRESET
, /* Network dropped connection because of reset */
183 WSAECONNABORTED
, /* Software caused connection abort */
184 WSAECONNRESET
, /* Connection reset by peer */
185 WSAENOBUFS
, /* No buffer space available */
186 WSAEISCONN
, /* Socket is already connected */
187 WSAENOTCONN
, /* Socket is not connected */
188 WSAESHUTDOWN
, /* Can't send after socket shutdown */
189 WSAETOOMANYREFS
, /* Too many references: can't splice */
190 WSAETIMEDOUT
, /* Connection timed out */
191 WSAECONNREFUSED
, /* Connection refused */
192 WSAEHOSTDOWN
, /* Host is down */
193 WSAEHOSTUNREACH
, /* No route to host */
194 WSAEWOULDBLOCK
, /* call would block on non-blocking socket */
195 WSAEALREADY
, /* operation already in progress */
196 WSAEINPROGRESS
/* operation now in progress */
199 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
201 oslSocketError i
= oslSocketError(0);
203 while(i
!= osl_Socket_E_InvalidError
)
205 if(SocketError
[i
] == nativeType
)
208 i
= static_cast<oslSocketError
>( static_cast<int>(i
) + 1);
213 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
215 #if OSL_DEBUG_LEVEL > 0
216 static sal_uInt32 g_nSocketAddr
= 0;
221 SAL_WARN_IF( g_nSocketAddr
, "sal.osl", "sal_socket: " << g_nSocketAddr
<< " socket address instances leak" );
224 static LeakWarning socketWarning
;
227 static oslSocket
createSocketImpl(SOCKET Socket
)
229 oslSocket pSockImpl
= static_cast<oslSocket
>(rtl_allocateZeroMemory( sizeof(struct oslSocketImpl
)));
230 pSockImpl
->m_Socket
= Socket
;
231 pSockImpl
->m_nRefCount
= 1;
235 static void destroySocketImpl(oslSocketImpl
*pImpl
)
243 static oslSocketAddr
createSocketAddr( )
245 oslSocketAddr pAddr
= static_cast<oslSocketAddr
>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
)));
246 pAddr
->m_nRefCount
= 1;
247 #if OSL_DEBUG_LEVEL > 0
253 static oslSocketAddr
createSocketAddrWithFamily(
254 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
256 OSL_ASSERT( family
== osl_Socket_FamilyInet
);
258 oslSocketAddr pAddr
= createSocketAddr();
261 case osl_Socket_FamilyInet
:
263 struct sockaddr_in
* pInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
265 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
266 pInetAddr
->sin_addr
.s_addr
= nAddr
;
267 pInetAddr
->sin_port
= static_cast<sal_uInt16
>(port
&0xffff);
271 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
276 static oslSocketAddr
createSocketAddFromSystem( struct sockaddr
*pSystemSockAddr
)
278 oslSocketAddr pAddr
= createSocketAddr();
279 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( sockaddr
) );
283 static void destroySocketAddr( oslSocketAddr addr
)
285 #if OSL_DEBUG_LEVEL > 0
291 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
293 oslSocketAddr pAddr
= nullptr;
295 /* is it an internet-Addr? */
296 if (Family
== osl_Socket_FamilyInet
)
297 pAddr
= createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
299 pAddr
= createSocketAddrWithFamily( Family
, 0 , 0 );
304 /** @deprecated, to be removed */
305 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
307 oslSocketAddr pCopy
= nullptr;
310 pCopy
= createSocketAddr();
313 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
318 sal_Bool SAL_CALL
osl_isEqualSocketAddr(oslSocketAddr Addr1
, oslSocketAddr Addr2
)
322 struct sockaddr
* pAddr1
= &(Addr1
->m_sockaddr
);
323 struct sockaddr
* pAddr2
= &(Addr2
->m_sockaddr
);
328 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
330 switch (pAddr1
->sa_family
)
334 struct sockaddr_in
* pInetAddr1
= reinterpret_cast<struct sockaddr_in
*>(pAddr1
);
335 struct sockaddr_in
* pInetAddr2
= reinterpret_cast<struct sockaddr_in
*>(pAddr2
);
337 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
338 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
339 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
346 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
354 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
355 rtl_uString
*strDottedAddr
,
358 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
360 if (strDottedAddr
&& strDottedAddr
->length
)
363 INT ret
= InetPtonW(AF_INET
, o3tl::toW(strDottedAddr
->buffer
), & addr
);
366 nAddr
= addr
.S_un
.S_addr
;
370 if (nAddr
!= OSL_INADDR_NONE
)
372 /* Limited broadcast */
373 nAddr
= ntohl(nAddr
);
374 if (IN_CLASSA(nAddr
))
376 nAddr
&= IN_CLASSA_NET
;
377 nAddr
|= IN_CLASSA_HOST
;
379 else if (IN_CLASSB(nAddr
))
381 nAddr
&= IN_CLASSB_NET
;
382 nAddr
|= IN_CLASSB_HOST
;
384 else if (IN_CLASSC(nAddr
))
386 nAddr
&= IN_CLASSC_NET
;
387 nAddr
|= IN_CLASSC_HOST
;
391 /* No broadcast in class D */
394 nAddr
= htonl(nAddr
);
397 oslSocketAddr pAddr
=
398 createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons( static_cast<sal_uInt16
>(Port
)), nAddr
);
402 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
403 rtl_uString
*strDottedAddr
,
409 INT ret
= InetPtonW(AF_INET
, o3tl::toW(strDottedAddr
->buffer
), & addr
);
410 Addr
= ret
== 1 ? addr
.S_un
.S_addr
: OSL_INADDR_NONE
;
412 oslSocketAddr pAddr
= nullptr;
413 if(Addr
!= OSL_INADDR_NONE
)
415 pAddr
= createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons( static_cast<sal_uInt16
>(Port
)), Addr
);
420 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
423 OSL_ASSERT( pByteSeq
);
425 oslSocketResult res
= osl_Socket_Error
;
426 if( pAddr
&& pByteSeq
)
428 OSL_ASSERT( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
429 OSL_ASSERT( pByteSeq
->nElements
== 4 );
430 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
431 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
437 /** Returns the addr field in the struct sockaddr. ppByteSeq is in network byteorder. *ppByteSeq may
438 either be 0 or contain a constructed sal_Sequence.
440 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
443 OSL_ASSERT( ppByteSeq
);
445 oslSocketResult res
= osl_Socket_Error
;
446 if( pAddr
&& ppByteSeq
)
448 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
449 rtl_byte_sequence_constructFromArray( ppByteSeq
, reinterpret_cast<sal_Int8
*>(&pSystemInetAddr
->sin_addr
),4);
455 struct oslHostAddrImpl
{
456 rtl_uString
*pHostName
;
457 oslSocketAddr pSockAddr
;
460 oslHostAddr SAL_CALL
osl_createHostAddr (
461 rtl_uString
*strHostname
,
462 const oslSocketAddr pSocketAddr
)
465 rtl_uString
*cn
= nullptr;
467 if ((strHostname
== nullptr) || (strHostname
->length
== 0) || (pSocketAddr
== nullptr))
470 rtl_uString_newFromString( &cn
, strHostname
);
472 pAddr
= static_cast<oslHostAddr
>(malloc (sizeof (struct oslHostAddrImpl
)));
474 if (pAddr
== nullptr)
476 rtl_uString_release(cn
);
480 pAddr
->pHostName
= cn
;
481 pAddr
->pSockAddr
= osl_copySocketAddr( pSocketAddr
);
486 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*strHostname
)
488 if ((strHostname
== nullptr) || (strHostname
->length
== 0))
491 PADDRINFOW pAddrInfo
= nullptr;
492 int ret
= GetAddrInfoW(
493 o3tl::toW(strHostname
->buffer
), nullptr, nullptr, & pAddrInfo
);
496 oslHostAddr pRet
= nullptr;
497 for (PADDRINFOW pIter
= pAddrInfo
; pIter
; pIter
= pIter
->ai_next
)
499 if (AF_INET
== pIter
->ai_family
)
501 pRet
= static_cast<oslHostAddr
>(
502 rtl_allocateZeroMemory(sizeof(struct oslHostAddrImpl
)));
503 rtl_uString_newFromStr(&pRet
->pHostName
, o3tl::toU(pIter
->ai_canonname
));
504 pRet
->pSockAddr
= createSocketAddr();
505 memcpy(& pRet
->pSockAddr
->m_sockaddr
,
506 pIter
->ai_addr
, pIter
->ai_addrlen
);
507 break; // ignore other results
510 FreeAddrInfoW(pAddrInfo
);
515 SAL_INFO("sal.osl", "GetAddrInfoW failed: " << WSAGetLastError());
520 oslHostAddr SAL_CALL
osl_createHostAddrByAddr(const oslSocketAddr pAddr
)
522 if (pAddr
== nullptr)
525 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
527 const struct sockaddr_in
*sin
= reinterpret_cast<const struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
529 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
532 WCHAR buf
[NI_MAXHOST
];
533 int ret
= GetNameInfoW(
534 & pAddr
->m_sockaddr
, sizeof(struct sockaddr
),
539 oslHostAddr pRet
= static_cast<oslHostAddr
>(
540 rtl_allocateZeroMemory(sizeof(struct oslHostAddrImpl
)));
541 rtl_uString_newFromStr(&pRet
->pHostName
, o3tl::toU(buf
));
542 pRet
->pSockAddr
= createSocketAddr();
543 memcpy(& pRet
->pSockAddr
->m_sockaddr
,
544 & pAddr
->m_sockaddr
, sizeof(struct sockaddr
));
549 SAL_INFO("sal.osl", "GetNameInfoW failed: " << WSAGetLastError());
556 oslHostAddr SAL_CALL
osl_copyHostAddr(const oslHostAddr Addr
)
558 oslHostAddr pAddr
= Addr
;
561 return osl_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
566 void SAL_CALL
osl_getHostnameOfHostAddr(
567 const oslHostAddr pAddr
, rtl_uString
**strHostname
)
570 rtl_uString_assign (strHostname
, pAddr
->pHostName
);
572 rtl_uString_new (strHostname
);
575 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr
)
578 return pAddr
->pSockAddr
;
583 void SAL_CALL
osl_destroyHostAddr(oslHostAddr pAddr
)
587 if (pAddr
->pHostName
)
588 rtl_uString_release (pAddr
->pHostName
);
589 if (pAddr
->pSockAddr
)
590 osl_destroySocketAddr( pAddr
->pSockAddr
);
596 oslSocketResult SAL_CALL
osl_getLocalHostname (rtl_uString
**strLocalHostname
)
598 static sal_Unicode LocalHostname
[256] = {0};
600 if (rtl_ustr_getLength(LocalHostname
) == 0)
602 sal_Char Host
[256]= "";
603 if (gethostname(Host
, sizeof(Host
)) == 0)
605 /* check if we have an FQDN */
606 if (strchr(Host
, '.') == nullptr)
609 rtl_uString
*hostName
= nullptr;
612 &hostName
, Host
, strlen(Host
),
613 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
614 OSL_ASSERT(hostName
!= nullptr);
616 /* no, determine it via dns */
617 pAddr
= osl_createHostAddrByName(hostName
);
618 rtl_uString_release (hostName
);
620 if (pAddr
&& pAddr
->pHostName
)
621 memcpy(LocalHostname
, pAddr
->pHostName
->buffer
, sizeof(sal_Unicode
)*(rtl_ustr_getLength(pAddr
->pHostName
->buffer
)+1));
623 memset(LocalHostname
, 0, sizeof(LocalHostname
));
625 osl_destroyHostAddr (pAddr
);
630 if (rtl_ustr_getLength(LocalHostname
) > 0)
632 rtl_uString_newFromStr (strLocalHostname
, LocalHostname
);
633 return osl_Socket_Ok
;
636 return osl_Socket_Error
;
639 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
* strHostname
)
641 oslHostAddr pAddr
= osl_createHostAddrByName (strHostname
);
644 oslSocketAddr SockAddr
= osl_copySocketAddr( pAddr
->pSockAddr
);
645 osl_destroyHostAddr(pAddr
);
651 sal_Int32 SAL_CALL
osl_getServicePort (
652 rtl_uString
* strServicename
,
653 rtl_uString
* strProtocol
)
657 rtl_String
*str_Servicename
=nullptr;
658 rtl_String
*str_Protocol
=nullptr;
662 rtl_uString_getStr(strServicename
),
663 rtl_uString_getLength(strServicename
),
664 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
667 rtl_uString_getStr(strProtocol
),
668 rtl_uString_getLength(strProtocol
),
669 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
672 rtl_string_getStr(str_Servicename
),
673 rtl_string_getStr(str_Protocol
));
675 rtl_string_release( str_Servicename
);
676 rtl_string_release( str_Protocol
);
679 return ntohs(ps
->s_port
);
681 return OSL_INVALID_PORT
;
684 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
686 destroySocketAddr( pAddr
);
689 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
692 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
694 return osl_Socket_FamilyInvalid
;
697 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
701 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
703 if (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
704 return ntohs(pSystemInetAddr
->sin_port
);
706 return OSL_INVALID_PORT
;
709 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr (
713 if (pAddr
== nullptr)
716 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
718 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
721 pSystemInetAddr
->sin_port
= htons(static_cast<short>(Port
));
725 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr (
727 rtl_uString
**strHostName
)
729 oslHostAddr pAddr
= osl_createHostAddrByAddr (Addr
);
733 rtl_uString_newFromString(strHostName
, pAddr
->pHostName
);
735 osl_destroyHostAddr(pAddr
);
737 return osl_Socket_Ok
;
740 return osl_Socket_Error
;
743 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr (
745 rtl_uString
**strDottedInetAddr
)
747 if (pAddr
== nullptr)
748 return osl_Socket_Error
;
750 struct sockaddr_in
*pSystemInetAddr
= reinterpret_cast<struct sockaddr_in
*>(&pAddr
->m_sockaddr
);
751 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
752 return osl_Socket_Error
;
754 *strDottedInetAddr
= nullptr;
755 WCHAR buf
[16]; // 16 for IPV4, 46 for IPV6
756 PCWSTR ret
= InetNtopW(
757 AF_INET
, & pSystemInetAddr
->sin_addr
,
758 buf
, SAL_N_ELEMENTS(buf
));
761 SAL_INFO("sal.osl", "InetNtopW failed: " << WSAGetLastError());
762 return osl_Socket_Error
;
764 rtl_uString_newFromStr(strDottedInetAddr
, o3tl::toU(ret
));
765 OSL_ASSERT(*strDottedInetAddr
!= nullptr);
767 return osl_Socket_Ok
;
770 oslSocket SAL_CALL
osl_createSocket(
771 oslAddrFamily Family
,
773 oslProtocol Protocol
)
776 oslSocket pSocket
= createSocketImpl(0);
778 if (pSocket
== nullptr)
782 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
783 TYPE_TO_NATIVE(Type
),
784 PROTOCOL_TO_NATIVE(Protocol
));
786 /* creation failed => free memory */
787 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
789 int nErrno
= WSAGetLastError();
790 SAL_WARN("sal.osl", "socket creation failed: (" << nErrno
<< "): " << WindowsErrorString(nErrno
));
792 destroySocketImpl(pSocket
);
797 pSocket
->m_Flags
= 0;
803 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
805 osl_atomic_increment(&(pSocket
->m_nRefCount
));
808 void SAL_CALL
osl_releaseSocket(oslSocket pSocket
)
810 if (pSocket
&& osl_atomic_decrement(&(pSocket
->m_nRefCount
)) == 0)
812 osl_closeSocket(pSocket
);
813 destroySocketImpl(pSocket
);
817 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
819 /* socket already invalid */
824 closesocket(pSocket
->m_Socket
);
826 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
830 Note that I rely on the fact that oslSocketAddr and struct sockaddr
831 are the same! I don't like it very much but see no other easy way
832 to conceal the struct sockaddr from the eyes of the user.
834 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
836 struct sockaddr Addr
;
839 if (pSocket
== nullptr) /* ENOTSOCK */
842 AddrLen
= sizeof(struct sockaddr
);
844 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
847 oslSocketAddr pAddr
= createSocketAddFromSystem( &Addr
);
851 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
853 struct sockaddr Addr
;
856 if (pSocket
== nullptr) /* ENOTSOCK */
859 AddrLen
= sizeof(struct sockaddr
);
861 if (getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
864 oslSocketAddr pAddr
= createSocketAddFromSystem( &Addr
);
868 sal_Bool SAL_CALL
osl_bindAddrToSocket ( oslSocket pSocket
, oslSocketAddr pAddr
)
872 if (pSocket
== nullptr) /* ENOTSOCK */
875 return (bind(pSocket
->m_Socket
,
876 &(pAddr
->m_sockaddr
),
877 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
);
880 oslSocketResult SAL_CALL
osl_connectSocketTo (
883 const TimeValue
* pTimeout
)
886 if (pSocket
== nullptr) /* ENOTSOCK */
887 return osl_Socket_Error
;
889 if (pAddr
== nullptr) /* EDESTADDRREQ */
890 return osl_Socket_Error
;
892 if (pTimeout
== nullptr)
894 if(connect(pSocket
->m_Socket
,
895 &(pAddr
->m_sockaddr
),
896 sizeof(struct sockaddr
)) == OSL_SOCKET_ERROR
)
897 return osl_Socket_Error
;
899 return osl_Socket_Ok
;
907 oslSocketResult Result
= osl_Socket_Ok
;
909 if (pSocket
->m_Flags
& OSL_SOCKET_FLAGS_NONBLOCKING
)
911 if (connect(pSocket
->m_Socket
,
912 &(pAddr
->m_sockaddr
),
913 sizeof(struct sockaddr
)) == OSL_SOCKET_ERROR
)
915 switch (WSAGetLastError())
919 return osl_Socket_InProgress
;
922 return osl_Socket_Error
;
926 return osl_Socket_Ok
;
929 /* set socket temporarily to non-blocking */
931 OSL_VERIFY(ioctlsocket(
932 pSocket
->m_Socket
, FIONBIO
, &Param
) != OSL_SOCKET_ERROR
);
934 /* initiate connect */
935 if (connect(pSocket
->m_Socket
,
936 &(pAddr
->m_sockaddr
),
937 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
939 /* immediate connection */
942 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
944 return osl_Socket_Ok
;
948 error
= WSAGetLastError();
950 /* really an error or just delayed? */
951 if (error
!= WSAEWOULDBLOCK
&& error
!= WSAEINPROGRESS
)
954 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
956 return osl_Socket_Error
;
960 /* prepare select set for socket */
962 FD_SET(pSocket
->m_Socket
, &fds
);
964 /* divide milliseconds into seconds and microseconds */
965 tv
.tv_sec
= pTimeout
->Seconds
;
966 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
969 error
= select(pSocket
->m_Socket
+1,
975 if (error
> 0) /* connected */
978 !FD_ISSET(pSocket
->m_Socket
, &fds
),
980 "osl_connectSocketTo(): select returned but socket not set");
982 Result
= osl_Socket_Ok
;
985 else if(error
< 0) /* error */
987 /* errno == EBADF: most probably interrupted by close() */
988 if(WSAGetLastError() == WSAEBADF
)
990 /* do not access pSockImpl because it is about to be or */
991 /* already destroyed */
992 return osl_Socket_Interrupted
;
995 Result
= osl_Socket_Error
;
999 Result
= osl_Socket_TimedOut
;
1003 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
);
1009 sal_Bool SAL_CALL
osl_listenOnSocket (
1011 sal_Int32 MaxPendingConnections
)
1013 if (pSocket
== nullptr) /* ENOTSOCK */
1016 return (listen(pSocket
->m_Socket
,
1017 MaxPendingConnections
== -1 ?
1019 MaxPendingConnections
) != OSL_SOCKET_ERROR
);
1022 oslSocket SAL_CALL
osl_acceptConnectionOnSocket (
1024 oslSocketAddr
* ppAddr
)
1026 if (pSocket
== nullptr) /* ENOTSOCK */
1034 osl_destroySocketAddr( *ppAddr
);
1037 int AddrLen
= sizeof(struct sockaddr
);
1039 /* user wants to know peer Addr */
1040 struct sockaddr Addr
;
1042 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
1043 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
1045 if(Connection
!= static_cast<SOCKET
>(OSL_SOCKET_ERROR
))
1046 *ppAddr
= createSocketAddFromSystem(&Addr
);
1052 /* user is not interested in peer-addr */
1053 Connection
= accept(pSocket
->m_Socket
, nullptr, nullptr);
1056 /* accept failed? */
1057 if(Connection
== static_cast<SOCKET
>(OSL_SOCKET_ERROR
))
1061 oslSocket pConnectionSocket
;
1062 pConnectionSocket
= createSocketImpl(Connection
);
1064 pConnectionSocket
->m_Flags
= 0;
1066 return pConnectionSocket
;
1069 sal_Int32 SAL_CALL
osl_receiveSocket (
1072 sal_uInt32 BytesToRead
,
1073 oslSocketMsgFlag Flag
)
1075 if (pSocket
== nullptr) /* ENOTSOCK */
1076 return osl_Socket_Error
;
1078 return recv(pSocket
->m_Socket
,
1079 static_cast<sal_Char
*>(pBuffer
),
1081 MSG_FLAG_TO_NATIVE(Flag
));
1084 sal_Int32 SAL_CALL
osl_receiveFromSocket (
1086 oslSocketAddr SenderAddr
,
1088 sal_uInt32 BufferSize
,
1089 oslSocketMsgFlag Flag
)
1091 struct sockaddr
*pSystemSockAddr
= nullptr;
1095 AddrLen
= sizeof( struct sockaddr
);
1096 pSystemSockAddr
= &(SenderAddr
->m_sockaddr
);
1099 if (pSocket
== nullptr) /* ENOTSOCK */
1100 return osl_Socket_Error
;
1102 return recvfrom(pSocket
->m_Socket
,
1103 static_cast<sal_Char
*>(pBuffer
),
1105 MSG_FLAG_TO_NATIVE(Flag
),
1110 sal_Int32 SAL_CALL
osl_sendSocket (
1112 const void* pBuffer
,
1113 sal_uInt32 BytesToSend
,
1114 oslSocketMsgFlag Flag
)
1116 if (pSocket
== nullptr) /* ENOTSOCK */
1117 return osl_Socket_Error
;
1119 return send(pSocket
->m_Socket
,
1120 static_cast<sal_Char
const *>(pBuffer
),
1122 MSG_FLAG_TO_NATIVE(Flag
));
1125 sal_Int32 SAL_CALL
osl_sendToSocket (
1127 oslSocketAddr ReceiverAddr
,
1128 const void* pBuffer
,
1129 sal_uInt32 BytesToSend
,
1130 oslSocketMsgFlag Flag
)
1132 if (pSocket
== nullptr) /* ENOTSOCK */
1133 return osl_Socket_Error
;
1135 /* ReceiverAddr might be 0 when used on a connected socket. */
1136 /* Then sendto should behave like send. */
1138 struct sockaddr
*pSystemSockAddr
= nullptr;
1140 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
1142 return sendto(pSocket
->m_Socket
,
1143 static_cast<sal_Char
const *>(pBuffer
),
1145 MSG_FLAG_TO_NATIVE(Flag
),
1147 pSystemSockAddr
== nullptr ? 0 : sizeof(struct sockaddr
));
1150 sal_Int32 SAL_CALL
osl_readSocket( oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
1152 sal_uInt8
* Ptr
= static_cast<sal_uInt8
*>(pBuffer
);
1154 OSL_ASSERT( pSocket
);
1156 /* loop until all desired bytes were read or an error occurred */
1157 sal_uInt32 BytesRead
= 0;
1158 sal_uInt32 BytesToRead
= n
;
1159 while (BytesToRead
> 0)
1162 RetVal
= osl_receiveSocket(pSocket
,
1165 osl_Socket_MsgNormal
);
1167 /* error occurred? */
1173 BytesToRead
-= RetVal
;
1174 BytesRead
+= RetVal
;
1181 sal_Int32 SAL_CALL
osl_writeSocket( oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
1183 OSL_ASSERT( pSocket
);
1185 /* loop until all desired bytes were send or an error occurred */
1186 sal_uInt32 BytesSend
= 0;
1187 sal_uInt32 BytesToSend
= n
;
1188 sal_uInt8
const *Ptr
= static_cast<sal_uInt8
const *>(pBuffer
);
1189 while (BytesToSend
> 0)
1193 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
1195 /* error occurred? */
1201 BytesToSend
-= RetVal
;
1202 BytesSend
+= RetVal
;
1209 sal_Bool SAL_CALL
osl_isReceiveReady (
1211 const TimeValue
* pTimeout
)
1216 if (pSocket
== nullptr) /* ENOTSOCK */
1220 FD_SET(pSocket
->m_Socket
, &fds
);
1224 tv
.tv_sec
= pTimeout
->Seconds
;
1225 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1228 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1229 &fds
, /* check read operations */
1230 nullptr, /* check write ops */
1231 nullptr, /* ckeck for OOB */
1232 pTimeout
? &tv
: nullptr)==1); /* use timeout? */
1235 /*****************************************************************************/
1236 /* osl_isSendReady */
1237 /*****************************************************************************/
1238 sal_Bool SAL_CALL
osl_isSendReady (
1240 const TimeValue
* pTimeout
)
1245 if (pSocket
== nullptr) /* ENOTSOCK */
1249 FD_SET(pSocket
->m_Socket
, &fds
);
1253 tv
.tv_sec
= pTimeout
->Seconds
;
1254 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1257 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1258 nullptr, /* check read operations */
1259 &fds
, /* check write ops */
1260 nullptr, /* ckeck for OOB */
1261 pTimeout
? &tv
: nullptr)==1); /* use timeout? */
1264 sal_Bool SAL_CALL
osl_isExceptionPending (
1266 const TimeValue
* pTimeout
)
1271 if (pSocket
== nullptr) /* ENOTSOCK */
1275 FD_SET(pSocket
->m_Socket
, &fds
);
1279 tv
.tv_sec
= pTimeout
->Seconds
;
1280 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1283 return (select(pSocket
->m_Socket
+ 1, /* no of sockets to monitor */
1284 nullptr, /* check read operations */
1285 nullptr, /* check write ops */
1286 &fds
, /* ckeck for OOB */
1287 pTimeout
? &tv
: nullptr)==1); /* use timeout? */
1290 sal_Bool SAL_CALL
osl_shutdownSocket (
1292 oslSocketDirection Direction
)
1294 if (pSocket
== nullptr) /* ENOTSOCK */
1297 return (shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
))==0);
1300 sal_Int32 SAL_CALL
osl_getSocketOption (
1302 oslSocketOptionLevel Level
,
1303 oslSocketOption Option
,
1305 sal_uInt32 BufferLen
)
1307 if (pSocket
== nullptr) /* ENOTSOCK */
1308 return osl_Socket_Error
;
1310 int len
= BufferLen
;
1311 if (getsockopt(pSocket
->m_Socket
,
1312 OPTION_LEVEL_TO_NATIVE(Level
),
1313 OPTION_TO_NATIVE(Option
),
1314 static_cast<char *>(pBuffer
),
1323 sal_Bool SAL_CALL
osl_setSocketOption (
1325 oslSocketOptionLevel Level
,
1326 oslSocketOption Option
,
1328 sal_uInt32 BufferLen
)
1330 if (pSocket
== nullptr) /* ENOTSOCK */
1333 return(setsockopt(pSocket
->m_Socket
,
1334 OPTION_LEVEL_TO_NATIVE(Level
),
1335 OPTION_TO_NATIVE(Option
),
1336 static_cast<sal_Char
*>(pBuffer
),
1340 sal_Bool SAL_CALL
osl_enableNonBlockingMode ( oslSocket pSocket
, sal_Bool On
)
1342 unsigned long Param
= On
? 1 : 0;
1344 if (pSocket
== nullptr) /* ENOTSOCK */
1347 pSocket
->m_Flags
= Param
?
1348 (pSocket
->m_Flags
| OSL_SOCKET_FLAGS_NONBLOCKING
) :
1349 (pSocket
->m_Flags
& ~OSL_SOCKET_FLAGS_NONBLOCKING
) ;
1352 ioctlsocket(pSocket
->m_Socket
, FIONBIO
, &Param
) != OSL_SOCKET_ERROR
);
1355 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
1357 if (pSocket
== nullptr) /* ENOTSOCK */
1360 return (pSocket
->m_Flags
& OSL_SOCKET_FLAGS_NONBLOCKING
) != 0;
1363 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
1366 int TypeSize
= sizeof(Type
);
1368 if (pSocket
== nullptr) /* ENOTSOCK */
1369 return osl_Socket_TypeInvalid
;
1371 if(getsockopt(pSocket
->m_Socket
,
1372 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
1373 OPTION_TO_NATIVE(osl_Socket_OptionType
),
1374 reinterpret_cast<char *>(&Type
),
1378 return osl_Socket_TypeInvalid
;
1381 return TYPE_FROM_NATIVE(Type
);
1384 void SAL_CALL
osl_getLastSocketErrorDescription (
1385 oslSocket
/*Socket*/,
1386 rtl_uString
**strError
)
1390 switch(error
= WSAGetLastError())
1393 rtl_uString_newFromAscii (strError
, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1396 case WSAEDESTADDRREQ
:
1397 rtl_uString_newFromAscii (strError
, "WSAEDESTADDRREQ, Destination Addr required");
1401 rtl_uString_newFromAscii (strError
, "WSAEMSGSIZE, Message too long");
1405 rtl_uString_newFromAscii (strError
, "WSAEPROTOTYPE, Protocol wrong type for socket");
1408 case WSAENOPROTOOPT
:
1409 rtl_uString_newFromAscii (strError
, "WSAENOPROTOOPT, Protocol not available");
1412 case WSAEPROTONOSUPPORT
:
1413 rtl_uString_newFromAscii (strError
, "WSAEPROTONOSUPPORT, Protocol not supported");
1416 case WSAESOCKTNOSUPPORT
:
1417 rtl_uString_newFromAscii (strError
, "WSAESOCKTNOSUPPORT, Socket type not supported");
1421 rtl_uString_newFromAscii (strError
, "WSAEOPNOTSUPP, Operation not supported on socket");
1424 case WSAEPFNOSUPPORT
:
1425 rtl_uString_newFromAscii (strError
, "WSAEPFNOSUPPORT, Protocol family not supported");
1428 case WSAEAFNOSUPPORT
:
1429 rtl_uString_newFromAscii (strError
, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1433 rtl_uString_newFromAscii (strError
, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1436 case WSAEADDRNOTAVAIL
:
1437 rtl_uString_newFromAscii (strError
, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1441 rtl_uString_newFromAscii (strError
, "WSAENETDOWN, Network is down");
1444 case WSAENETUNREACH
:
1445 rtl_uString_newFromAscii (strError
, "WSAENETUNREACH, Network is unreachable");
1449 rtl_uString_newFromAscii (strError
, "WSAENETRESET, Network dropped connection or reset");
1452 case WSAECONNABORTED
:
1453 rtl_uString_newFromAscii (strError
, "WSAECONNABORTED, Software caused connection abort");
1457 rtl_uString_newFromAscii (strError
, "WSAECONNRESET, Connection reset by peer");
1461 rtl_uString_newFromAscii (strError
, "WSAENOBUFS, No buffer space available.");
1465 rtl_uString_newFromAscii (strError
, "WSAEISCONN, Socket is already connected");
1469 rtl_uString_newFromAscii (strError
, "WSAENOTCONN, Socket is not connected");
1473 rtl_uString_newFromAscii (strError
, "WSAESHUTDOWN, Can't send after socket shutdown");
1477 rtl_uString_newFromAscii (strError
, "WSAETIMEDOUT, Connection timed out");
1480 case WSAECONNREFUSED
:
1481 rtl_uString_newFromAscii (strError
, "WSAECONNREFUSED, Connection refused");
1485 rtl_uString_newFromAscii (strError
, "WSAEHOSTDOWN, Networking subsystem not started");
1488 case WSAEHOSTUNREACH
:
1489 rtl_uString_newFromAscii (strError
, "WSAEHOSTUNREACH, No route to host");
1492 case WSAEWOULDBLOCK
:
1493 rtl_uString_newFromAscii (strError
, "WSAEWOULDBLOCK, Operation would block");
1496 case WSAEINPROGRESS
:
1497 rtl_uString_newFromAscii (strError
, "WSAEINPROGRESS, Operation now in progress");
1501 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation already in progress");
1505 rtl_uString_newFromAscii (strError
, "WSAEALREADY, Operation was interrupted");
1509 rtl_uString_newFromAscii (strError
, "WSAEBADF, Bad file number");
1513 rtl_uString_newFromAscii (strError
, "WSAEACCES, Access is denied");
1517 rtl_uString_newFromAscii (strError
, "WSAEFAULT, Bad memory Addr");
1521 rtl_uString_newFromAscii (strError
, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1525 rtl_uString_newFromAscii (strError
, "WSAEMFILE, No more file descriptors are available");
1528 case WSAETOOMANYREFS
:
1529 rtl_uString_newFromAscii (strError
, "WSAETOOMANYREFS, Undocumented WinSock error");
1532 case WSAENAMETOOLONG
:
1533 rtl_uString_newFromAscii (strError
, "WSAENAMETOOLONG, Undocumented WinSock error");
1537 rtl_uString_newFromAscii (strError
, "WSAENOTEMPTY, Undocumented WinSock error");
1541 rtl_uString_newFromAscii (strError
, "WSAEPROCLIM, Undocumented WinSock error");
1545 rtl_uString_newFromAscii (strError
, "WSAEUSERS, Undocumented WinSock error");
1549 rtl_uString_newFromAscii (strError
, "WSAEDQUOT, Undocumented WinSock error");
1553 rtl_uString_newFromAscii (strError
, "WSAESTALE, Undocumented WinSock error");
1557 rtl_uString_newFromAscii (strError
, "WSAEREMOTE, Undocumented WinSock error");
1561 rtl_uString_newFromAscii (strError
, "WSAEDISCON, Circuit was gracefully terminated");
1564 case WSASYSNOTREADY
:
1565 rtl_uString_newFromAscii (strError
, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
1568 case WSAVERNOTSUPPORTED
:
1569 rtl_uString_newFromAscii (strError
, "WSAVERNOTSUPPORTED, The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation");
1572 case WSANOTINITIALISED
:
1573 rtl_uString_newFromAscii (strError
, "WSANOTINITIALISED, WSAStartup() has not been called");
1576 case WSAHOST_NOT_FOUND
:
1577 rtl_uString_newFromAscii (strError
, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
1581 rtl_uString_newFromAscii (strError
, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
1584 case WSANO_RECOVERY
:
1585 rtl_uString_newFromAscii (strError
, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1589 rtl_uString_newFromAscii (strError
, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
1594 sal_Unicode message
[128];
1596 wsprintfW(o3tl::toW(message
), L
"Unknown WinSock Error Number %d", error
);
1597 rtl_uString_newFromStr (strError
, message
);
1605 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket
/*Socket*/)
1607 return ERROR_FROM_NATIVE(WSAGetLastError());
1610 struct oslSocketSetImpl
1612 fd_set m_Set
; /* the set of descriptors */
1616 oslSocketSet SAL_CALL
osl_createSocketSet()
1618 oslSocketSetImpl
* pSet
;
1620 pSet
= static_cast<oslSocketSetImpl
*>(malloc(sizeof(oslSocketSetImpl
)));
1624 FD_ZERO(&pSet
->m_Set
);
1630 void SAL_CALL
osl_destroySocketSet (oslSocketSet Set
)
1636 void SAL_CALL
osl_clearSocketSet (oslSocketSet Set
)
1639 FD_ZERO(&Set
->m_Set
);
1642 void SAL_CALL
osl_addToSocketSet (
1647 FD_SET(Socket
->m_Socket
, &Set
->m_Set
);
1650 void SAL_CALL
osl_removeFromSocketSet (
1655 FD_CLR(Socket
->m_Socket
, &Set
->m_Set
);
1658 sal_Bool SAL_CALL
osl_isInSocketSet (
1663 return (FD_ISSET(Socket
->m_Socket
, &Set
->m_Set
) != 0);
1668 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents (
1669 oslSocketSet IncomingSet
,
1670 oslSocketSet OutgoingSet
,
1671 oslSocketSet OutOfBandSet
,
1672 const TimeValue
* pTimeout
)
1678 /* divide milliseconds into seconds and microseconds */
1679 tv
.tv_sec
= pTimeout
->Seconds
;
1680 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1683 return select(0, /* redundant in WIN32 */
1684 IncomingSet
? &IncomingSet
->m_Set
: nullptr,
1685 OutgoingSet
? &OutgoingSet
->m_Set
: nullptr,
1686 OutOfBandSet
? &OutOfBandSet
->m_Set
: nullptr,
1687 pTimeout
? &tv
: nullptr);
1690 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */