1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
26 #include <osl/socket.h>
27 #include <osl/mutex.h>
28 #include <osl/signal.h>
30 #include <rtl/alloc.h>
31 #include <rtl/byteseq.h>
32 #include <rtl/ustring.hxx>
34 #include <sal/types.h>
35 #include <sal/log.hxx>
37 #include "sockimpl.hxx"
38 #include "unixerrnostring.hxx"
39 #include <oslsocket.hxx>
43 /* defines for shutdown */
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
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
)
92 i
= static_cast<oslAddrFamily
>( i
+ 1 );
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
)
128 i
= static_cast<oslSocketType
>(i
+ 1);
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]
192 oslSocketError error
;
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 */
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
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
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 */
221 { ETOOMANYREFS
, osl_Socket_E_TooManyRefs
}, /* Too many references: can't splice */
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
)
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
);
269 int convertToMs(TimeValue
const * value
) {
270 return value
->Seconds
* 1000 + value
->Nanosec
/ 1000000; //TODO: overflow
275 static oslSocket
createSocketImpl()
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;
292 static void destroySocketImpl(oslSocket Socket
)
294 if ( Socket
!= nullptr)
298 static oslSocketAddr
createSocketAddr()
300 oslSocketAddr pAddr
= static_cast<oslSocketAddr
>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
)));
304 static oslSocketAddr
createSocketAddrWithFamily(
305 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
309 SAL_WARN_IF( family
!= osl_Socket_FamilyInet
, "sal.osl", "creating socket for non-IP address family" );
311 pAddr
= createSocketAddr();
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);
324 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
329 static oslSocketAddr
createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
331 oslSocketAddr pAddr
= createSocketAddr();
332 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( struct sockaddr
) );
336 static void destroySocketAddr( oslSocketAddr 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
) );
352 pAddr
= createSocketAddrWithFamily( Family
, 0 , 0 );
358 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
360 oslSocketAddr pCopy
= nullptr;
363 pCopy
= createSocketAddr();
366 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
371 sal_Bool SAL_CALL
osl_isEqualSocketAddr (
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
)
387 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
389 switch (pAddr1
->sa_family
)
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
))
405 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
413 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
414 rtl_uString
*strDottedAddr
,
417 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
420 if (strDottedAddr
&& strDottedAddr
->length
)
422 /* Dotted host address for limited broadcast */
423 rtl_String
*pDottedAddr
= nullptr;
426 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
427 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
430 if (inet_pton (AF_INET
, pDottedAddr
->buffer
, &buf
) == 1) {
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
;
457 /* No broadcast in class D */
460 nAddr
= htonl(nAddr
);
463 pAddr
= createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
), nAddr
);
467 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
468 rtl_uString
*ustrDottedAddr
,
471 rtl_String
* strDottedAddr
=nullptr;
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
);
495 oslSocketAddr
osl_psz_createInetSocketAddr (
496 const char* pszDottedAddr
,
499 oslSocketAddr pAddr
= nullptr;
501 if(inet_pton(AF_INET
, pszDottedAddr
, &buf
) == 1)
503 /* valid dotted addr */
504 pAddr
= createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
) , buf
.s_addr
);
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 );
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);
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
557 addrinfo
* pAddrInfoList
= nullptr;
560 oslAddrInfo(const char* name
, bool isInet
= false)
563 memset(&aHints
, 0, sizeof(addrinfo
));
565 aHints
.ai_family
= AF_INET
;
566 aHints
.ai_flags
= AI_CANONNAME
;
568 nError
= getaddrinfo(name
, nullptr, &aHints
, &pAddrInfoList
);
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
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
);
604 oslAddrInfo
aAddrInfo(pHostName
);
605 if (aAddrInfo
.nError
== 0)
606 pFullQualifiedName
= strdup(aAddrInfo
.getHostName());
609 return pFullQualifiedName
;
612 struct oslHostAddrImpl
615 oslSocketAddr pSockAddr
;
618 static oslHostAddr
addrinfoToHostAddr (const addrinfo
* ai
)
620 if (!ai
|| !ai
->ai_canonname
|| !ai
->ai_addr
)
623 char* cn
= getFullQualifiedDomainName(ai
->ai_canonname
);
624 SAL_WARN_IF( !cn
, "sal.osl", "couldn't get full qualified domain name" );
628 oslSocketAddr pSockAddr
= createSocketAddr();
629 SAL_WARN_IF( !pSockAddr
, "sal.osl", "insufficient memory" );
630 if (pSockAddr
== nullptr)
636 if (ai
->ai_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
639 &(pSockAddr
->m_sockaddr
),
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
);
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
);
664 pAddr
->pHostName
= cn
;
665 pAddr
->pSockAddr
= pSockAddr
;
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
);
698 oslHostAddr
osl_psz_createHostAddr (
699 const char *pszHostname
,
700 const oslSocketAddr pAddr
)
702 oslHostAddr pHostAddr
;
705 SAL_WARN_IF( !pszHostname
, "sal.osl", "undefined hostname" );
706 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
707 if ((pszHostname
== nullptr) || (pAddr
== nullptr))
710 cn
= strdup(pszHostname
);
711 SAL_WARN_IF( !cn
, "sal.osl", "insufficient memory" );
715 pHostAddr
= static_cast<oslHostAddr
>(malloc(sizeof(struct oslHostAddrImpl
)));
716 SAL_WARN_IF( !pHostAddr
, "sal.osl", "allocation error" );
717 if (pHostAddr
== nullptr)
723 pHostAddr
->pHostName
= cn
;
724 pHostAddr
->pSockAddr
= osl_copySocketAddr( pAddr
);
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
);
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)
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
))
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
);
781 char *cn
= getFullQualifiedDomainName(host
);
782 SAL_WARN_IF( !cn
, "sal.osl", "couldn't get full qualified domain name" );
786 oslSocketAddr pSockAddr
= createSocketAddr();
787 SAL_WARN_IF( !pSockAddr
, "sal.osl", "insufficient memory" );
788 if (pSockAddr
== 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
);
805 pHostAddr
->pHostName
= cn
;
806 pHostAddr
->pSockAddr
= pSockAddr
;
814 oslHostAddr SAL_CALL
osl_copyHostAddr (const oslHostAddr pAddr
)
816 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
819 return osl_psz_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
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
)
835 return pAddr
->pHostName
;
839 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr
)
841 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
844 return pAddr
->pSockAddr
;
848 void SAL_CALL
osl_destroyHostAddr (oslHostAddr pAddr
)
852 if (pAddr
->pHostName
)
853 free (pAddr
->pHostName
);
854 if (pAddr
->pSockAddr
)
855 osl_destroySocketAddr (pAddr
->pSockAddr
);
862 oslSocketResult
lcl_getLocalHostname(rtl_uString
**ustrLocalHostname
, bool bUseFQDN
)
864 static auto const init
= [bUseFQDN
]() -> std::pair
<oslSocketResult
, OUString
> {
865 char LocalHostname
[256] = "";
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()};
881 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
883 /* check if we have an FQDN */
884 if (bUseFQDN
&& strchr(LocalHostname
, '.') == nullptr)
888 /* no, determine it via dns */
889 Addr
= osl_psz_createHostAddrByName(LocalHostname
);
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()};
908 rtl_uString_assign(ustrLocalHostname
,init
.second
.pData
);
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
)
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
);
950 oslSocketAddr
osl_psz_resolveHostname(const char* pszHostname
)
952 struct oslHostAddrImpl
*pAddr
= osl_psz_createHostAddrByName(pszHostname
);
956 oslSocketAddr SockAddr
= osl_copySocketAddr(pAddr
->pSockAddr
);
958 osl_destroyHostAddr(pAddr
);
966 sal_Int32 SAL_CALL
osl_getServicePort(rtl_uString
*ustrServicename
, rtl_uString
*ustrProtocol
)
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
);
1009 sal_Int32
osl_psz_getServicePort(const char* pszServicename
,
1010 const char* pszProtocol
)
1014 ps
= getservbyname(pszServicename
, pszProtocol
);
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" );
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" );
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" );
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
));
1064 /* this is not a inet-addr => can't set port */
1068 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrHostname
)
1070 oslHostAddr pHostAddr
= osl_createHostAddrByAddr(Addr
);
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
)
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
,
1110 oslProtocol Protocol
)
1115 pSocket
= createSocketImpl();
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
)
1126 SAL_WARN( "sal.osl", "socket creation failed: " << UnixErrnoString(nErrno
) );
1128 destroySocketImpl(pSocket
);
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
;
1142 SAL_WARN( "sal.osl", "failed changing socket flags: " << UnixErrnoString(nErrno
) );
1147 pSocket
->m_nLastError
=errno
;
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" );
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 */
1181 pSocket
->m_nLastError
=0;
1182 sal_Int32 nFD
= pSocket
->m_Socket
;
1184 if (nFD
== OSL_INVALID_SOCKET
)
1187 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1190 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1191 pSocket
->m_bIsInShutdown
= true;
1193 if (pSocket
->m_bIsAccepting
)
1196 struct sockaddr aSockAddr
;
1197 struct sockaddr_in aSockAddrIn
;
1199 socklen_t nSockLen
= sizeof(s
.aSockAddr
);
1201 nRet
= getsockname(nFD
, &s
.aSockAddr
, &nSockLen
);
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);
1219 SAL_WARN( "sal.osl", "socket call failed: " << UnixErrnoString(nErrno
) );
1223 nRet
= connect(nConnFD
, &s
.aSockAddr
, sizeof(s
.aSockAddr
));
1227 SAL_WARN( "sal.osl", "connect call failed: " << UnixErrnoString(nErrno
) );
1232 pSocket
->m_bIsAccepting
= false;
1234 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1239 pSocket
->m_nLastError
=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
)
1253 struct sockaddr Addr
;
1254 oslSocketAddr pAddr
;
1256 if (pSocket
== nullptr) /* ENOTSOCK */
1259 AddrLen
= sizeof(struct sockaddr
);
1261 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1264 pAddr
= createSocketAddrFromSystem( &Addr
);
1268 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1271 struct sockaddr Addr
;
1273 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1274 if ( pSocket
== 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
;
1287 return createSocketAddrFromSystem( &Addr
);
1290 sal_Bool SAL_CALL
osl_bindAddrToSocket(oslSocket pSocket
,
1291 oslSocketAddr pAddr
)
1295 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1296 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
1297 if ( pSocket
== nullptr || pAddr
== nullptr )
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
;
1315 sal_Bool SAL_CALL
osl_listenOnSocket(oslSocket pSocket
,
1316 sal_Int32 MaxPendingConnections
)
1320 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1321 if ( pSocket
== nullptr )
1326 pSocket
->m_nLastError
=0;
1328 nRet
= listen(pSocket
->m_Socket
,
1329 MaxPendingConnections
== -1 ?
1331 MaxPendingConnections
);
1332 if ( nRet
== OSL_SOCKET_ERROR
)
1334 pSocket
->m_nLastError
=errno
;
1341 oslSocketResult SAL_CALL
osl_connectSocketTo(oslSocket pSocket
,
1342 oslSocketAddr pAddr
,
1343 const TimeValue
* pTimeout
)
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
;
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
;
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};
1405 ReadyHandles
= poll(&Set
, 1,
1406 pTimeout
? convertToMs(pTimeout
) : -1);
1408 if (ReadyHandles
> 0) /* connected */
1410 if ( (Set
.revents
& POLLOUT
) != 0 )
1413 socklen_t nErrorSize
= sizeof( nErrorCode
);
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
;
1426 pSocket
->m_nLastError
= (nSockOpt
== 0) ? nErrorCode
: errno
;
1427 return osl_Socket_Error
;
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
;
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 )
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
);
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
;
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 */
1497 assert(AddrLen
== sizeof(struct sockaddr
));
1499 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1500 if ( pSocket
->m_bIsInShutdown
)
1503 SAL_WARN( "sal.osl", "close while accept" );
1506 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1510 *ppAddr
= createSocketAddrFromSystem(&Addr
);
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
;
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
,
1541 sal_uInt32 BytesToRead
,
1542 oslSocketMsgFlag Flag
)
1546 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1547 if ( pSocket
== nullptr )
1552 pSocket
->m_nLastError
=0;
1556 nRead
= recv(pSocket
->m_Socket
,
1559 MSG_FLAG_TO_NATIVE(Flag
));
1560 } while ( nRead
< 0 && errno
== EINTR
);
1564 pSocket
->m_nLastError
=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" );
1576 sal_Int32 SAL_CALL
osl_receiveFromSocket(oslSocket pSocket
,
1577 oslSocketAddr pSenderAddr
,
1579 sal_uInt32 BufferSize
,
1580 oslSocketMsgFlag Flag
)
1583 struct sockaddr
*pSystemSockAddr
= nullptr;
1584 socklen_t AddrLen
= 0;
1587 AddrLen
= sizeof( struct sockaddr
);
1588 pSystemSockAddr
= &(pSenderAddr
->m_sockaddr
);
1591 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1592 if ( pSocket
== nullptr )
1597 pSocket
->m_nLastError
=0;
1599 nRead
= recvfrom(pSocket
->m_Socket
,
1602 MSG_FLAG_TO_NATIVE(Flag
),
1608 pSocket
->m_nLastError
=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" );
1620 sal_Int32 SAL_CALL
osl_sendSocket(oslSocket pSocket
,
1621 const void* pBuffer
,
1622 sal_uInt32 BytesToSend
,
1623 oslSocketMsgFlag Flag
)
1627 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1628 if ( pSocket
== nullptr )
1633 pSocket
->m_nLastError
=0;
1637 nWritten
= send(pSocket
->m_Socket
,
1640 MSG_FLAG_TO_NATIVE(Flag
));
1641 } while ( nWritten
< 0 && errno
== EINTR
);
1645 pSocket
->m_nLastError
=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" );
1657 sal_Int32 SAL_CALL
osl_sendToSocket(oslSocket pSocket
,
1658 oslSocketAddr ReceiverAddr
,
1659 const void* pBuffer
,
1660 sal_uInt32 BytesToSend
,
1661 oslSocketMsgFlag Flag
)
1665 struct sockaddr
*pSystemSockAddr
= nullptr;
1669 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
1670 AddrLen
= sizeof( struct sockaddr
);
1673 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1674 if ( pSocket
== nullptr )
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
,
1687 MSG_FLAG_TO_NATIVE(Flag
),
1693 pSocket
->m_nLastError
=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" );
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)
1718 RetVal
= osl_receiveSocket(pSocket
,
1721 osl_Socket_MsgNormal
);
1723 /* error occurred? */
1729 BytesToRead
-= RetVal
;
1730 BytesRead
+= RetVal
;
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)
1751 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
1753 /* error occurred? */
1759 BytesToSend
-= RetVal
;
1760 BytesSend
+= RetVal
;
1767 static bool socket_poll (
1769 const TimeValue
* pTimeout
,
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
;
1789 timeout
= convertToMs(pTimeout
);
1792 result
= poll (&fds
, 1, timeout
);
1795 pSocket
->m_nLastError
= errno
;
1797 SAL_WARN( "sal.osl", "poll failed: " << UnixErrnoString(nErrno
) );
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)
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)
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)
1845 return socket_poll (pSocket
, pTimeout
, POLLPRI
);
1848 sal_Bool SAL_CALL
osl_shutdownSocket(oslSocket pSocket
,
1849 oslSocketDirection Direction
)
1853 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1854 if ( pSocket
== nullptr )
1859 pSocket
->m_nLastError
=0;
1861 nRet
=shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
));
1864 pSocket
->m_nLastError
=errno
;
1866 SAL_WARN( "sal.osl", "shutdown failed: " << UnixErrnoString(nErrno
) );
1871 sal_Int32 SAL_CALL
osl_getSocketOption(oslSocket pSocket
,
1872 oslSocketOptionLevel Level
,
1873 oslSocketOption Option
,
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 )
1885 pSocket
->m_nLastError
=0;
1887 if(getsockopt(pSocket
->m_Socket
,
1888 OPTION_LEVEL_TO_NATIVE(Level
),
1889 OPTION_TO_NATIVE(Option
),
1893 pSocket
->m_nLastError
=errno
;
1900 sal_Bool SAL_CALL
osl_setSocketOption(oslSocket pSocket
,
1901 oslSocketOptionLevel Level
,
1902 oslSocketOption Option
,
1904 sal_uInt32 BufferLen
)
1908 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1909 if ( pSocket
== nullptr )
1914 pSocket
->m_nLastError
=0;
1916 nRet
= setsockopt(pSocket
->m_Socket
,
1917 OPTION_LEVEL_TO_NATIVE(Level
),
1918 OPTION_TO_NATIVE(Option
),
1924 pSocket
->m_nLastError
=errno
;
1931 sal_Bool SAL_CALL
osl_enableNonBlockingMode(oslSocket pSocket
,
1937 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1938 if ( pSocket
== nullptr )
1943 pSocket
->m_nLastError
=0;
1945 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
1948 flags
|= O_NONBLOCK
;
1950 flags
&= ~(O_NONBLOCK
);
1952 nRet
= fcntl(pSocket
->m_Socket
, F_SETFL
, flags
);
1956 pSocket
->m_nLastError
=errno
;
1963 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
1967 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1968 if ( pSocket
== nullptr )
1973 pSocket
->m_nLastError
=0;
1975 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
1977 if (flags
== -1 || !(flags
& O_NONBLOCK
))
1983 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
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
),
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];
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);
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: */