lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / sal / osl / w32 / socket.cxx
blobf3cf5016a14b1b72ac8b3b742485cf23bb1214fe
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "system.h"
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
49 or whatever).
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)
73 return i;
74 i = static_cast<oslAddrFamily>( static_cast<int>(i) + 1);
76 return i;
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)
107 return i;
108 i = static_cast<oslSocketType>(static_cast<int>(i)+1);
110 return i;
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[]= {
167 0, /* no error */
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)
206 return i;
208 i = static_cast<oslSocketError>( static_cast<int>(i) + 1);
210 return i;
213 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
215 #if OSL_DEBUG_LEVEL > 0
216 static sal_uInt32 g_nSocketAddr = 0;
217 struct LeakWarning
219 ~LeakWarning()
221 SAL_WARN_IF( g_nSocketAddr, "sal.osl", "sal_socket: " << g_nSocketAddr << " socket address instances leak" );
224 static LeakWarning socketWarning;
225 #endif
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;
232 return pSockImpl;
235 static void destroySocketImpl(oslSocketImpl *pImpl)
237 if (pImpl)
239 free (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
248 g_nSocketAddr ++;
249 #endif
250 return pAddr;
253 static oslSocketAddr createSocketAddrWithFamily(
254 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
256 OSL_ASSERT( family == osl_Socket_FamilyInet );
258 oslSocketAddr pAddr = createSocketAddr();
259 switch( family )
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);
268 break;
270 default:
271 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
273 return pAddr;
276 static oslSocketAddr createSocketAddFromSystem( struct sockaddr *pSystemSockAddr )
278 oslSocketAddr pAddr = createSocketAddr();
279 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( sockaddr ) );
280 return pAddr;
283 static void destroySocketAddr( oslSocketAddr addr )
285 #if OSL_DEBUG_LEVEL > 0
286 g_nSocketAddr --;
287 #endif
288 free( addr );
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) );
298 else
299 pAddr = createSocketAddrWithFamily( Family , 0 , 0 );
301 return pAddr;
304 /** @deprecated, to be removed */
305 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
307 oslSocketAddr pCopy = nullptr;
308 if (Addr)
310 pCopy = createSocketAddr();
312 if (pCopy)
313 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
315 return pCopy;
318 sal_Bool SAL_CALL osl_isEqualSocketAddr(oslSocketAddr Addr1, oslSocketAddr Addr2)
320 OSL_ASSERT(Addr1);
321 OSL_ASSERT(Addr2);
322 struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
323 struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
325 OSL_ASSERT(pAddr1);
326 OSL_ASSERT(pAddr2);
328 if (pAddr1->sa_family == pAddr2->sa_family)
330 switch (pAddr1->sa_family)
332 case AF_INET:
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))
340 return true;
341 SAL_FALLTHROUGH;
344 default:
346 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
351 return false;
354 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
355 rtl_uString *strDottedAddr,
356 sal_Int32 Port)
358 sal_uInt32 nAddr = OSL_INADDR_NONE;
360 if (strDottedAddr && strDottedAddr->length)
362 IN_ADDR addr;
363 INT ret = InetPtonW(AF_INET, o3tl::toW(strDottedAddr->buffer), & addr);
364 if (1 == ret)
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;
389 else
391 /* No broadcast in class D */
392 return nullptr;
394 nAddr = htonl(nAddr);
397 oslSocketAddr pAddr =
398 createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( static_cast<sal_uInt16>(Port)), nAddr );
399 return pAddr;
402 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
403 rtl_uString *strDottedAddr,
404 sal_Int32 Port)
406 sal_uInt32 Addr;
408 IN_ADDR addr;
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 );
417 return pAddr;
420 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
422 OSL_ASSERT( pAddr );
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 );
432 res = osl_Socket_Ok;
434 return res;
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 )
442 OSL_ASSERT( pAddr );
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);
450 res = osl_Socket_Ok;
452 return res;
455 struct oslHostAddrImpl {
456 rtl_uString *pHostName;
457 oslSocketAddr pSockAddr;
460 oslHostAddr SAL_CALL osl_createHostAddr (
461 rtl_uString *strHostname,
462 const oslSocketAddr pSocketAddr)
464 oslHostAddr pAddr;
465 rtl_uString *cn= nullptr;
467 if ((strHostname == nullptr) || (strHostname->length == 0) || (pSocketAddr == nullptr))
468 return 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);
477 return nullptr;
480 pAddr->pHostName= cn;
481 pAddr->pSockAddr= osl_copySocketAddr( pSocketAddr );
483 return pAddr;
486 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *strHostname)
488 if ((strHostname == nullptr) || (strHostname->length == 0))
489 return nullptr;
491 PADDRINFOW pAddrInfo = nullptr;
492 int ret = GetAddrInfoW(
493 o3tl::toW(strHostname->buffer), nullptr, nullptr, & pAddrInfo);
494 if (0 == ret)
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);
511 return pRet;
513 else
515 SAL_INFO("sal.osl", "GetAddrInfoW failed: " << WSAGetLastError());
517 return nullptr;
520 oslHostAddr SAL_CALL osl_createHostAddrByAddr(const oslSocketAddr pAddr)
522 if (pAddr == nullptr)
523 return 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))
530 return nullptr;
532 WCHAR buf[NI_MAXHOST];
533 int ret = GetNameInfoW(
534 & pAddr->m_sockaddr, sizeof(struct sockaddr),
535 buf, NI_MAXHOST,
536 nullptr, 0, 0);
537 if (0 == ret)
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));
545 return pRet;
547 else
549 SAL_INFO("sal.osl", "GetNameInfoW failed: " << WSAGetLastError());
553 return nullptr;
556 oslHostAddr SAL_CALL osl_copyHostAddr(const oslHostAddr Addr)
558 oslHostAddr pAddr = Addr;
560 if (pAddr)
561 return osl_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
562 else
563 return nullptr;
566 void SAL_CALL osl_getHostnameOfHostAddr(
567 const oslHostAddr pAddr, rtl_uString **strHostname)
569 if (pAddr)
570 rtl_uString_assign (strHostname, pAddr->pHostName);
571 else
572 rtl_uString_new (strHostname);
575 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)
577 if (pAddr)
578 return pAddr->pSockAddr;
579 else
580 return nullptr;
583 void SAL_CALL osl_destroyHostAddr(oslHostAddr pAddr)
585 if (pAddr)
587 if (pAddr->pHostName)
588 rtl_uString_release (pAddr->pHostName);
589 if (pAddr->pSockAddr)
590 osl_destroySocketAddr( pAddr->pSockAddr );
592 free (pAddr);
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)
608 oslHostAddr pAddr;
609 rtl_uString *hostName= nullptr;
611 rtl_string2UString(
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));
622 else
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);
642 if (pAddr)
644 oslSocketAddr SockAddr = osl_copySocketAddr( pAddr->pSockAddr );
645 osl_destroyHostAddr(pAddr);
646 return SockAddr;
648 return nullptr;
651 sal_Int32 SAL_CALL osl_getServicePort (
652 rtl_uString* strServicename,
653 rtl_uString* strProtocol)
655 struct servent* ps;
657 rtl_String *str_Servicename=nullptr;
658 rtl_String *str_Protocol=nullptr;
660 rtl_uString2String(
661 &str_Servicename,
662 rtl_uString_getStr(strServicename),
663 rtl_uString_getLength(strServicename),
664 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
665 rtl_uString2String(
666 &str_Protocol,
667 rtl_uString_getStr(strProtocol),
668 rtl_uString_getLength(strProtocol),
669 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
671 ps= getservbyname(
672 rtl_string_getStr(str_Servicename),
673 rtl_string_getStr(str_Protocol));
675 rtl_string_release( str_Servicename );
676 rtl_string_release( str_Protocol );
678 if (ps != nullptr)
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)
691 if (pAddr)
692 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
693 else
694 return osl_Socket_FamilyInvalid;
697 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
699 if( 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 (
710 oslSocketAddr pAddr,
711 sal_Int32 Port)
713 if (pAddr == nullptr)
714 return false;
716 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<struct sockaddr_in*>(&pAddr->m_sockaddr);
718 if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
719 return false;
721 pSystemInetAddr->sin_port= htons(static_cast<short>(Port));
722 return true;
725 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr (
726 oslSocketAddr Addr,
727 rtl_uString **strHostName)
729 oslHostAddr pAddr= osl_createHostAddrByAddr (Addr);
731 if (pAddr)
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 (
744 oslSocketAddr pAddr,
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));
759 if (nullptr == ret)
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,
772 oslSocketType Type,
773 oslProtocol Protocol)
775 /* alloc memory */
776 oslSocket pSocket = createSocketImpl(0);
778 if (pSocket == nullptr)
779 return nullptr;
781 /* create socket */
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);
793 pSocket = nullptr;
795 else
797 pSocket->m_Flags = 0;
800 return pSocket;
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 */
820 if (!pSocket)
821 return;
823 /* close */
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;
837 int AddrLen;
839 if (pSocket == nullptr) /* ENOTSOCK */
840 return nullptr;
842 AddrLen= sizeof(struct sockaddr);
844 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
845 return nullptr;
847 oslSocketAddr pAddr = createSocketAddFromSystem( &Addr );
848 return pAddr;
851 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
853 struct sockaddr Addr;
854 int AddrLen;
856 if (pSocket == nullptr) /* ENOTSOCK */
857 return nullptr;
859 AddrLen= sizeof(struct sockaddr);
861 if (getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
862 return nullptr;
864 oslSocketAddr pAddr = createSocketAddFromSystem( &Addr );
865 return pAddr;
868 sal_Bool SAL_CALL osl_bindAddrToSocket ( oslSocket pSocket, oslSocketAddr pAddr)
870 OSL_ASSERT( pAddr );
872 if (pSocket == nullptr) /* ENOTSOCK */
873 return false;
875 return (bind(pSocket->m_Socket,
876 &(pAddr->m_sockaddr),
877 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR);
880 oslSocketResult SAL_CALL osl_connectSocketTo (
881 oslSocket pSocket,
882 oslSocketAddr pAddr,
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;
898 else
899 return osl_Socket_Ok;
901 else
903 fd_set fds;
904 int error;
905 struct timeval tv;
906 unsigned long Param;
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())
917 case WSAEWOULDBLOCK:
918 case WSAEINPROGRESS:
919 return osl_Socket_InProgress;
921 default:
922 return osl_Socket_Error;
925 else
926 return osl_Socket_Ok;
929 /* set socket temporarily to non-blocking */
930 Param= 1;
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 */
941 Param= 0;
942 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
944 return osl_Socket_Ok;
946 else
948 error = WSAGetLastError();
950 /* really an error or just delayed? */
951 if (error != WSAEWOULDBLOCK && error != WSAEINPROGRESS)
953 Param= 0;
954 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
956 return osl_Socket_Error;
960 /* prepare select set for socket */
961 FD_ZERO(&fds);
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;
968 /* select */
969 error= select(pSocket->m_Socket+1,
970 nullptr,
971 &fds,
972 nullptr,
973 &tv);
975 if (error > 0) /* connected */
977 SAL_WARN_IF(
978 !FD_ISSET(pSocket->m_Socket, &fds),
979 "sal.osl",
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;
994 else
995 Result= osl_Socket_Error;
998 else /* timeout */
999 Result= osl_Socket_TimedOut;
1001 /* clean up */
1002 Param= 0;
1003 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1005 return Result;
1009 sal_Bool SAL_CALL osl_listenOnSocket (
1010 oslSocket pSocket,
1011 sal_Int32 MaxPendingConnections)
1013 if (pSocket == nullptr) /* ENOTSOCK */
1014 return false;
1016 return (listen(pSocket->m_Socket,
1017 MaxPendingConnections == -1 ?
1018 SOMAXCONN :
1019 MaxPendingConnections) != OSL_SOCKET_ERROR);
1022 oslSocket SAL_CALL osl_acceptConnectionOnSocket (
1023 oslSocket pSocket,
1024 oslSocketAddr* ppAddr)
1026 if (pSocket == nullptr) /* ENOTSOCK */
1027 return nullptr;
1029 SOCKET Connection;
1030 if(ppAddr)
1032 if( *ppAddr )
1034 osl_destroySocketAddr( *ppAddr );
1035 *ppAddr = nullptr;
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);
1047 else
1048 *ppAddr = nullptr;
1050 else
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))
1058 return nullptr;
1060 /* alloc memory */
1061 oslSocket pConnectionSocket;
1062 pConnectionSocket= createSocketImpl(Connection);
1064 pConnectionSocket->m_Flags = 0;
1066 return pConnectionSocket;
1069 sal_Int32 SAL_CALL osl_receiveSocket (
1070 oslSocket pSocket,
1071 void* pBuffer,
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),
1080 BytesToRead,
1081 MSG_FLAG_TO_NATIVE(Flag));
1084 sal_Int32 SAL_CALL osl_receiveFromSocket (
1085 oslSocket pSocket,
1086 oslSocketAddr SenderAddr,
1087 void* pBuffer,
1088 sal_uInt32 BufferSize,
1089 oslSocketMsgFlag Flag)
1091 struct sockaddr *pSystemSockAddr = nullptr;
1092 int AddrLen = 0;
1093 if( SenderAddr )
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),
1104 BufferSize,
1105 MSG_FLAG_TO_NATIVE(Flag),
1106 pSystemSockAddr,
1107 &AddrLen);
1110 sal_Int32 SAL_CALL osl_sendSocket (
1111 oslSocket pSocket,
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),
1121 BytesToSend,
1122 MSG_FLAG_TO_NATIVE(Flag));
1125 sal_Int32 SAL_CALL osl_sendToSocket (
1126 oslSocket pSocket,
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;
1139 if( ReceiverAddr )
1140 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1142 return sendto(pSocket->m_Socket,
1143 static_cast<sal_Char const *>(pBuffer),
1144 BytesToSend,
1145 MSG_FLAG_TO_NATIVE(Flag),
1146 pSystemSockAddr,
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)
1161 sal_Int32 RetVal;
1162 RetVal= osl_receiveSocket(pSocket,
1163 Ptr,
1164 BytesToRead,
1165 osl_Socket_MsgNormal);
1167 /* error occurred? */
1168 if(RetVal <= 0)
1170 break;
1173 BytesToRead -= RetVal;
1174 BytesRead += RetVal;
1175 Ptr += RetVal;
1178 return BytesRead;
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)
1191 sal_Int32 RetVal;
1193 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1195 /* error occurred? */
1196 if(RetVal <= 0)
1198 break;
1201 BytesToSend -= RetVal;
1202 BytesSend += RetVal;
1203 Ptr += RetVal;
1206 return BytesSend;
1209 sal_Bool SAL_CALL osl_isReceiveReady (
1210 oslSocket pSocket,
1211 const TimeValue* pTimeout)
1213 fd_set fds;
1214 struct timeval tv;
1216 if (pSocket == nullptr) /* ENOTSOCK */
1217 return false;
1219 FD_ZERO(&fds);
1220 FD_SET(pSocket->m_Socket, &fds);
1222 if (pTimeout)
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 (
1239 oslSocket pSocket,
1240 const TimeValue* pTimeout)
1242 fd_set fds;
1243 struct timeval tv;
1245 if (pSocket == nullptr) /* ENOTSOCK */
1246 return false;
1248 FD_ZERO(&fds);
1249 FD_SET(pSocket->m_Socket, &fds);
1251 if (pTimeout)
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 (
1265 oslSocket pSocket,
1266 const TimeValue* pTimeout)
1268 fd_set fds;
1269 struct timeval tv;
1271 if (pSocket == nullptr) /* ENOTSOCK */
1272 return false;
1274 FD_ZERO(&fds);
1275 FD_SET(pSocket->m_Socket, &fds);
1277 if (pTimeout)
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 (
1291 oslSocket pSocket,
1292 oslSocketDirection Direction)
1294 if (pSocket == nullptr) /* ENOTSOCK */
1295 return false;
1297 return (shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction))==0);
1300 sal_Int32 SAL_CALL osl_getSocketOption (
1301 oslSocket pSocket,
1302 oslSocketOptionLevel Level,
1303 oslSocketOption Option,
1304 void* pBuffer,
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),
1315 &len) == -1)
1317 return -1;
1320 return len;
1323 sal_Bool SAL_CALL osl_setSocketOption (
1324 oslSocket pSocket,
1325 oslSocketOptionLevel Level,
1326 oslSocketOption Option,
1327 void* pBuffer,
1328 sal_uInt32 BufferLen)
1330 if (pSocket == nullptr) /* ENOTSOCK */
1331 return false;
1333 return(setsockopt(pSocket->m_Socket,
1334 OPTION_LEVEL_TO_NATIVE(Level),
1335 OPTION_TO_NATIVE(Option),
1336 static_cast<sal_Char*>(pBuffer),
1337 BufferLen) == 0);
1340 sal_Bool SAL_CALL osl_enableNonBlockingMode ( oslSocket pSocket, sal_Bool On)
1342 unsigned long Param= On ? 1 : 0;
1344 if (pSocket == nullptr) /* ENOTSOCK */
1345 return false;
1347 pSocket->m_Flags = Param ?
1348 (pSocket->m_Flags | OSL_SOCKET_FLAGS_NONBLOCKING) :
1349 (pSocket->m_Flags & ~OSL_SOCKET_FLAGS_NONBLOCKING) ;
1351 return (
1352 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
1355 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
1357 if (pSocket == nullptr) /* ENOTSOCK */
1358 return false;
1360 return (pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING) != 0;
1363 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
1365 int Type=0;
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),
1375 &TypeSize) == -1)
1377 /* error */
1378 return osl_Socket_TypeInvalid;
1381 return TYPE_FROM_NATIVE(Type);
1384 void SAL_CALL osl_getLastSocketErrorDescription (
1385 oslSocket /*Socket*/,
1386 rtl_uString **strError)
1388 int error;
1390 switch(error = WSAGetLastError())
1392 case WSAENOTSOCK:
1393 rtl_uString_newFromAscii (strError, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1394 break;
1396 case WSAEDESTADDRREQ:
1397 rtl_uString_newFromAscii (strError, "WSAEDESTADDRREQ, Destination Addr required");
1398 break;
1400 case WSAEMSGSIZE:
1401 rtl_uString_newFromAscii (strError, "WSAEMSGSIZE, Message too long");
1402 break;
1404 case WSAEPROTOTYPE:
1405 rtl_uString_newFromAscii (strError, "WSAEPROTOTYPE, Protocol wrong type for socket");
1406 break;
1408 case WSAENOPROTOOPT:
1409 rtl_uString_newFromAscii (strError, "WSAENOPROTOOPT, Protocol not available");
1410 break;
1412 case WSAEPROTONOSUPPORT:
1413 rtl_uString_newFromAscii (strError, "WSAEPROTONOSUPPORT, Protocol not supported");
1414 break;
1416 case WSAESOCKTNOSUPPORT:
1417 rtl_uString_newFromAscii (strError, "WSAESOCKTNOSUPPORT, Socket type not supported");
1418 break;
1420 case WSAEOPNOTSUPP:
1421 rtl_uString_newFromAscii (strError, "WSAEOPNOTSUPP, Operation not supported on socket");
1422 break;
1424 case WSAEPFNOSUPPORT:
1425 rtl_uString_newFromAscii (strError, "WSAEPFNOSUPPORT, Protocol family not supported");
1426 break;
1428 case WSAEAFNOSUPPORT:
1429 rtl_uString_newFromAscii (strError, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1430 break;
1432 case WSAEADDRINUSE:
1433 rtl_uString_newFromAscii (strError, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1434 break;
1436 case WSAEADDRNOTAVAIL:
1437 rtl_uString_newFromAscii (strError, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1438 break;
1440 case WSAENETDOWN:
1441 rtl_uString_newFromAscii (strError, "WSAENETDOWN, Network is down");
1442 break;
1444 case WSAENETUNREACH:
1445 rtl_uString_newFromAscii (strError, "WSAENETUNREACH, Network is unreachable");
1446 break;
1448 case WSAENETRESET:
1449 rtl_uString_newFromAscii (strError, "WSAENETRESET, Network dropped connection or reset");
1450 break;
1452 case WSAECONNABORTED:
1453 rtl_uString_newFromAscii (strError, "WSAECONNABORTED, Software caused connection abort");
1454 break;
1456 case WSAECONNRESET:
1457 rtl_uString_newFromAscii (strError, "WSAECONNRESET, Connection reset by peer");
1458 break;
1460 case WSAENOBUFS:
1461 rtl_uString_newFromAscii (strError, "WSAENOBUFS, No buffer space available.");
1462 break;
1464 case WSAEISCONN:
1465 rtl_uString_newFromAscii (strError, "WSAEISCONN, Socket is already connected");
1466 break;
1468 case WSAENOTCONN:
1469 rtl_uString_newFromAscii (strError, "WSAENOTCONN, Socket is not connected");
1470 break;
1472 case WSAESHUTDOWN:
1473 rtl_uString_newFromAscii (strError, "WSAESHUTDOWN, Can't send after socket shutdown");
1474 break;
1476 case WSAETIMEDOUT:
1477 rtl_uString_newFromAscii (strError, "WSAETIMEDOUT, Connection timed out");
1478 break;
1480 case WSAECONNREFUSED:
1481 rtl_uString_newFromAscii (strError, "WSAECONNREFUSED, Connection refused");
1482 break;
1484 case WSAEHOSTDOWN:
1485 rtl_uString_newFromAscii (strError, "WSAEHOSTDOWN, Networking subsystem not started");
1486 break;
1488 case WSAEHOSTUNREACH:
1489 rtl_uString_newFromAscii (strError, "WSAEHOSTUNREACH, No route to host");
1490 break;
1492 case WSAEWOULDBLOCK:
1493 rtl_uString_newFromAscii (strError, "WSAEWOULDBLOCK, Operation would block");
1494 break;
1496 case WSAEINPROGRESS:
1497 rtl_uString_newFromAscii (strError, "WSAEINPROGRESS, Operation now in progress");
1498 break;
1500 case WSAEALREADY:
1501 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation already in progress");
1502 break;
1504 case WSAEINTR:
1505 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation was interrupted");
1506 break;
1508 case WSAEBADF:
1509 rtl_uString_newFromAscii (strError, "WSAEBADF, Bad file number");
1510 break;
1512 case WSAEACCES:
1513 rtl_uString_newFromAscii (strError, "WSAEACCES, Access is denied");
1514 break;
1516 case WSAEFAULT:
1517 rtl_uString_newFromAscii (strError, "WSAEFAULT, Bad memory Addr");
1518 break;
1520 case WSAEINVAL:
1521 rtl_uString_newFromAscii (strError, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1522 break;
1524 case WSAEMFILE:
1525 rtl_uString_newFromAscii (strError, "WSAEMFILE, No more file descriptors are available");
1526 break;
1528 case WSAETOOMANYREFS:
1529 rtl_uString_newFromAscii (strError, "WSAETOOMANYREFS, Undocumented WinSock error");
1530 break;
1532 case WSAENAMETOOLONG:
1533 rtl_uString_newFromAscii (strError, "WSAENAMETOOLONG, Undocumented WinSock error");
1534 break;
1536 case WSAENOTEMPTY:
1537 rtl_uString_newFromAscii (strError, "WSAENOTEMPTY, Undocumented WinSock error");
1538 break;
1540 case WSAEPROCLIM:
1541 rtl_uString_newFromAscii (strError, "WSAEPROCLIM, Undocumented WinSock error");
1542 break;
1544 case WSAEUSERS:
1545 rtl_uString_newFromAscii (strError, "WSAEUSERS, Undocumented WinSock error");
1546 break;
1548 case WSAEDQUOT:
1549 rtl_uString_newFromAscii (strError, "WSAEDQUOT, Undocumented WinSock error");
1550 break;
1552 case WSAESTALE:
1553 rtl_uString_newFromAscii (strError, "WSAESTALE, Undocumented WinSock error");
1554 break;
1556 case WSAEREMOTE:
1557 rtl_uString_newFromAscii (strError, "WSAEREMOTE, Undocumented WinSock error");
1558 break;
1560 case WSAEDISCON:
1561 rtl_uString_newFromAscii (strError, "WSAEDISCON, Circuit was gracefully terminated");
1562 break;
1564 case WSASYSNOTREADY:
1565 rtl_uString_newFromAscii (strError, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
1566 break;
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");
1570 break;
1572 case WSANOTINITIALISED:
1573 rtl_uString_newFromAscii (strError, "WSANOTINITIALISED, WSAStartup() has not been called");
1574 break;
1576 case WSAHOST_NOT_FOUND:
1577 rtl_uString_newFromAscii (strError, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
1578 break;
1580 case WSATRY_AGAIN:
1581 rtl_uString_newFromAscii (strError, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
1582 break;
1584 case WSANO_RECOVERY:
1585 rtl_uString_newFromAscii (strError, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1586 break;
1588 case WSANO_DATA:
1589 rtl_uString_newFromAscii (strError, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
1590 break;
1592 default:
1594 sal_Unicode message[128];
1596 wsprintfW(o3tl::toW(message), L"Unknown WinSock Error Number %d", error);
1597 rtl_uString_newFromStr (strError, message);
1600 return;
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)));
1622 if(pSet)
1624 FD_ZERO(&pSet->m_Set);
1627 return pSet;
1630 void SAL_CALL osl_destroySocketSet (oslSocketSet Set)
1632 if(Set)
1633 free(Set);
1636 void SAL_CALL osl_clearSocketSet (oslSocketSet Set)
1638 if (Set)
1639 FD_ZERO(&Set->m_Set);
1642 void SAL_CALL osl_addToSocketSet (
1643 oslSocketSet Set,
1644 oslSocket Socket)
1646 if (Set && Socket)
1647 FD_SET(Socket->m_Socket, &Set->m_Set);
1650 void SAL_CALL osl_removeFromSocketSet (
1651 oslSocketSet Set,
1652 oslSocket Socket)
1654 if (Set && Socket)
1655 FD_CLR(Socket->m_Socket, &Set->m_Set);
1658 sal_Bool SAL_CALL osl_isInSocketSet (
1659 oslSocketSet Set,
1660 oslSocket Socket)
1662 if (Set && Socket)
1663 return (FD_ISSET(Socket->m_Socket, &Set->m_Set) != 0);
1664 else
1665 return false;
1668 sal_Int32 SAL_CALL osl_demultiplexSocketEvents (
1669 oslSocketSet IncomingSet,
1670 oslSocketSet OutgoingSet,
1671 oslSocketSet OutOfBandSet,
1672 const TimeValue* pTimeout)
1674 struct timeval tv;
1676 if(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: */