tdf#154546 skip dispatch when presenter controller is not set
[LibreOffice.git] / sal / osl / unx / socket.cxx
blob535c1727cb1577a0c1f3c651cd95651b84cf3cd3
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.hxx"
26 #include <osl/socket.h>
27 #include <osl/mutex.h>
28 #include <osl/signal.h>
30 #include <rtl/alloc.h>
31 #include <rtl/byteseq.h>
32 #include <rtl/ustring.hxx>
33 #include <assert.h>
34 #include <sal/types.h>
35 #include <sal/log.hxx>
37 #include "sockimpl.hxx"
38 #include "unixerrnostring.hxx"
39 #include <oslsocket.hxx>
41 #include <poll.h>
43 /* defines for shutdown */
44 #define SD_RECEIVE 0
45 #define SD_SEND 1
46 #define SD_BOTH 2
49 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
50 I refrained from using sockaddr_in because of possible further
51 extensions of this socket-interface (IP-NG?).
52 The intention was to hide all Berkeley data-structures from
53 direct access past the osl-interface.
55 The current implementation is internet (IP) centered. All
56 the constructor-functions (osl_create...) take parameters
57 that will probably make sense only in the IP-environment
58 (e.g. because of using the dotted-address-format).
60 If the interface will be extended to host other protocol-
61 families, I expect no externally visible changes in the
62 existing functions. You'll probably need only new
63 constructor-functions who take the different address
64 formats into consideration (maybe a long dotted address
65 or whatever).
68 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
69 /* are the same! I don't like it very much but see no other easy way to */
70 /* conceal the struct sockaddr from the eyes of the user. */
72 #define OSL_INVALID_SOCKET -1
73 #define OSL_SOCKET_ERROR -1
75 /* Buffer size for getnameinfo */
76 #define MAX_HOSTBUFFER_SIZE 2048
78 const unsigned long FamilyMap[]= {
79 AF_INET, /* osl_Socket_FamilyInet */
80 AF_IPX, /* osl_Socket_FamilyIpx */
81 0 /* osl_Socket_FamilyInvalid */
84 static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
86 oslAddrFamily i= oslAddrFamily(0);
88 while(i != osl_Socket_FamilyInvalid)
90 if(FamilyMap[i] == nativeType)
91 return i;
92 i = static_cast<oslAddrFamily>( i + 1 );
95 return i;
98 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
99 #define FAMILY_TO_NATIVE(x) static_cast<short>(FamilyMap[x])
101 const sal_uInt32 ProtocolMap[]= {
102 0, /* osl_Socket_ProtocolIp */
103 NSPROTO_IPX, /* osl_Socket_ProtocolIpx */
104 NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
105 NSPROTO_SPXII, /* osl_Socket_ProtocolSpxII */
106 0 /* osl_Socket_ProtocolInvalid */
109 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
111 const sal_uInt32 TypeMap[]= {
112 SOCK_STREAM, /* osl_Socket_TypeStream */
113 SOCK_DGRAM, /* osl_Socket_TypeDgram */
114 SOCK_RAW, /* osl_Socket_TypeRaw */
115 SOCK_RDM, /* osl_Socket_TypeRdm */
116 SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
117 0 /* osl_Socket_TypeInvalid */
120 static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
122 oslSocketType i= oslSocketType(0);
124 while(i != osl_Socket_TypeInvalid)
126 if(TypeMap[i] == nativeType)
127 return i;
128 i = static_cast<oslSocketType>(i + 1);
131 return i;
134 #define TYPE_TO_NATIVE(x) TypeMap[x]
135 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
137 const sal_uInt32 OptionMap[]= {
138 SO_DEBUG, /* osl_Socket_OptionDebug */
139 SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
140 SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
141 SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
142 SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
143 SO_BROADCAST, /* osl_Socket_OptionBroadcast */
144 SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
145 SO_LINGER, /* osl_Socket_OptionLinger */
146 SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
147 SO_SNDBUF, /* osl_Socket_OptionSndBuf */
148 SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
149 SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
150 SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
151 SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
152 SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
153 SO_ERROR, /* osl_Socket_OptionError */
154 SO_TYPE, /* osl_Socket_OptionType */
155 TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
156 0 /* osl_Socket_OptionInvalid */
159 #define OPTION_TO_NATIVE(x) OptionMap[x]
161 const sal_uInt32 OptionLevelMap[]= {
162 SOL_SOCKET, /* osl_Socket_LevelSocket */
163 IPPROTO_TCP, /* osl_Socket_LevelTcp */
164 0 /* osl_Socket_LevelInvalid */
167 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
169 const sal_uInt32 SocketMsgFlagMap[]= {
170 0, /* osl_Socket_MsgNormal */
171 MSG_OOB, /* osl_Socket_MsgOOB */
172 MSG_PEEK, /* osl_Socket_MsgPeek */
173 MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
174 MSG_MAXIOVLEN, /* osl_Socket_MsgMaxIOVLen */
175 0 /* osl_Socket_MsgInvalid */
178 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
180 const sal_uInt32 SocketDirection[]= {
181 SD_RECEIVE, /* osl_Socket_DirRead */
182 SD_SEND, /* osl_Socket_DirWrite */
183 SD_BOTH, /* osl_Socket_DirReadWrite */
184 0 /* osl_Socket_DirInvalid */
187 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
189 const struct
191 int errcode;
192 oslSocketError error;
193 } SocketError[]= {
194 { 0, osl_Socket_E_None }, /* no error */
195 { ENOTSOCK, osl_Socket_E_NotSocket }, /* Socket operation on non-socket */
196 { EDESTADDRREQ, osl_Socket_E_DestAddrReq }, /* Destination address required */
197 { EMSGSIZE, osl_Socket_E_MsgSize }, /* Message too long */
198 { EPROTOTYPE, osl_Socket_E_Prototype }, /* Protocol wrong type for socket */
199 { ENOPROTOOPT, osl_Socket_E_NoProtocol }, /* Protocol not available */
200 { EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
201 #ifdef ESOCKTNOSUPPORT
202 { ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport }, /* Socket type not supported */
203 #endif
204 { EOPNOTSUPP, osl_Socket_E_OpNotSupport }, /* Operation not supported on socket */
205 { EPFNOSUPPORT, osl_Socket_E_PfNoSupport }, /* Protocol family not supported */
206 { EAFNOSUPPORT, osl_Socket_E_AfNoSupport }, /* Address family not supported by
207 protocol family */
208 { EADDRINUSE, osl_Socket_E_AddrInUse }, /* Address already in use */
209 { EADDRNOTAVAIL, osl_Socket_E_AddrNotAvail }, /* Can't assign requested address */
210 { ENETDOWN, osl_Socket_E_NetDown }, /* Network is down */
211 { ENETUNREACH, osl_Socket_E_NetUnreachable }, /* Network is unreachable */
212 { ENETRESET, osl_Socket_E_NetReset }, /* Network dropped connection because
213 of reset */
214 { ECONNABORTED, osl_Socket_E_ConnAborted }, /* Software caused connection abort */
215 { ECONNRESET, osl_Socket_E_ConnReset }, /* Connection reset by peer */
216 { ENOBUFS, osl_Socket_E_NoBufferSpace }, /* No buffer space available */
217 { EISCONN, osl_Socket_E_IsConnected }, /* Socket is already connected */
218 { ENOTCONN, osl_Socket_E_NotConnected }, /* Socket is not connected */
219 { ESHUTDOWN, osl_Socket_E_Shutdown }, /* Can't send after socket shutdown */
220 #ifdef ETOOMANYREFS
221 { ETOOMANYREFS, osl_Socket_E_TooManyRefs }, /* Too many references: can't splice */
222 #endif
223 { ETIMEDOUT, osl_Socket_E_TimedOut }, /* Connection timed out */
224 { ECONNREFUSED, osl_Socket_E_ConnRefused }, /* Connection refused */
225 { EHOSTDOWN, osl_Socket_E_HostDown }, /* Host is down */
226 { EHOSTUNREACH, osl_Socket_E_HostUnreachable }, /* No route to host */
227 { EWOULDBLOCK, osl_Socket_E_WouldBlock }, /* call would block on non-blocking socket */
228 { EALREADY, osl_Socket_E_Already }, /* operation already in progress */
229 { EINPROGRESS, osl_Socket_E_InProgress }, /* operation now in progress */
230 { EAGAIN, osl_Socket_E_WouldBlock }, /* same as EWOULDBLOCK */
231 { -1, osl_Socket_E_InvalidError }
234 static oslSocketError osl_SocketErrorFromNative(int nativeType)
236 int i = 0;
238 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
239 (SocketError[i].errcode != nativeType)) i++;
241 return SocketError[i].error;
244 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
246 static oslSocketAddr osl_psz_createInetSocketAddr (
247 const char* pszDottedAddr, sal_Int32 Port);
249 static oslHostAddr osl_psz_createHostAddr (
250 const char *pszHostname, const oslSocketAddr Addr);
252 static oslHostAddr osl_psz_createHostAddrByName (
253 const char *pszHostname);
255 static const char* osl_psz_getHostnameOfHostAddr (
256 const oslHostAddr Addr);
258 static oslSocketAddr osl_psz_resolveHostname (
259 const char* pszHostname);
261 static sal_Int32 osl_psz_getServicePort (
262 const char* pszServicename, const char* pszProtocol);
264 static void osl_psz_getLastSocketErrorDescription (
265 oslSocket Socket, char* pBuffer, sal_uInt32 BufferSize);
267 namespace {
269 int convertToMs(TimeValue const * value) {
270 return value->Seconds * 1000 + value->Nanosec / 1000000; //TODO: overflow
275 static oslSocket createSocketImpl()
277 oslSocket pSocket;
279 pSocket = static_cast<oslSocket>(calloc(1, sizeof(struct oslSocketImpl)));
281 pSocket->m_Socket = OSL_INVALID_SOCKET;
282 pSocket->m_nLastError = 0;
283 pSocket->m_nRefCount = 1;
285 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
286 pSocket->m_bIsAccepting = false;
287 #endif
289 return pSocket;
292 static void destroySocketImpl(oslSocket Socket)
294 if ( Socket != nullptr)
295 free(Socket);
298 static oslSocketAddr createSocketAddr()
300 oslSocketAddr pAddr = static_cast<oslSocketAddr>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl )));
301 return pAddr;
304 static oslSocketAddr createSocketAddrWithFamily(
305 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
307 oslSocketAddr pAddr;
309 SAL_WARN_IF( family != osl_Socket_FamilyInet, "sal.osl", "creating socket for non-IP address family" );
311 pAddr = createSocketAddr();
312 switch( family )
314 case osl_Socket_FamilyInet:
316 struct sockaddr_in* pInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
318 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
319 pInetAddr->sin_addr.s_addr = nAddr;
320 pInetAddr->sin_port = static_cast<sal_uInt16>(port&0xffff);
321 break;
323 default:
324 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
326 return pAddr;
329 static oslSocketAddr createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
331 oslSocketAddr pAddr = createSocketAddr();
332 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
333 return pAddr;
336 static void destroySocketAddr( oslSocketAddr addr )
338 free( addr );
341 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
343 oslSocketAddr pAddr = nullptr;
345 /* is it an internet-Addr? */
346 if (Family == osl_Socket_FamilyInet)
348 pAddr = createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
350 else
352 pAddr = createSocketAddrWithFamily( Family , 0 , 0 );
355 return pAddr;
358 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
360 oslSocketAddr pCopy = nullptr;
361 if (Addr)
363 pCopy = createSocketAddr();
365 if (pCopy)
366 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
368 return pCopy;
371 sal_Bool SAL_CALL osl_isEqualSocketAddr (
372 oslSocketAddr Addr1,
373 oslSocketAddr Addr2)
375 struct sockaddr* pAddr1 = nullptr;
376 struct sockaddr* pAddr2 = nullptr;
378 assert(Addr1 && Addr2);
379 pAddr1 = &(Addr1->m_sockaddr);
380 pAddr2 = &(Addr2->m_sockaddr);
382 if (pAddr1 == pAddr2)
384 return true;
387 if (pAddr1->sa_family == pAddr2->sa_family)
389 switch (pAddr1->sa_family)
391 case AF_INET:
393 struct sockaddr_in* pInetAddr1= reinterpret_cast<sockaddr_in*>(pAddr1);
394 struct sockaddr_in* pInetAddr2= reinterpret_cast<sockaddr_in*>(pAddr2);
396 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
397 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
398 (pInetAddr1->sin_port == pInetAddr2->sin_port))
399 return true;
400 [[fallthrough]];
403 default:
405 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
410 return false;
413 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
414 rtl_uString *strDottedAddr,
415 sal_Int32 Port)
417 sal_uInt32 nAddr = OSL_INADDR_NONE;
418 oslSocketAddr pAddr;
420 if (strDottedAddr && strDottedAddr->length)
422 /* Dotted host address for limited broadcast */
423 rtl_String *pDottedAddr = nullptr;
425 rtl_uString2String (
426 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
427 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
429 in_addr buf;
430 if (inet_pton (AF_INET, pDottedAddr->buffer, &buf) == 1) {
431 nAddr = buf.s_addr;
433 rtl_string_release (pDottedAddr);
436 if (nAddr != OSL_INADDR_NONE)
438 /* Limited broadcast */
439 nAddr = ntohl(nAddr);
440 if (IN_CLASSA(nAddr))
442 nAddr &= IN_CLASSA_NET;
443 nAddr |= IN_CLASSA_HOST;
445 else if (IN_CLASSB(nAddr))
447 nAddr &= IN_CLASSB_NET;
448 nAddr |= IN_CLASSB_HOST;
450 else if (IN_CLASSC(nAddr))
452 nAddr &= IN_CLASSC_NET;
453 nAddr |= IN_CLASSC_HOST;
455 else
457 /* No broadcast in class D */
458 return nullptr;
460 nAddr = htonl(nAddr);
463 pAddr = createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
464 return pAddr;
467 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
468 rtl_uString *ustrDottedAddr,
469 sal_Int32 Port)
471 rtl_String* strDottedAddr=nullptr;
472 oslSocketAddr Addr;
473 char* pszDottedAddr=nullptr;
475 if ( ustrDottedAddr != nullptr )
477 rtl_uString2String( &strDottedAddr,
478 rtl_uString_getStr(ustrDottedAddr),
479 rtl_uString_getLength(ustrDottedAddr),
480 RTL_TEXTENCODING_UTF8,
481 OUSTRING_TO_OSTRING_CVTFLAGS);
482 pszDottedAddr = rtl_string_getStr(strDottedAddr);
485 Addr = pszDottedAddr ? osl_psz_createInetSocketAddr(pszDottedAddr, Port) : nullptr;
487 if ( strDottedAddr != nullptr )
489 rtl_string_release(strDottedAddr);
492 return Addr;
495 oslSocketAddr osl_psz_createInetSocketAddr (
496 const char* pszDottedAddr,
497 sal_Int32 Port)
499 oslSocketAddr pAddr = nullptr;
500 in_addr buf;
501 if(inet_pton(AF_INET, pszDottedAddr, &buf) == 1)
503 /* valid dotted addr */
504 pAddr = createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , buf.s_addr );
506 return pAddr;
509 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
511 oslSocketResult res = osl_Socket_Error;
513 SAL_WARN_IF( !pAddr, "sal.osl", "setting address of undefined socket address" );
514 SAL_WARN_IF( !pByteSeq, "sal.osl", "setting undefined address for socket address" );
516 if( pAddr && pByteSeq )
518 struct sockaddr_in * pSystemInetAddr;
520 assert( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
521 assert( pByteSeq->nElements == 4 );
523 pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
524 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
525 res = osl_Socket_Ok;
527 return res;
530 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
532 oslSocketResult res = osl_Socket_Error;
534 SAL_WARN_IF( !pAddr, "sal.osl", "getting address of undefined socket address" );
535 SAL_WARN_IF( !ppByteSeq, "sal.osl", "getting address to undefined address pointer" );
537 if( pAddr && ppByteSeq )
539 struct sockaddr_in * pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
540 rtl_byte_sequence_constructFromArray( ppByteSeq, reinterpret_cast<sal_Int8 *>(&pSystemInetAddr->sin_addr), 4);
541 res = osl_Socket_Ok;
543 return res;
546 /** try to figure out a full-qualified hostname, by adding the current domain
547 as given by the domainname program to the given hostname.
548 This function MUST NOT call gethostbyname since pHostName already points
549 to data returned by gethostname and would be garbled: use gethostname_r
550 instead!
553 namespace {
555 struct oslAddrInfo
557 addrinfo* pAddrInfoList = nullptr;
558 int nError;
560 oslAddrInfo(const char* name, bool isInet = false)
562 addrinfo aHints;
563 memset(&aHints, 0, sizeof(addrinfo));
564 if (isInet)
565 aHints.ai_family = AF_INET;
566 aHints.ai_flags = AI_CANONNAME;
568 nError = getaddrinfo(name, nullptr, &aHints, &pAddrInfoList);
571 ~oslAddrInfo()
573 if (nError == 0)
574 freeaddrinfo(pAddrInfoList);
577 const char* getHostName() const
579 assert(pAddrInfoList);
580 return pAddrInfoList->ai_canonname;
585 static bool isFullQualifiedDomainName (const char *pHostName)
587 /* a FQDN (aka 'hostname.domain.top_level_domain' )
588 * is a name which contains a dot '.' in it ( would
589 * match as well for 'hostname.' but is good enough
590 * for now )*/
591 return strchr( pHostName, int('.') ) != nullptr;
594 static char* getFullQualifiedDomainName (const char *pHostName)
596 char *pFullQualifiedName = nullptr;
598 if (isFullQualifiedDomainName(pHostName))
600 pFullQualifiedName = strdup(pHostName);
602 else
604 oslAddrInfo aAddrInfo(pHostName);
605 if (aAddrInfo.nError == 0)
606 pFullQualifiedName = strdup(aAddrInfo.getHostName());
609 return pFullQualifiedName;
612 struct oslHostAddrImpl
614 char *pHostName;
615 oslSocketAddr pSockAddr;
618 static oslHostAddr addrinfoToHostAddr (const addrinfo* ai)
620 if (!ai || !ai->ai_canonname || !ai->ai_addr)
621 return nullptr;
623 char* cn = getFullQualifiedDomainName(ai->ai_canonname);
624 SAL_WARN_IF( !cn, "sal.osl", "couldn't get full qualified domain name" );
625 if (cn == nullptr)
626 return nullptr;
628 oslSocketAddr pSockAddr = createSocketAddr();
629 SAL_WARN_IF( !pSockAddr, "sal.osl", "insufficient memory" );
630 if (pSockAddr == nullptr)
632 free(cn);
633 return nullptr;
636 if (ai->ai_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
638 memcpy (
639 &(pSockAddr->m_sockaddr),
640 ai->ai_addr,
641 ai->ai_addrlen);
643 else
645 /* unknown address family */
646 /* future extensions for new families might be implemented here */
648 SAL_WARN( "sal.osl", "unknown address family" );
650 destroySocketAddr( pSockAddr );
651 free (cn);
652 return nullptr;
655 oslHostAddr pAddr = static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
656 SAL_WARN_IF( !pAddr, "sal.osl", "allocation error" );
657 if (pAddr == nullptr)
659 destroySocketAddr( pSockAddr );
660 free (cn);
661 return nullptr;
664 pAddr->pHostName= cn;
665 pAddr->pSockAddr= pSockAddr;
667 return pAddr;
670 oslHostAddr SAL_CALL osl_createHostAddr (
671 rtl_uString *ustrHostname,
672 const oslSocketAddr Addr)
674 oslHostAddr HostAddr;
675 rtl_String* strHostname=nullptr;
676 char* pszHostName=nullptr;
678 if ( ustrHostname != nullptr )
680 rtl_uString2String( &strHostname,
681 rtl_uString_getStr(ustrHostname),
682 rtl_uString_getLength(ustrHostname),
683 RTL_TEXTENCODING_UTF8,
684 OUSTRING_TO_OSTRING_CVTFLAGS );
685 pszHostName = rtl_string_getStr(strHostname);
688 HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
690 if ( strHostname != nullptr )
692 rtl_string_release(strHostname);
695 return HostAddr;
698 oslHostAddr osl_psz_createHostAddr (
699 const char *pszHostname,
700 const oslSocketAddr pAddr)
702 oslHostAddr pHostAddr;
703 char *cn;
705 SAL_WARN_IF( !pszHostname, "sal.osl", "undefined hostname" );
706 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
707 if ((pszHostname == nullptr) || (pAddr == nullptr))
708 return nullptr;
710 cn = strdup(pszHostname);
711 SAL_WARN_IF( !cn, "sal.osl", "insufficient memory" );
712 if (cn == nullptr)
713 return nullptr;
715 pHostAddr= static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
716 SAL_WARN_IF( !pHostAddr, "sal.osl", "allocation error" );
717 if (pHostAddr == nullptr)
719 free (cn);
720 return nullptr;
723 pHostAddr->pHostName= cn;
724 pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
726 return pHostAddr;
729 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
731 oslHostAddr HostAddr;
732 rtl_String* strHostname=nullptr;
733 char* pszHostName=nullptr;
735 if ( ustrHostname != nullptr )
737 rtl_uString2String( &strHostname,
738 rtl_uString_getStr(ustrHostname),
739 rtl_uString_getLength(ustrHostname),
740 RTL_TEXTENCODING_UTF8,
741 OUSTRING_TO_OSTRING_CVTFLAGS );
742 pszHostName=rtl_string_getStr(strHostname);
745 HostAddr = osl_psz_createHostAddrByName(pszHostName);
747 if ( strHostname != nullptr )
749 rtl_string_release(strHostname);
752 return HostAddr;
755 oslHostAddr osl_psz_createHostAddrByName (const char *pszHostname)
757 oslAddrInfo aAddrInfo(pszHostname, /* isInet */ true);
759 return addrinfoToHostAddr (aAddrInfo.pAddrInfoList);
762 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
764 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
766 if (pAddr == nullptr)
767 return nullptr;
769 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
771 const struct sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
772 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
773 return nullptr;
775 char host[MAX_HOSTBUFFER_SIZE];
776 int res = getnameinfo(&pAddr->m_sockaddr, sizeof(struct sockaddr_in),
777 host, sizeof(host), nullptr, 0, NI_NAMEREQD);
778 if (res != 0)
779 return nullptr;
781 char *cn = getFullQualifiedDomainName(host);
782 SAL_WARN_IF( !cn, "sal.osl", "couldn't get full qualified domain name" );
783 if (cn == nullptr)
784 return nullptr;
786 oslSocketAddr pSockAddr = createSocketAddr();
787 SAL_WARN_IF( !pSockAddr, "sal.osl", "insufficient memory" );
788 if (pSockAddr == nullptr)
790 free(cn);
791 return nullptr;
794 memcpy(&pSockAddr->m_sockaddr, &pAddr->m_sockaddr, sizeof(pAddr->m_sockaddr));
796 oslHostAddr pHostAddr = static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
797 SAL_WARN_IF( !pAddr, "sal.osl", "allocation error" );
798 if (pHostAddr == nullptr)
800 destroySocketAddr(pSockAddr);
801 free(cn);
802 return nullptr;
805 pHostAddr->pHostName = cn;
806 pHostAddr->pSockAddr = pSockAddr;
808 return pHostAddr;
811 return nullptr;
814 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
816 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
818 if (pAddr)
819 return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
820 return nullptr;
823 void SAL_CALL osl_getHostnameOfHostAddr (
824 const oslHostAddr Addr,
825 rtl_uString **ustrHostname)
827 const char* pHostname = osl_psz_getHostnameOfHostAddr(Addr);
829 rtl_uString_newFromAscii (ustrHostname, pHostname);
832 const char* osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
834 if (pAddr)
835 return pAddr->pHostName;
836 return nullptr;
839 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
841 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
843 if (pAddr)
844 return pAddr->pSockAddr;
845 return nullptr;
848 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
850 if (pAddr)
852 if (pAddr->pHostName)
853 free (pAddr->pHostName);
854 if (pAddr->pSockAddr)
855 osl_destroySocketAddr (pAddr->pSockAddr);
856 free (pAddr);
860 namespace
862 oslSocketResult lcl_getLocalHostname(rtl_uString **ustrLocalHostname, bool bUseFQDN)
864 static auto const init = [bUseFQDN]() -> std::pair<oslSocketResult, OUString> {
865 char LocalHostname[256] = "";
867 #ifdef SYSV
868 struct utsname uts;
870 if (uname(&uts) < 0)
871 return {osl_Socket_Error, OUString()};
873 if ((strlen(uts.nodename) + 1) > nBufLen)
874 return {osl_Socket_Error, OUString()};
876 strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
877 #else /* BSD compatible */
878 if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
879 return {osl_Socket_Error, OUString()};
880 #endif /* SYSV */
881 LocalHostname[sizeof(LocalHostname)-1] = 0;
883 /* check if we have an FQDN */
884 if (bUseFQDN && strchr(LocalHostname, '.') == nullptr)
886 oslHostAddr Addr;
888 /* no, determine it via dns */
889 Addr = osl_psz_createHostAddrByName(LocalHostname);
891 const char *pStr;
892 if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != nullptr)
894 strncpy(LocalHostname, pStr, sizeof( LocalHostname ));
895 LocalHostname[sizeof(LocalHostname)-1] = 0;
897 osl_destroyHostAddr(Addr);
900 if (LocalHostname[0] != '\0')
902 return {osl_Socket_Ok, OUString::createFromAscii(LocalHostname)};
905 return {osl_Socket_Error, OUString()};
906 }();
908 rtl_uString_assign(ustrLocalHostname,init.second.pData);
910 return init.first;
914 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
916 return lcl_getLocalHostname(ustrLocalHostname, false);
919 oslSocketResult osl_getLocalHostnameFQDN(rtl_uString **ustrLocalHostname)
921 return lcl_getLocalHostname(ustrLocalHostname, true);
924 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
926 oslSocketAddr Addr;
927 rtl_String* strHostname=nullptr;
928 char* pszHostName=nullptr;
930 if ( ustrHostname != nullptr )
932 rtl_uString2String( &strHostname,
933 rtl_uString_getStr(ustrHostname),
934 rtl_uString_getLength(ustrHostname),
935 RTL_TEXTENCODING_UTF8,
936 OUSTRING_TO_OSTRING_CVTFLAGS );
937 pszHostName = rtl_string_getStr(strHostname);
940 Addr = osl_psz_resolveHostname(pszHostName);
942 if ( strHostname != nullptr )
944 rtl_string_release(strHostname);
947 return Addr;
950 oslSocketAddr osl_psz_resolveHostname(const char* pszHostname)
952 struct oslHostAddrImpl *pAddr = osl_psz_createHostAddrByName(pszHostname);
954 if (pAddr)
956 oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
958 osl_destroyHostAddr(pAddr);
960 return SockAddr;
963 return nullptr;
966 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
968 sal_Int32 nPort;
969 rtl_String* strServicename=nullptr;
970 rtl_String* strProtocol=nullptr;
971 char* pszServiceName=nullptr;
972 char* pszProtocol=nullptr;
974 if ( ustrServicename != nullptr )
976 rtl_uString2String( &strServicename,
977 rtl_uString_getStr(ustrServicename),
978 rtl_uString_getLength(ustrServicename),
979 RTL_TEXTENCODING_UTF8,
980 OUSTRING_TO_OSTRING_CVTFLAGS );
981 pszServiceName = rtl_string_getStr(strServicename);
984 if ( ustrProtocol != nullptr )
986 rtl_uString2String( &strProtocol,
987 rtl_uString_getStr(ustrProtocol),
988 rtl_uString_getLength(ustrProtocol),
989 RTL_TEXTENCODING_UTF8,
990 OUSTRING_TO_OSTRING_CVTFLAGS );
991 pszProtocol = rtl_string_getStr(strProtocol);
994 nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
996 if ( strServicename != nullptr )
998 rtl_string_release(strServicename);
1001 if ( strProtocol != nullptr )
1003 rtl_string_release(strProtocol);
1006 return nPort;
1009 sal_Int32 osl_psz_getServicePort(const char* pszServicename,
1010 const char* pszProtocol)
1012 struct servent* ps;
1014 ps= getservbyname(pszServicename, pszProtocol);
1016 if (ps != nullptr)
1017 return ntohs(ps->s_port);
1019 return OSL_INVALID_PORT;
1022 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1024 destroySocketAddr( pAddr );
1027 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1029 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1031 if (pAddr)
1032 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1033 return osl_Socket_FamilyInvalid;
1036 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1038 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1040 if( pAddr )
1042 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
1044 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1045 return ntohs(pSystemInetAddr->sin_port);
1047 return OSL_INVALID_PORT;
1050 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1052 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1054 if( pAddr )
1056 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
1057 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1059 pSystemInetAddr->sin_port= htons(static_cast<short>(Port));
1060 return true;
1064 /* this is not a inet-addr => can't set port */
1065 return false;
1068 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1070 oslHostAddr pHostAddr= osl_createHostAddrByAddr(Addr);
1072 if (!pHostAddr)
1074 return osl_Socket_Error;
1077 rtl_uString_newFromAscii(ustrHostname,pHostAddr->pHostName);
1079 osl_destroyHostAddr(pHostAddr);
1081 return osl_Socket_Ok;
1084 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1086 if( !Addr )
1088 return osl_Socket_Error;
1091 struct sockaddr_in* pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&Addr->m_sockaddr);
1093 if (pSystemInetAddr->sin_family != FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1095 return osl_Socket_Error;
1098 char buf[INET_ADDRSTRLEN];
1099 auto const text = inet_ntop(AF_INET, &pSystemInetAddr->sin_addr, buf, INET_ADDRSTRLEN);
1100 assert(text != nullptr);
1101 rtl_uString_newFromAscii(ustrDottedInetAddr,text);
1103 return osl_Socket_Ok;
1107 oslSocket SAL_CALL osl_createSocket(
1108 oslAddrFamily Family,
1109 oslSocketType Type,
1110 oslProtocol Protocol)
1112 oslSocket pSocket;
1114 /* alloc memory */
1115 pSocket= createSocketImpl();
1117 /* create socket */
1118 pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1119 TYPE_TO_NATIVE(Type),
1120 PROTOCOL_TO_NATIVE(Protocol));
1122 /* creation failed => free memory */
1123 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1125 int nErrno = errno;
1126 SAL_WARN( "sal.osl", "socket creation failed: " << UnixErrnoString(nErrno) );
1128 destroySocketImpl(pSocket);
1129 pSocket= nullptr;
1131 else
1133 sal_Int32 nFlags=0;
1134 /* set close-on-exec flag */
1135 if ((nFlags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1137 nFlags |= FD_CLOEXEC;
1138 if (fcntl(pSocket->m_Socket, F_SETFD, nFlags) == -1)
1140 pSocket->m_nLastError=errno;
1141 int nErrno = errno;
1142 SAL_WARN( "sal.osl", "failed changing socket flags: " << UnixErrnoString(nErrno) );
1145 else
1147 pSocket->m_nLastError=errno;
1151 return pSocket;
1154 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1156 osl_atomic_increment(&(pSocket->m_nRefCount));
1159 void SAL_CALL osl_releaseSocket(oslSocket pSocket)
1161 if (pSocket && osl_atomic_decrement(&(pSocket->m_nRefCount)) == 0)
1163 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1164 if (pSocket->m_bIsAccepting)
1166 SAL_WARN( "sal.osl", "attempt to destroy socket while accepting" );
1167 return;
1169 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1170 osl_closeSocket(pSocket);
1171 destroySocketImpl(pSocket);
1175 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1177 /* socket already invalid */
1178 if (!pSocket)
1179 return;
1181 pSocket->m_nLastError=0;
1182 sal_Int32 nFD = pSocket->m_Socket;
1184 if (nFD == OSL_INVALID_SOCKET)
1185 return;
1187 pSocket->m_Socket = OSL_INVALID_SOCKET;
1189 sal_Int32 nRet=0;
1190 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1191 pSocket->m_bIsInShutdown = true;
1193 if (pSocket->m_bIsAccepting)
1195 union {
1196 struct sockaddr aSockAddr;
1197 struct sockaddr_in aSockAddrIn;
1198 } s;
1199 socklen_t nSockLen = sizeof(s.aSockAddr);
1201 nRet = getsockname(nFD, &s.aSockAddr, &nSockLen);
1202 if (nRet < 0)
1204 int nErrno = errno;
1205 SAL_WARN( "sal.osl", "getsockname call failed: " << UnixErrnoString(nErrno) );
1208 if (s.aSockAddr.sa_family == AF_INET)
1210 if (s.aSockAddrIn.sin_addr.s_addr == htonl(INADDR_ANY))
1212 s.aSockAddrIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1215 int nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1216 if (nConnFD < 0)
1218 int nErrno = errno;
1219 SAL_WARN( "sal.osl", "socket call failed: " << UnixErrnoString(nErrno) );
1221 else
1223 nRet = connect(nConnFD, &s.aSockAddr, sizeof(s.aSockAddr));
1224 if (nRet < 0)
1226 int nErrno = errno;
1227 SAL_WARN( "sal.osl", "connect call failed: " << UnixErrnoString(nErrno) );
1229 close(nConnFD);
1232 pSocket->m_bIsAccepting = false;
1234 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1236 nRet=close(nFD);
1237 if (nRet != 0)
1239 pSocket->m_nLastError=errno;
1240 int nErrno = errno;
1241 SAL_WARN( "sal.osl", "closeSocket close failed: " << UnixErrnoString(nErrno) );
1244 pSocket->m_Socket = OSL_INVALID_SOCKET;
1247 /* Note from function creator: I rely on the fact that oslSocketAddr and struct sockaddr
1248 are the same! I don't like it very much but see no other easy way to conceal
1249 the struct sockaddr from the eyes of the user. */
1250 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1252 socklen_t AddrLen;
1253 struct sockaddr Addr;
1254 oslSocketAddr pAddr;
1256 if (pSocket == nullptr) /* ENOTSOCK */
1257 return nullptr;
1259 AddrLen= sizeof(struct sockaddr);
1261 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1262 return nullptr;
1264 pAddr = createSocketAddrFromSystem( &Addr );
1265 return pAddr;
1268 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1270 socklen_t AddrLen;
1271 struct sockaddr Addr;
1273 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1274 if ( pSocket == nullptr )
1276 return nullptr;
1279 pSocket->m_nLastError=0;
1280 AddrLen= sizeof(struct sockaddr);
1282 if(getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1284 pSocket->m_nLastError=errno;
1285 return nullptr;
1287 return createSocketAddrFromSystem( &Addr );
1290 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
1291 oslSocketAddr pAddr)
1293 int nRet;
1295 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1296 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1297 if ( pSocket == nullptr || pAddr == nullptr )
1299 return false;
1302 pSocket->m_nLastError=0;
1304 nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1306 if ( nRet == OSL_SOCKET_ERROR)
1308 pSocket->m_nLastError=errno;
1309 return false;
1312 return true;
1315 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
1316 sal_Int32 MaxPendingConnections)
1318 int nRet;
1320 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1321 if ( pSocket == nullptr )
1323 return false;
1326 pSocket->m_nLastError=0;
1328 nRet = listen(pSocket->m_Socket,
1329 MaxPendingConnections == -1 ?
1330 SOMAXCONN :
1331 MaxPendingConnections);
1332 if ( nRet == OSL_SOCKET_ERROR)
1334 pSocket->m_nLastError=errno;
1335 return false;
1338 return true;
1341 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
1342 oslSocketAddr pAddr,
1343 const TimeValue* pTimeout)
1345 int ReadyHandles;
1347 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1349 if ( pSocket == nullptr )
1351 return osl_Socket_Error;
1354 pSocket->m_nLastError=0;
1356 if (osl_isNonBlockingMode(pSocket))
1358 if (connect(pSocket->m_Socket,
1359 &(pAddr->m_sockaddr),
1360 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1361 return osl_Socket_Ok;
1363 if (errno == EWOULDBLOCK || errno == EINPROGRESS)
1365 pSocket->m_nLastError=EINPROGRESS;
1366 return osl_Socket_InProgress;
1369 pSocket->m_nLastError=errno;
1370 int nErrno = errno;
1371 SAL_WARN( "sal.osl", "connection failed: " << UnixErrnoString(nErrno) );
1372 return osl_Socket_Error;
1375 /* set socket temporarily to non-blocking */
1376 if( !osl_enableNonBlockingMode(pSocket, true) )
1377 SAL_WARN( "sal.osl", "failed to enable non-blocking mode" );
1379 /* initiate connect */
1380 if(connect(pSocket->m_Socket,
1381 &(pAddr->m_sockaddr),
1382 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1384 /* immediate connection */
1385 osl_enableNonBlockingMode(pSocket, false);
1387 return osl_Socket_Ok;
1390 /* really an error or just delayed? */
1391 if (errno != EINPROGRESS)
1393 pSocket->m_nLastError=errno;
1394 int nErrno = errno;
1395 SAL_WARN( "sal.osl", "connection failed: " << UnixErrnoString(nErrno) );
1397 osl_enableNonBlockingMode(pSocket, false);
1398 return osl_Socket_Error;
1401 /* prepare poll set for socket */
1402 pollfd Set = {pSocket->m_Socket, POLLPRI | POLLOUT, 0};
1404 /* poll */
1405 ReadyHandles= poll(&Set, 1,
1406 pTimeout ? convertToMs(pTimeout) : -1);
1408 if (ReadyHandles > 0) /* connected */
1410 if ( (Set.revents & POLLOUT) != 0 )
1412 int nErrorCode = 0;
1413 socklen_t nErrorSize = sizeof( nErrorCode );
1415 int nSockOpt;
1417 nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
1418 &nErrorCode, &nErrorSize );
1419 if ( (nSockOpt == 0) && (nErrorCode == 0))
1421 osl_enableNonBlockingMode(pSocket, false);
1422 return osl_Socket_Ok;
1424 else
1426 pSocket->m_nLastError = (nSockOpt == 0) ? nErrorCode : errno;
1427 return osl_Socket_Error;
1430 else
1432 return osl_Socket_Error;
1435 else if (ReadyHandles < 0) /* error */
1437 if (errno == EBADF) /* most probably interrupted by close() */
1439 /* do not access pSockImpl because it is about to be or */
1440 /* already destroyed */
1441 return osl_Socket_Interrupted;
1443 pSocket->m_nLastError=errno;
1444 return osl_Socket_Error;
1446 else /* timeout */
1448 pSocket->m_nLastError=errno;
1449 return osl_Socket_TimedOut;
1453 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
1454 oslSocketAddr* ppAddr)
1456 struct sockaddr Addr;
1457 int Connection, Flags;
1458 oslSocket pConnectionSockImpl;
1460 socklen_t AddrLen = sizeof(struct sockaddr);
1461 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1462 if ( pSocket == nullptr )
1464 return nullptr;
1467 pSocket->m_nLastError=0;
1468 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1469 pSocket->m_bIsAccepting = true;
1470 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1472 if( ppAddr && *ppAddr )
1474 osl_destroySocketAddr( *ppAddr );
1475 *ppAddr = nullptr;
1478 /* prevent Linux EINTR behaviour */
1481 Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
1482 } while (Connection == -1 && errno == EINTR);
1484 /* accept failed? */
1485 if( Connection == OSL_SOCKET_ERROR )
1487 pSocket->m_nLastError=errno;
1488 int nErrno = errno;
1489 SAL_WARN( "sal.osl", "accept connection failed: " << UnixErrnoString(nErrno) );
1491 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1492 pSocket->m_bIsAccepting = false;
1493 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1494 return nullptr;
1497 assert(AddrLen == sizeof(struct sockaddr));
1499 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1500 if ( pSocket->m_bIsInShutdown )
1502 close(Connection);
1503 SAL_WARN( "sal.osl", "close while accept" );
1504 return nullptr;
1506 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1508 if(ppAddr)
1510 *ppAddr= createSocketAddrFromSystem(&Addr);
1513 /* alloc memory */
1514 pConnectionSockImpl= createSocketImpl();
1516 /* set close-on-exec flag */
1517 if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
1519 Flags |= FD_CLOEXEC;
1520 if (fcntl(Connection, F_SETFD, Flags) == -1)
1522 pSocket->m_nLastError=errno;
1523 int nErrno = errno;
1524 SAL_WARN( "sal.osl", "fcntl failed: " << UnixErrnoString(nErrno) );
1529 pConnectionSockImpl->m_Socket = Connection;
1530 pConnectionSockImpl->m_nLastError = 0;
1531 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1532 pConnectionSockImpl->m_bIsAccepting = false;
1534 pSocket->m_bIsAccepting = false;
1535 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1536 return pConnectionSockImpl;
1539 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
1540 void* pBuffer,
1541 sal_uInt32 BytesToRead,
1542 oslSocketMsgFlag Flag)
1544 int nRead;
1546 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1547 if ( pSocket == nullptr )
1549 return -1;
1552 pSocket->m_nLastError=0;
1556 nRead = recv(pSocket->m_Socket,
1557 pBuffer,
1558 BytesToRead,
1559 MSG_FLAG_TO_NATIVE(Flag));
1560 } while ( nRead < 0 && errno == EINTR );
1562 if ( nRead < 0 )
1564 pSocket->m_nLastError=errno;
1565 int nErrno = errno;
1566 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: " << UnixErrnoString(nErrno) );
1568 else if ( nRead == 0 )
1570 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: EOL" );
1573 return nRead;
1576 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
1577 oslSocketAddr pSenderAddr,
1578 void* pBuffer,
1579 sal_uInt32 BufferSize,
1580 oslSocketMsgFlag Flag)
1582 int nRead;
1583 struct sockaddr *pSystemSockAddr = nullptr;
1584 socklen_t AddrLen = 0;
1585 if( pSenderAddr )
1587 AddrLen = sizeof( struct sockaddr );
1588 pSystemSockAddr = &(pSenderAddr->m_sockaddr);
1591 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1592 if ( pSocket == nullptr )
1594 return -1;
1597 pSocket->m_nLastError=0;
1599 nRead = recvfrom(pSocket->m_Socket,
1600 pBuffer,
1601 BufferSize,
1602 MSG_FLAG_TO_NATIVE(Flag),
1603 pSystemSockAddr,
1604 &AddrLen);
1606 if ( nRead < 0 )
1608 pSocket->m_nLastError=errno;
1609 int nErrno = errno;
1610 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: " << UnixErrnoString(nErrno) );
1612 else if ( nRead == 0 )
1614 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: EOL" );
1617 return nRead;
1620 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
1621 const void* pBuffer,
1622 sal_uInt32 BytesToSend,
1623 oslSocketMsgFlag Flag)
1625 int nWritten;
1627 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1628 if ( pSocket == nullptr )
1630 return -1;
1633 pSocket->m_nLastError=0;
1637 nWritten = send(pSocket->m_Socket,
1638 pBuffer,
1639 BytesToSend,
1640 MSG_FLAG_TO_NATIVE(Flag));
1641 } while ( nWritten < 0 && errno == EINTR );
1643 if ( nWritten < 0 )
1645 pSocket->m_nLastError=errno;
1646 int nErrno = errno;
1647 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: " << UnixErrnoString(nErrno) );
1649 else if ( nWritten == 0 )
1651 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: EOL" );
1654 return nWritten;
1657 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
1658 oslSocketAddr ReceiverAddr,
1659 const void* pBuffer,
1660 sal_uInt32 BytesToSend,
1661 oslSocketMsgFlag Flag)
1663 int nWritten;
1665 struct sockaddr *pSystemSockAddr = nullptr;
1666 int AddrLen = 0;
1667 if( ReceiverAddr )
1669 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1670 AddrLen = sizeof( struct sockaddr );
1673 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1674 if ( pSocket == nullptr )
1676 return -1;
1679 pSocket->m_nLastError=0;
1681 /* ReceiverAddr might be 0 when used on a connected socket. */
1682 /* Then sendto should behave like send. */
1684 nWritten = sendto(pSocket->m_Socket,
1685 pBuffer,
1686 BytesToSend,
1687 MSG_FLAG_TO_NATIVE(Flag),
1688 pSystemSockAddr,
1689 AddrLen);
1691 if ( nWritten < 0 )
1693 pSocket->m_nLastError=errno;
1694 int nErrno = errno;
1695 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: " << UnixErrnoString(nErrno) );
1697 else if ( nWritten == 0 )
1699 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: EOL" );
1702 return nWritten;
1705 sal_Int32 SAL_CALL osl_readSocket (
1706 oslSocket pSocket, void *pBuffer, sal_Int32 n )
1708 sal_uInt8 * Ptr = static_cast<sal_uInt8 *>(pBuffer);
1709 sal_uInt32 BytesRead= 0;
1710 sal_uInt32 BytesToRead= n;
1712 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1714 /* loop until all desired bytes were read or an error occurred */
1715 while (BytesToRead > 0)
1717 sal_Int32 RetVal;
1718 RetVal= osl_receiveSocket(pSocket,
1719 Ptr,
1720 BytesToRead,
1721 osl_Socket_MsgNormal);
1723 /* error occurred? */
1724 if(RetVal <= 0)
1726 break;
1729 BytesToRead -= RetVal;
1730 BytesRead += RetVal;
1731 Ptr += RetVal;
1734 return BytesRead;
1737 sal_Int32 SAL_CALL osl_writeSocket(
1738 oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1740 /* loop until all desired bytes were send or an error occurred */
1741 sal_uInt32 BytesSend= 0;
1742 sal_uInt32 BytesToSend= n;
1743 sal_uInt8 const *Ptr = static_cast<sal_uInt8 const *>(pBuffer);
1745 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1747 while (BytesToSend > 0)
1749 sal_Int32 RetVal;
1751 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1753 /* error occurred? */
1754 if(RetVal <= 0)
1756 break;
1759 BytesToSend -= RetVal;
1760 BytesSend += RetVal;
1761 Ptr += RetVal;
1764 return BytesSend;
1767 static bool socket_poll (
1768 oslSocket pSocket,
1769 const TimeValue* pTimeout,
1770 short nEvent)
1772 struct pollfd fds;
1773 int timeout;
1774 int result;
1776 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1777 if (pSocket == nullptr)
1778 return false; /* EINVAL */
1780 pSocket->m_nLastError = 0;
1782 fds.fd = pSocket->m_Socket;
1783 fds.events = nEvent;
1784 fds.revents = 0;
1786 timeout = -1;
1787 if (pTimeout)
1789 timeout = convertToMs(pTimeout);
1792 result = poll (&fds, 1, timeout);
1793 if (result < 0)
1795 pSocket->m_nLastError = errno;
1796 int nErrno = errno;
1797 SAL_WARN( "sal.osl", "poll failed: " << UnixErrnoString(nErrno) );
1798 return false;
1800 if (result == 0)
1802 /* Timeout */
1803 return false;
1806 return ((fds.revents & nEvent) == nEvent);
1809 sal_Bool SAL_CALL osl_isReceiveReady (
1810 oslSocket pSocket, const TimeValue* pTimeout)
1812 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1813 if (pSocket == nullptr)
1815 /* ENOTSOCK */
1816 return false;
1819 return socket_poll (pSocket, pTimeout, POLLIN);
1822 sal_Bool SAL_CALL osl_isSendReady (
1823 oslSocket pSocket, const TimeValue* pTimeout)
1825 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1826 if (pSocket == nullptr)
1828 /* ENOTSOCK */
1829 return false;
1832 return socket_poll (pSocket, pTimeout, POLLOUT);
1835 sal_Bool SAL_CALL osl_isExceptionPending (
1836 oslSocket pSocket, const TimeValue* pTimeout)
1838 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1839 if (pSocket == nullptr)
1841 /* ENOTSOCK */
1842 return false;
1845 return socket_poll (pSocket, pTimeout, POLLPRI);
1848 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
1849 oslSocketDirection Direction)
1851 int nRet;
1853 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1854 if ( pSocket == nullptr )
1856 return false;
1859 pSocket->m_nLastError=0;
1861 nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
1862 if (nRet != 0 )
1864 pSocket->m_nLastError=errno;
1865 int nErrno = errno;
1866 SAL_WARN( "sal.osl", "shutdown failed: " << UnixErrnoString(nErrno) );
1868 return (nRet==0);
1871 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
1872 oslSocketOptionLevel Level,
1873 oslSocketOption Option,
1874 void* pBuffer,
1875 sal_uInt32 BufferLen)
1877 socklen_t nOptLen = static_cast<socklen_t>(BufferLen);
1879 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1880 if ( pSocket == nullptr )
1882 return -1;
1885 pSocket->m_nLastError=0;
1887 if(getsockopt(pSocket->m_Socket,
1888 OPTION_LEVEL_TO_NATIVE(Level),
1889 OPTION_TO_NATIVE(Option),
1890 pBuffer,
1891 &nOptLen) == -1)
1893 pSocket->m_nLastError=errno;
1894 return -1;
1897 return nOptLen;
1900 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
1901 oslSocketOptionLevel Level,
1902 oslSocketOption Option,
1903 void* pBuffer,
1904 sal_uInt32 BufferLen)
1906 int nRet;
1908 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1909 if ( pSocket == nullptr )
1911 return false;
1914 pSocket->m_nLastError=0;
1916 nRet = setsockopt(pSocket->m_Socket,
1917 OPTION_LEVEL_TO_NATIVE(Level),
1918 OPTION_TO_NATIVE(Option),
1919 pBuffer,
1920 BufferLen);
1922 if ( nRet < 0 )
1924 pSocket->m_nLastError=errno;
1925 return false;
1928 return true;
1931 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
1932 sal_Bool On)
1934 int flags;
1935 int nRet;
1937 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1938 if ( pSocket == nullptr )
1940 return false;
1943 pSocket->m_nLastError=0;
1945 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
1947 if (On)
1948 flags |= O_NONBLOCK;
1949 else
1950 flags &= ~(O_NONBLOCK);
1952 nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
1954 if ( nRet < 0 )
1956 pSocket->m_nLastError=errno;
1957 return false;
1960 return true;
1963 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
1965 int flags;
1967 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1968 if ( pSocket == nullptr )
1970 return false;
1973 pSocket->m_nLastError=0;
1975 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
1977 if (flags == -1 || !(flags & O_NONBLOCK))
1978 return false;
1980 return true;
1983 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
1985 int Type=0;
1986 socklen_t TypeSize= sizeof(Type);
1988 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1989 if ( pSocket == nullptr )
1991 return osl_Socket_TypeInvalid;
1994 pSocket->m_nLastError=0;
1996 if(getsockopt(pSocket->m_Socket,
1997 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
1998 OPTION_TO_NATIVE(osl_Socket_OptionType),
1999 &Type,
2000 &TypeSize) == -1)
2002 /* error */
2003 pSocket->m_nLastError=errno;
2004 return osl_Socket_TypeInvalid;
2007 return TYPE_FROM_NATIVE(Type);
2011 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2013 char pszError[1024];
2015 pszError[0] = '\0';
2017 osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2019 rtl_uString_newFromAscii(ustrError,pszError);
2022 void osl_psz_getLastSocketErrorDescription(oslSocket pSocket, char* pBuffer, sal_uInt32 BufferSize)
2024 /* make sure pBuffer will be a zero-terminated string even when strncpy has to cut */
2025 pBuffer[BufferSize-1]= '\0';
2027 if ( pSocket == nullptr )
2029 strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2030 return;
2033 strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2036 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2038 if ( pSocket == nullptr )
2040 return ERROR_FROM_NATIVE(EINVAL);
2043 return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2046 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */