Branch libreoffice-6-3
[LibreOffice.git] / sal / osl / w32 / socket.cxx
blob3bee3ecde178b4daf243ccab568c60728f4c4be6
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 <sal/config.h>
22 #include <utility>
24 #include "system.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
54 or whatever).
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)
78 return i;
79 i = static_cast<oslAddrFamily>( static_cast<int>(i) + 1);
81 return i;
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)
112 return i;
113 i = static_cast<oslSocketType>(static_cast<int>(i)+1);
115 return i;
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[]= {
172 0, /* no error */
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)
211 return i;
213 i = static_cast<oslSocketError>( static_cast<int>(i) + 1);
215 return i;
218 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
220 #if OSL_DEBUG_LEVEL > 0
221 static sal_uInt32 g_nSocketAddr = 0;
222 struct LeakWarning
224 ~LeakWarning()
226 SAL_WARN_IF( g_nSocketAddr, "sal.osl", "sal_socket: " << g_nSocketAddr << " socket address instances leak" );
229 static LeakWarning socketWarning;
230 #endif
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;
237 return pSockImpl;
240 static void destroySocketImpl(oslSocketImpl *pImpl)
242 if (pImpl)
244 free (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
253 g_nSocketAddr ++;
254 #endif
255 return pAddr;
258 static oslSocketAddr createSocketAddrWithFamily(
259 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
261 OSL_ASSERT( family == osl_Socket_FamilyInet );
263 oslSocketAddr pAddr = createSocketAddr();
264 switch( family )
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);
273 break;
275 default:
276 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
278 return pAddr;
281 static oslSocketAddr createSocketAddFromSystem( struct sockaddr *pSystemSockAddr )
283 oslSocketAddr pAddr = createSocketAddr();
284 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( sockaddr ) );
285 return pAddr;
288 static void destroySocketAddr( oslSocketAddr addr )
290 #if OSL_DEBUG_LEVEL > 0
291 g_nSocketAddr --;
292 #endif
293 free( addr );
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) );
303 else
304 pAddr = createSocketAddrWithFamily( Family , 0 , 0 );
306 return pAddr;
309 /** @deprecated, to be removed */
310 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
312 oslSocketAddr pCopy = nullptr;
313 if (Addr)
315 pCopy = createSocketAddr();
317 if (pCopy)
318 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
320 return pCopy;
323 sal_Bool SAL_CALL osl_isEqualSocketAddr(oslSocketAddr Addr1, oslSocketAddr Addr2)
325 OSL_ASSERT(Addr1);
326 OSL_ASSERT(Addr2);
327 struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
328 struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
330 OSL_ASSERT(pAddr1);
331 OSL_ASSERT(pAddr2);
333 if (pAddr1->sa_family == pAddr2->sa_family)
335 switch (pAddr1->sa_family)
337 case AF_INET:
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))
345 return true;
346 [[fallthrough]];
349 default:
351 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
356 return false;
359 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
360 rtl_uString *strDottedAddr,
361 sal_Int32 Port)
363 sal_uInt32 nAddr = OSL_INADDR_NONE;
365 if (strDottedAddr && strDottedAddr->length)
367 IN_ADDR addr;
368 INT ret = InetPtonW(AF_INET, o3tl::toW(strDottedAddr->buffer), & addr);
369 if (1 == ret)
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;
394 else
396 /* No broadcast in class D */
397 return nullptr;
399 nAddr = htonl(nAddr);
402 oslSocketAddr pAddr =
403 createSocketAddrWithFamily( osl_Socket_FamilyInet, htons( static_cast<sal_uInt16>(Port)), nAddr );
404 return pAddr;
407 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
408 rtl_uString *strDottedAddr,
409 sal_Int32 Port)
411 sal_uInt32 Addr;
413 IN_ADDR addr;
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 );
422 return pAddr;
425 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
427 OSL_ASSERT( pAddr );
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 );
437 res = osl_Socket_Ok;
439 return res;
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 )
447 OSL_ASSERT( pAddr );
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);
455 res = osl_Socket_Ok;
457 return res;
460 struct oslHostAddrImpl {
461 rtl_uString *pHostName;
462 oslSocketAddr pSockAddr;
465 oslHostAddr SAL_CALL osl_createHostAddr (
466 rtl_uString *strHostname,
467 const oslSocketAddr pSocketAddr)
469 oslHostAddr pAddr;
470 rtl_uString *cn= nullptr;
472 if ((strHostname == nullptr) || (strHostname->length == 0) || (pSocketAddr == nullptr))
473 return 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);
482 return nullptr;
485 pAddr->pHostName= cn;
486 pAddr->pSockAddr= osl_copySocketAddr( pSocketAddr );
488 return pAddr;
491 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *strHostname)
493 if ((strHostname == nullptr) || (strHostname->length == 0))
494 return nullptr;
496 PADDRINFOW pAddrInfo = nullptr;
497 int ret = GetAddrInfoW(
498 o3tl::toW(strHostname->buffer), nullptr, nullptr, & pAddrInfo);
499 if (0 == ret)
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);
516 return pRet;
518 else
520 SAL_INFO("sal.osl", "GetAddrInfoW failed: " << WSAGetLastError());
522 return nullptr;
525 oslHostAddr SAL_CALL osl_createHostAddrByAddr(const oslSocketAddr pAddr)
527 if (pAddr == nullptr)
528 return 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))
535 return nullptr;
537 WCHAR buf[NI_MAXHOST];
538 int ret = GetNameInfoW(
539 & pAddr->m_sockaddr, sizeof(struct sockaddr),
540 buf, NI_MAXHOST,
541 nullptr, 0, 0);
542 if (0 == ret)
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));
550 return pRet;
552 else
554 SAL_INFO("sal.osl", "GetNameInfoW failed: " << WSAGetLastError());
558 return nullptr;
561 oslHostAddr SAL_CALL osl_copyHostAddr(const oslHostAddr Addr)
563 oslHostAddr pAddr = Addr;
565 if (pAddr)
566 return osl_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
567 else
568 return nullptr;
571 void SAL_CALL osl_getHostnameOfHostAddr(
572 const oslHostAddr pAddr, rtl_uString **strHostname)
574 if (pAddr)
575 rtl_uString_assign (strHostname, pAddr->pHostName);
576 else
577 rtl_uString_new (strHostname);
580 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr(const oslHostAddr pAddr)
582 if (pAddr)
583 return pAddr->pSockAddr;
584 else
585 return nullptr;
588 void SAL_CALL osl_destroyHostAddr(oslHostAddr pAddr)
590 if (pAddr)
592 if (pAddr->pHostName)
593 rtl_uString_release (pAddr->pHostName);
594 if (pAddr->pSockAddr)
595 osl_destroySocketAddr( pAddr->pSockAddr );
597 free (pAddr);
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)
612 oslHostAddr pAddr;
613 rtl_uString *hostName= nullptr;
615 rtl_string2UString(
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));
625 else
626 memset(LocalHostname, 0, sizeof(LocalHostname));
628 osl_destroyHostAddr (pAddr);
630 if (LocalHostname[0] == u'\0')
632 OUString u;
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()};
651 }();
653 rtl_uString_assign (strLocalHostname, init.second.pData);
655 return init.first;
658 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString* strHostname)
660 oslHostAddr pAddr = osl_createHostAddrByName (strHostname);
661 if (pAddr)
663 oslSocketAddr SockAddr = osl_copySocketAddr( pAddr->pSockAddr );
664 osl_destroyHostAddr(pAddr);
665 return SockAddr;
667 return nullptr;
670 sal_Int32 SAL_CALL osl_getServicePort (
671 rtl_uString* strServicename,
672 rtl_uString* strProtocol)
674 struct servent* ps;
676 rtl_String *str_Servicename=nullptr;
677 rtl_String *str_Protocol=nullptr;
679 rtl_uString2String(
680 &str_Servicename,
681 rtl_uString_getStr(strServicename),
682 rtl_uString_getLength(strServicename),
683 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
684 rtl_uString2String(
685 &str_Protocol,
686 rtl_uString_getStr(strProtocol),
687 rtl_uString_getLength(strProtocol),
688 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
690 ps= getservbyname(
691 rtl_string_getStr(str_Servicename),
692 rtl_string_getStr(str_Protocol));
694 rtl_string_release( str_Servicename );
695 rtl_string_release( str_Protocol );
697 if (ps != nullptr)
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)
710 if (pAddr)
711 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
712 else
713 return osl_Socket_FamilyInvalid;
716 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
718 if( 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 (
729 oslSocketAddr pAddr,
730 sal_Int32 Port)
732 if (pAddr == nullptr)
733 return false;
735 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<struct sockaddr_in*>(&pAddr->m_sockaddr);
737 if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
738 return false;
740 pSystemInetAddr->sin_port= htons(static_cast<short>(Port));
741 return true;
744 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr (
745 oslSocketAddr Addr,
746 rtl_uString **strHostName)
748 oslHostAddr pAddr= osl_createHostAddrByAddr (Addr);
750 if (pAddr)
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 (
763 oslSocketAddr pAddr,
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));
778 if (nullptr == ret)
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,
791 oslSocketType Type,
792 oslProtocol Protocol)
794 /* alloc memory */
795 oslSocket pSocket = createSocketImpl(0);
797 if (pSocket == nullptr)
798 return nullptr;
800 /* create socket */
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);
812 pSocket = nullptr;
814 else
816 pSocket->m_Flags = 0;
819 return pSocket;
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 */
839 if (!pSocket)
840 return;
842 /* close */
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;
856 int AddrLen;
858 if (pSocket == nullptr) /* ENOTSOCK */
859 return nullptr;
861 AddrLen= sizeof(struct sockaddr);
863 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
864 return nullptr;
866 oslSocketAddr pAddr = createSocketAddFromSystem( &Addr );
867 return pAddr;
870 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
872 struct sockaddr Addr;
873 int AddrLen;
875 if (pSocket == nullptr) /* ENOTSOCK */
876 return nullptr;
878 AddrLen= sizeof(struct sockaddr);
880 if (getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
881 return nullptr;
883 oslSocketAddr pAddr = createSocketAddFromSystem( &Addr );
884 return pAddr;
887 sal_Bool SAL_CALL osl_bindAddrToSocket ( oslSocket pSocket, oslSocketAddr pAddr)
889 OSL_ASSERT( pAddr );
891 if (pSocket == nullptr) /* ENOTSOCK */
892 return false;
894 return (bind(pSocket->m_Socket,
895 &(pAddr->m_sockaddr),
896 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR);
899 oslSocketResult SAL_CALL osl_connectSocketTo (
900 oslSocket pSocket,
901 oslSocketAddr pAddr,
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;
917 else
918 return osl_Socket_Ok;
920 else
922 fd_set fds;
923 int error;
924 struct timeval tv;
925 unsigned long Param;
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())
936 case WSAEWOULDBLOCK:
937 case WSAEINPROGRESS:
938 return osl_Socket_InProgress;
940 default:
941 return osl_Socket_Error;
944 else
945 return osl_Socket_Ok;
948 /* set socket temporarily to non-blocking */
949 Param= 1;
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 */
960 Param= 0;
961 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
963 return osl_Socket_Ok;
965 else
967 error = WSAGetLastError();
969 /* really an error or just delayed? */
970 if (error != WSAEWOULDBLOCK && error != WSAEINPROGRESS)
972 Param= 0;
973 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
975 return osl_Socket_Error;
979 /* prepare select set for socket */
980 FD_ZERO(&fds);
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;
987 /* select */
988 error= select(pSocket->m_Socket+1,
989 nullptr,
990 &fds,
991 nullptr,
992 &tv);
994 if (error > 0) /* connected */
996 SAL_WARN_IF(
997 !FD_ISSET(pSocket->m_Socket, &fds),
998 "sal.osl",
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;
1013 else
1014 Result= osl_Socket_Error;
1017 else /* timeout */
1018 Result= osl_Socket_TimedOut;
1020 /* clean up */
1021 Param= 0;
1022 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param);
1024 return Result;
1028 sal_Bool SAL_CALL osl_listenOnSocket (
1029 oslSocket pSocket,
1030 sal_Int32 MaxPendingConnections)
1032 if (pSocket == nullptr) /* ENOTSOCK */
1033 return false;
1035 return (listen(pSocket->m_Socket,
1036 MaxPendingConnections == -1 ?
1037 SOMAXCONN :
1038 MaxPendingConnections) != OSL_SOCKET_ERROR);
1041 oslSocket SAL_CALL osl_acceptConnectionOnSocket (
1042 oslSocket pSocket,
1043 oslSocketAddr* ppAddr)
1045 if (pSocket == nullptr) /* ENOTSOCK */
1046 return nullptr;
1048 SOCKET Connection;
1049 if(ppAddr)
1051 if( *ppAddr )
1053 osl_destroySocketAddr( *ppAddr );
1054 *ppAddr = nullptr;
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);
1066 else
1067 *ppAddr = nullptr;
1069 else
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))
1077 return nullptr;
1079 /* alloc memory */
1080 oslSocket pConnectionSocket;
1081 pConnectionSocket= createSocketImpl(Connection);
1083 pConnectionSocket->m_Flags = 0;
1085 return pConnectionSocket;
1088 sal_Int32 SAL_CALL osl_receiveSocket (
1089 oslSocket pSocket,
1090 void* pBuffer,
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),
1099 BytesToRead,
1100 MSG_FLAG_TO_NATIVE(Flag));
1103 sal_Int32 SAL_CALL osl_receiveFromSocket (
1104 oslSocket pSocket,
1105 oslSocketAddr SenderAddr,
1106 void* pBuffer,
1107 sal_uInt32 BufferSize,
1108 oslSocketMsgFlag Flag)
1110 struct sockaddr *pSystemSockAddr = nullptr;
1111 int AddrLen = 0;
1112 if( SenderAddr )
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),
1123 BufferSize,
1124 MSG_FLAG_TO_NATIVE(Flag),
1125 pSystemSockAddr,
1126 &AddrLen);
1129 sal_Int32 SAL_CALL osl_sendSocket (
1130 oslSocket pSocket,
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),
1140 BytesToSend,
1141 MSG_FLAG_TO_NATIVE(Flag));
1144 sal_Int32 SAL_CALL osl_sendToSocket (
1145 oslSocket pSocket,
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;
1158 if( ReceiverAddr )
1159 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1161 return sendto(pSocket->m_Socket,
1162 static_cast<sal_Char const *>(pBuffer),
1163 BytesToSend,
1164 MSG_FLAG_TO_NATIVE(Flag),
1165 pSystemSockAddr,
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)
1180 sal_Int32 RetVal;
1181 RetVal= osl_receiveSocket(pSocket,
1182 Ptr,
1183 BytesToRead,
1184 osl_Socket_MsgNormal);
1186 /* error occurred? */
1187 if(RetVal <= 0)
1189 break;
1192 BytesToRead -= RetVal;
1193 BytesRead += RetVal;
1194 Ptr += RetVal;
1197 return BytesRead;
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)
1210 sal_Int32 RetVal;
1212 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1214 /* error occurred? */
1215 if(RetVal <= 0)
1217 break;
1220 BytesToSend -= RetVal;
1221 BytesSend += RetVal;
1222 Ptr += RetVal;
1225 return BytesSend;
1228 sal_Bool SAL_CALL osl_isReceiveReady (
1229 oslSocket pSocket,
1230 const TimeValue* pTimeout)
1232 fd_set fds;
1233 struct timeval tv;
1235 if (pSocket == nullptr) /* ENOTSOCK */
1236 return false;
1238 FD_ZERO(&fds);
1239 FD_SET(pSocket->m_Socket, &fds);
1241 if (pTimeout)
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 (
1258 oslSocket pSocket,
1259 const TimeValue* pTimeout)
1261 fd_set fds;
1262 struct timeval tv;
1264 if (pSocket == nullptr) /* ENOTSOCK */
1265 return false;
1267 FD_ZERO(&fds);
1268 FD_SET(pSocket->m_Socket, &fds);
1270 if (pTimeout)
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 (
1284 oslSocket pSocket,
1285 const TimeValue* pTimeout)
1287 fd_set fds;
1288 struct timeval tv;
1290 if (pSocket == nullptr) /* ENOTSOCK */
1291 return false;
1293 FD_ZERO(&fds);
1294 FD_SET(pSocket->m_Socket, &fds);
1296 if (pTimeout)
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 (
1310 oslSocket pSocket,
1311 oslSocketDirection Direction)
1313 if (pSocket == nullptr) /* ENOTSOCK */
1314 return false;
1316 return (shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction))==0);
1319 sal_Int32 SAL_CALL osl_getSocketOption (
1320 oslSocket pSocket,
1321 oslSocketOptionLevel Level,
1322 oslSocketOption Option,
1323 void* pBuffer,
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),
1334 &len) == -1)
1336 return -1;
1339 return len;
1342 sal_Bool SAL_CALL osl_setSocketOption (
1343 oslSocket pSocket,
1344 oslSocketOptionLevel Level,
1345 oslSocketOption Option,
1346 void* pBuffer,
1347 sal_uInt32 BufferLen)
1349 if (pSocket == nullptr) /* ENOTSOCK */
1350 return false;
1352 return(setsockopt(pSocket->m_Socket,
1353 OPTION_LEVEL_TO_NATIVE(Level),
1354 OPTION_TO_NATIVE(Option),
1355 static_cast<sal_Char*>(pBuffer),
1356 BufferLen) == 0);
1359 sal_Bool SAL_CALL osl_enableNonBlockingMode ( oslSocket pSocket, sal_Bool On)
1361 unsigned long Param= On ? 1 : 0;
1363 if (pSocket == nullptr) /* ENOTSOCK */
1364 return false;
1366 pSocket->m_Flags = Param ?
1367 (pSocket->m_Flags | OSL_SOCKET_FLAGS_NONBLOCKING) :
1368 (pSocket->m_Flags & ~OSL_SOCKET_FLAGS_NONBLOCKING) ;
1370 return (
1371 ioctlsocket(pSocket->m_Socket, FIONBIO, &Param) != OSL_SOCKET_ERROR);
1374 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
1376 if (pSocket == nullptr) /* ENOTSOCK */
1377 return false;
1379 return (pSocket->m_Flags & OSL_SOCKET_FLAGS_NONBLOCKING) != 0;
1382 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
1384 int Type=0;
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),
1394 &TypeSize) == -1)
1396 /* error */
1397 return osl_Socket_TypeInvalid;
1400 return TYPE_FROM_NATIVE(Type);
1403 void SAL_CALL osl_getLastSocketErrorDescription (
1404 oslSocket /*Socket*/,
1405 rtl_uString **strError)
1407 int error;
1409 switch(error = WSAGetLastError())
1411 case WSAENOTSOCK:
1412 rtl_uString_newFromAscii (strError, "WSAENOTSOCK, Socket operation on non-socket. A socket created in one process is used by another process.");
1413 break;
1415 case WSAEDESTADDRREQ:
1416 rtl_uString_newFromAscii (strError, "WSAEDESTADDRREQ, Destination Addr required");
1417 break;
1419 case WSAEMSGSIZE:
1420 rtl_uString_newFromAscii (strError, "WSAEMSGSIZE, Message too long");
1421 break;
1423 case WSAEPROTOTYPE:
1424 rtl_uString_newFromAscii (strError, "WSAEPROTOTYPE, Protocol wrong type for socket");
1425 break;
1427 case WSAENOPROTOOPT:
1428 rtl_uString_newFromAscii (strError, "WSAENOPROTOOPT, Protocol not available");
1429 break;
1431 case WSAEPROTONOSUPPORT:
1432 rtl_uString_newFromAscii (strError, "WSAEPROTONOSUPPORT, Protocol not supported");
1433 break;
1435 case WSAESOCKTNOSUPPORT:
1436 rtl_uString_newFromAscii (strError, "WSAESOCKTNOSUPPORT, Socket type not supported");
1437 break;
1439 case WSAEOPNOTSUPP:
1440 rtl_uString_newFromAscii (strError, "WSAEOPNOTSUPP, Operation not supported on socket");
1441 break;
1443 case WSAEPFNOSUPPORT:
1444 rtl_uString_newFromAscii (strError, "WSAEPFNOSUPPORT, Protocol family not supported");
1445 break;
1447 case WSAEAFNOSUPPORT:
1448 rtl_uString_newFromAscii (strError, "WSEAFNOSUPPORT, Addr family not supported by protocol family");
1449 break;
1451 case WSAEADDRINUSE:
1452 rtl_uString_newFromAscii (strError, "WSAEADDRINUSE, Triggered by bind() because a process went down without closing a socket.");
1453 break;
1455 case WSAEADDRNOTAVAIL:
1456 rtl_uString_newFromAscii (strError, "WSAEADDRNOTAVAIL, Can't assign requested Addr");
1457 break;
1459 case WSAENETDOWN:
1460 rtl_uString_newFromAscii (strError, "WSAENETDOWN, Network is down");
1461 break;
1463 case WSAENETUNREACH:
1464 rtl_uString_newFromAscii (strError, "WSAENETUNREACH, Network is unreachable");
1465 break;
1467 case WSAENETRESET:
1468 rtl_uString_newFromAscii (strError, "WSAENETRESET, Network dropped connection or reset");
1469 break;
1471 case WSAECONNABORTED:
1472 rtl_uString_newFromAscii (strError, "WSAECONNABORTED, Software caused connection abort");
1473 break;
1475 case WSAECONNRESET:
1476 rtl_uString_newFromAscii (strError, "WSAECONNRESET, Connection reset by peer");
1477 break;
1479 case WSAENOBUFS:
1480 rtl_uString_newFromAscii (strError, "WSAENOBUFS, No buffer space available.");
1481 break;
1483 case WSAEISCONN:
1484 rtl_uString_newFromAscii (strError, "WSAEISCONN, Socket is already connected");
1485 break;
1487 case WSAENOTCONN:
1488 rtl_uString_newFromAscii (strError, "WSAENOTCONN, Socket is not connected");
1489 break;
1491 case WSAESHUTDOWN:
1492 rtl_uString_newFromAscii (strError, "WSAESHUTDOWN, Can't send after socket shutdown");
1493 break;
1495 case WSAETIMEDOUT:
1496 rtl_uString_newFromAscii (strError, "WSAETIMEDOUT, Connection timed out");
1497 break;
1499 case WSAECONNREFUSED:
1500 rtl_uString_newFromAscii (strError, "WSAECONNREFUSED, Connection refused");
1501 break;
1503 case WSAEHOSTDOWN:
1504 rtl_uString_newFromAscii (strError, "WSAEHOSTDOWN, Networking subsystem not started");
1505 break;
1507 case WSAEHOSTUNREACH:
1508 rtl_uString_newFromAscii (strError, "WSAEHOSTUNREACH, No route to host");
1509 break;
1511 case WSAEWOULDBLOCK:
1512 rtl_uString_newFromAscii (strError, "WSAEWOULDBLOCK, Operation would block");
1513 break;
1515 case WSAEINPROGRESS:
1516 rtl_uString_newFromAscii (strError, "WSAEINPROGRESS, Operation now in progress");
1517 break;
1519 case WSAEALREADY:
1520 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation already in progress");
1521 break;
1523 case WSAEINTR:
1524 rtl_uString_newFromAscii (strError, "WSAEALREADY, Operation was interrupted");
1525 break;
1527 case WSAEBADF:
1528 rtl_uString_newFromAscii (strError, "WSAEBADF, Bad file number");
1529 break;
1531 case WSAEACCES:
1532 rtl_uString_newFromAscii (strError, "WSAEACCES, Access is denied");
1533 break;
1535 case WSAEFAULT:
1536 rtl_uString_newFromAscii (strError, "WSAEFAULT, Bad memory Addr");
1537 break;
1539 case WSAEINVAL:
1540 rtl_uString_newFromAscii (strError, "WSAEINVAL, The socket has not been bound with bind() or is already connected");
1541 break;
1543 case WSAEMFILE:
1544 rtl_uString_newFromAscii (strError, "WSAEMFILE, No more file descriptors are available");
1545 break;
1547 case WSAETOOMANYREFS:
1548 rtl_uString_newFromAscii (strError, "WSAETOOMANYREFS, Undocumented WinSock error");
1549 break;
1551 case WSAENAMETOOLONG:
1552 rtl_uString_newFromAscii (strError, "WSAENAMETOOLONG, Undocumented WinSock error");
1553 break;
1555 case WSAENOTEMPTY:
1556 rtl_uString_newFromAscii (strError, "WSAENOTEMPTY, Undocumented WinSock error");
1557 break;
1559 case WSAEPROCLIM:
1560 rtl_uString_newFromAscii (strError, "WSAEPROCLIM, Undocumented WinSock error");
1561 break;
1563 case WSAEUSERS:
1564 rtl_uString_newFromAscii (strError, "WSAEUSERS, Undocumented WinSock error");
1565 break;
1567 case WSAEDQUOT:
1568 rtl_uString_newFromAscii (strError, "WSAEDQUOT, Undocumented WinSock error");
1569 break;
1571 case WSAESTALE:
1572 rtl_uString_newFromAscii (strError, "WSAESTALE, Undocumented WinSock error");
1573 break;
1575 case WSAEREMOTE:
1576 rtl_uString_newFromAscii (strError, "WSAEREMOTE, Undocumented WinSock error");
1577 break;
1579 case WSAEDISCON:
1580 rtl_uString_newFromAscii (strError, "WSAEDISCON, Circuit was gracefully terminated");
1581 break;
1583 case WSASYSNOTREADY:
1584 rtl_uString_newFromAscii (strError, "WSASYSNOTREADY, The underlying network subsystem is not ready for network communication");
1585 break;
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");
1589 break;
1591 case WSANOTINITIALISED:
1592 rtl_uString_newFromAscii (strError, "WSANOTINITIALISED, WSAStartup() has not been called");
1593 break;
1595 case WSAHOST_NOT_FOUND:
1596 rtl_uString_newFromAscii (strError, "WSAHOST_NOT_FOUND, Authoritative answer host not found");
1597 break;
1599 case WSATRY_AGAIN:
1600 rtl_uString_newFromAscii (strError, "WSATRY_AGAIN, Non-authoritative answer host not found or SERVERFAIL");
1601 break;
1603 case WSANO_RECOVERY:
1604 rtl_uString_newFromAscii (strError, "WSANO_RECOVERY, Non recoverable errors, FORMERR, REFUSED, NOTIMP");
1605 break;
1607 case WSANO_DATA:
1608 rtl_uString_newFromAscii (strError, "WSANO_DATA or WSANO_ADDRESS, Valid name, no data record of requested type");
1609 break;
1611 default:
1613 sal_Unicode message[128];
1615 wsprintfW(o3tl::toW(message), L"Unknown WinSock Error Number %d", error);
1616 rtl_uString_newFromStr (strError, message);
1619 return;
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)));
1641 if(pSet)
1643 FD_ZERO(&pSet->m_Set);
1646 return pSet;
1649 void SAL_CALL osl_destroySocketSet (oslSocketSet Set)
1651 if(Set)
1652 free(Set);
1655 void SAL_CALL osl_clearSocketSet (oslSocketSet Set)
1657 if (Set)
1658 FD_ZERO(&Set->m_Set);
1661 void SAL_CALL osl_addToSocketSet (
1662 oslSocketSet Set,
1663 oslSocket Socket)
1665 if (Set && Socket)
1666 FD_SET(Socket->m_Socket, &Set->m_Set);
1669 void SAL_CALL osl_removeFromSocketSet (
1670 oslSocketSet Set,
1671 oslSocket Socket)
1673 if (Set && Socket)
1674 FD_CLR(Socket->m_Socket, &Set->m_Set);
1677 sal_Bool SAL_CALL osl_isInSocketSet (
1678 oslSocketSet Set,
1679 oslSocket Socket)
1681 if (Set && Socket)
1682 return (FD_ISSET(Socket->m_Socket, &Set->m_Set) != 0);
1683 else
1684 return false;
1687 sal_Int32 SAL_CALL osl_demultiplexSocketEvents (
1688 oslSocketSet IncomingSet,
1689 oslSocketSet OutgoingSet,
1690 oslSocketSet OutOfBandSet,
1691 const TimeValue* pTimeout)
1693 struct timeval tv;
1695 if(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: */