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>
28 #include <rtl/alloc.h>
29 #include <rtl/byteseq.h>
30 #include <rtl/ustring.hxx>
32 #include <sal/types.h>
33 #include <sal/log.hxx>
35 #include "sockimpl.hxx"
36 #include "unixerrnostring.hxx"
37 #include <oslsocket.hxx>
39 #include <arpa/inet.h>
42 #include <netinet/tcp.h>
46 /* defines for shutdown */
52 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
53 I refrained from using sockaddr_in because of possible further
54 extensions of this socket-interface (IP-NG?).
55 The intention was to hide all Berkeley data-structures from
56 direct access past the osl-interface.
58 The current implementation is internet (IP) centered. All
59 the constructor-functions (osl_create...) take parameters
60 that will probably make sense only in the IP-environment
61 (e.g. because of using the dotted-address-format).
63 If the interface will be extended to host other protocol-
64 families, I expect no externally visible changes in the
65 existing functions. You'll probably need only new
66 constructor-functions who take the different address
67 formats into consideration (maybe a long dotted address
71 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
72 /* are the same! I don't like it very much but see no other easy way to */
73 /* conceal the struct sockaddr from the eyes of the user. */
75 #define OSL_INVALID_SOCKET -1
76 #define OSL_SOCKET_ERROR -1
78 /* Buffer size for getnameinfo */
79 #define MAX_HOSTBUFFER_SIZE 2048
81 const unsigned long FamilyMap
[]= {
82 AF_INET
, /* osl_Socket_FamilyInet */
83 AF_IPX
, /* osl_Socket_FamilyIpx */
84 0 /* osl_Socket_FamilyInvalid */
87 static oslAddrFamily
osl_AddrFamilyFromNative(sal_uInt32 nativeType
)
89 oslAddrFamily i
= oslAddrFamily(0);
91 while(i
!= osl_Socket_FamilyInvalid
)
93 if(FamilyMap
[i
] == nativeType
)
95 i
= static_cast<oslAddrFamily
>( i
+ 1 );
101 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
102 #define FAMILY_TO_NATIVE(x) static_cast<short>(FamilyMap[x])
104 const sal_uInt32 ProtocolMap
[]= {
105 0, /* osl_Socket_ProtocolIp */
106 NSPROTO_IPX
, /* osl_Socket_ProtocolIpx */
107 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
108 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpxII */
109 0 /* osl_Socket_ProtocolInvalid */
112 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
114 const sal_uInt32 TypeMap
[]= {
115 SOCK_STREAM
, /* osl_Socket_TypeStream */
116 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
117 SOCK_RAW
, /* osl_Socket_TypeRaw */
118 SOCK_RDM
, /* osl_Socket_TypeRdm */
119 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
120 0 /* osl_Socket_TypeInvalid */
123 static oslSocketType
osl_SocketTypeFromNative(sal_uInt32 nativeType
)
125 oslSocketType i
= oslSocketType(0);
127 while(i
!= osl_Socket_TypeInvalid
)
129 if(TypeMap
[i
] == nativeType
)
131 i
= static_cast<oslSocketType
>(i
+ 1);
137 #define TYPE_TO_NATIVE(x) TypeMap[x]
138 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
140 const sal_uInt32 OptionMap
[]= {
141 SO_DEBUG
, /* osl_Socket_OptionDebug */
142 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
143 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
144 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
145 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
146 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
147 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
148 SO_LINGER
, /* osl_Socket_OptionLinger */
149 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
150 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
151 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
152 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
153 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
154 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
155 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
156 SO_ERROR
, /* osl_Socket_OptionError */
157 SO_TYPE
, /* osl_Socket_OptionType */
158 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
159 0 /* osl_Socket_OptionInvalid */
162 #define OPTION_TO_NATIVE(x) OptionMap[x]
164 const sal_uInt32 OptionLevelMap
[]= {
165 SOL_SOCKET
, /* osl_Socket_LevelSocket */
166 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
167 0 /* osl_Socket_LevelInvalid */
170 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
172 const sal_uInt32 SocketMsgFlagMap
[]= {
173 0, /* osl_Socket_MsgNormal */
174 MSG_OOB
, /* osl_Socket_MsgOOB */
175 MSG_PEEK
, /* osl_Socket_MsgPeek */
176 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
177 MSG_MAXIOVLEN
, /* osl_Socket_MsgMaxIOVLen */
178 0 /* osl_Socket_MsgInvalid */
181 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
183 const sal_uInt32 SocketDirection
[]= {
184 SD_RECEIVE
, /* osl_Socket_DirRead */
185 SD_SEND
, /* osl_Socket_DirWrite */
186 SD_BOTH
, /* osl_Socket_DirReadWrite */
187 0 /* osl_Socket_DirInvalid */
190 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
195 oslSocketError error
;
197 { 0, osl_Socket_E_None
}, /* no error */
198 { ENOTSOCK
, osl_Socket_E_NotSocket
}, /* Socket operation on non-socket */
199 { EDESTADDRREQ
, osl_Socket_E_DestAddrReq
}, /* Destination address required */
200 { EMSGSIZE
, osl_Socket_E_MsgSize
}, /* Message too long */
201 { EPROTOTYPE
, osl_Socket_E_Prototype
}, /* Protocol wrong type for socket */
202 { ENOPROTOOPT
, osl_Socket_E_NoProtocol
}, /* Protocol not available */
203 { EPROTONOSUPPORT
, osl_Socket_E_ProtocolNoSupport
}, /* Protocol not supported */
204 #ifdef ESOCKTNOSUPPORT
205 { ESOCKTNOSUPPORT
, osl_Socket_E_TypeNoSupport
}, /* Socket type not supported */
207 { EOPNOTSUPP
, osl_Socket_E_OpNotSupport
}, /* Operation not supported on socket */
208 { EPFNOSUPPORT
, osl_Socket_E_PfNoSupport
}, /* Protocol family not supported */
209 { EAFNOSUPPORT
, osl_Socket_E_AfNoSupport
}, /* Address family not supported by
211 { EADDRINUSE
, osl_Socket_E_AddrInUse
}, /* Address already in use */
212 { EADDRNOTAVAIL
, osl_Socket_E_AddrNotAvail
}, /* Can't assign requested address */
213 { ENETDOWN
, osl_Socket_E_NetDown
}, /* Network is down */
214 { ENETUNREACH
, osl_Socket_E_NetUnreachable
}, /* Network is unreachable */
215 { ENETRESET
, osl_Socket_E_NetReset
}, /* Network dropped connection because
217 { ECONNABORTED
, osl_Socket_E_ConnAborted
}, /* Software caused connection abort */
218 { ECONNRESET
, osl_Socket_E_ConnReset
}, /* Connection reset by peer */
219 { ENOBUFS
, osl_Socket_E_NoBufferSpace
}, /* No buffer space available */
220 { EISCONN
, osl_Socket_E_IsConnected
}, /* Socket is already connected */
221 { ENOTCONN
, osl_Socket_E_NotConnected
}, /* Socket is not connected */
222 { ESHUTDOWN
, osl_Socket_E_Shutdown
}, /* Can't send after socket shutdown */
224 { ETOOMANYREFS
, osl_Socket_E_TooManyRefs
}, /* Too many references: can't splice */
226 { ETIMEDOUT
, osl_Socket_E_TimedOut
}, /* Connection timed out */
227 { ECONNREFUSED
, osl_Socket_E_ConnRefused
}, /* Connection refused */
228 { EHOSTDOWN
, osl_Socket_E_HostDown
}, /* Host is down */
229 { EHOSTUNREACH
, osl_Socket_E_HostUnreachable
}, /* No route to host */
230 { EWOULDBLOCK
, osl_Socket_E_WouldBlock
}, /* call would block on non-blocking socket */
231 { EALREADY
, osl_Socket_E_Already
}, /* operation already in progress */
232 { EINPROGRESS
, osl_Socket_E_InProgress
}, /* operation now in progress */
233 { EAGAIN
, osl_Socket_E_WouldBlock
}, /* same as EWOULDBLOCK */
234 { -1, osl_Socket_E_InvalidError
}
237 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
241 while ((SocketError
[i
].error
!= osl_Socket_E_InvalidError
) &&
242 (SocketError
[i
].errcode
!= nativeType
)) i
++;
244 return SocketError
[i
].error
;
247 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
249 static oslSocketAddr
osl_psz_createInetSocketAddr (
250 const char* pszDottedAddr
, sal_Int32 Port
);
252 static oslHostAddr
osl_psz_createHostAddr (
253 const char *pszHostname
, const oslSocketAddr Addr
);
255 static oslHostAddr
osl_psz_createHostAddrByName (
256 const char *pszHostname
);
258 static const char* osl_psz_getHostnameOfHostAddr (
259 const oslHostAddr Addr
);
261 static oslSocketAddr
osl_psz_resolveHostname (
262 const char* pszHostname
);
264 static sal_Int32
osl_psz_getServicePort (
265 const char* pszServicename
, const char* pszProtocol
);
267 static void osl_psz_getLastSocketErrorDescription (
268 oslSocket Socket
, char* pBuffer
, sal_uInt32 BufferSize
);
272 int convertToMs(TimeValue
const * value
) {
273 return value
->Seconds
* 1000 + value
->Nanosec
/ 1000000; //TODO: overflow
278 static oslSocket
createSocketImpl()
282 pSocket
= static_cast<oslSocket
>(calloc(1, sizeof(struct oslSocketImpl
)));
284 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
285 pSocket
->m_nLastError
= 0;
286 pSocket
->m_nRefCount
= 1;
288 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
289 pSocket
->m_bIsAccepting
= false;
295 static void destroySocketImpl(oslSocket Socket
)
297 if ( Socket
!= nullptr)
301 static oslSocketAddr
createSocketAddr()
303 oslSocketAddr pAddr
= static_cast<oslSocketAddr
>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
)));
307 static oslSocketAddr
createSocketAddrWithFamily(
308 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
312 SAL_WARN_IF( family
!= osl_Socket_FamilyInet
, "sal.osl", "creating socket for non-IP address family" );
314 pAddr
= createSocketAddr();
317 case osl_Socket_FamilyInet
:
319 struct sockaddr_in
* pInetAddr
= reinterpret_cast<sockaddr_in
*>(&pAddr
->m_sockaddr
);
321 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
322 pInetAddr
->sin_addr
.s_addr
= nAddr
;
323 pInetAddr
->sin_port
= static_cast<sal_uInt16
>(port
&0xffff);
327 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
332 static oslSocketAddr
createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
334 oslSocketAddr pAddr
= createSocketAddr();
335 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( struct sockaddr
) );
339 static void destroySocketAddr( oslSocketAddr addr
)
344 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
346 oslSocketAddr pAddr
= nullptr;
348 /* is it an internet-Addr? */
349 if (Family
== osl_Socket_FamilyInet
)
351 pAddr
= createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
355 pAddr
= createSocketAddrWithFamily( Family
, 0 , 0 );
361 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
363 oslSocketAddr pCopy
= nullptr;
366 pCopy
= createSocketAddr();
369 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
374 sal_Bool SAL_CALL
osl_isEqualSocketAddr (
378 struct sockaddr
* pAddr1
= nullptr;
379 struct sockaddr
* pAddr2
= nullptr;
381 assert(Addr1
&& Addr2
);
382 pAddr1
= &(Addr1
->m_sockaddr
);
383 pAddr2
= &(Addr2
->m_sockaddr
);
385 if (pAddr1
== pAddr2
)
390 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
392 switch (pAddr1
->sa_family
)
396 struct sockaddr_in
* pInetAddr1
= reinterpret_cast<sockaddr_in
*>(pAddr1
);
397 struct sockaddr_in
* pInetAddr2
= reinterpret_cast<sockaddr_in
*>(pAddr2
);
399 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
400 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
401 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
408 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
416 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
417 rtl_uString
*strDottedAddr
,
420 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
423 if (strDottedAddr
&& strDottedAddr
->length
)
425 /* Dotted host address for limited broadcast */
426 rtl_String
*pDottedAddr
= nullptr;
429 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
430 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
433 if (inet_pton (AF_INET
, pDottedAddr
->buffer
, &buf
) == 1) {
436 rtl_string_release (pDottedAddr
);
439 if (nAddr
!= OSL_INADDR_NONE
)
441 /* Limited broadcast */
442 nAddr
= ntohl(nAddr
);
443 if (IN_CLASSA(nAddr
))
445 nAddr
&= IN_CLASSA_NET
;
446 nAddr
|= IN_CLASSA_HOST
;
448 else if (IN_CLASSB(nAddr
))
450 nAddr
&= IN_CLASSB_NET
;
451 nAddr
|= IN_CLASSB_HOST
;
453 else if (IN_CLASSC(nAddr
))
455 nAddr
&= IN_CLASSC_NET
;
456 nAddr
|= IN_CLASSC_HOST
;
460 /* No broadcast in class D */
463 nAddr
= htonl(nAddr
);
466 pAddr
= createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
), nAddr
);
470 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
471 rtl_uString
*ustrDottedAddr
,
474 rtl_String
* strDottedAddr
=nullptr;
476 char* pszDottedAddr
=nullptr;
478 if ( ustrDottedAddr
!= nullptr )
480 rtl_uString2String( &strDottedAddr
,
481 rtl_uString_getStr(ustrDottedAddr
),
482 rtl_uString_getLength(ustrDottedAddr
),
483 RTL_TEXTENCODING_UTF8
,
484 OUSTRING_TO_OSTRING_CVTFLAGS
);
485 pszDottedAddr
= rtl_string_getStr(strDottedAddr
);
488 Addr
= pszDottedAddr
? osl_psz_createInetSocketAddr(pszDottedAddr
, Port
) : nullptr;
490 if ( strDottedAddr
!= nullptr )
492 rtl_string_release(strDottedAddr
);
498 oslSocketAddr
osl_psz_createInetSocketAddr (
499 const char* pszDottedAddr
,
502 oslSocketAddr pAddr
= nullptr;
504 if(inet_pton(AF_INET
, pszDottedAddr
, &buf
) == 1)
506 /* valid dotted addr */
507 pAddr
= createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
) , buf
.s_addr
);
512 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
514 oslSocketResult res
= osl_Socket_Error
;
516 SAL_WARN_IF( !pAddr
, "sal.osl", "setting address of undefined socket address" );
517 SAL_WARN_IF( !pByteSeq
, "sal.osl", "setting undefined address for socket address" );
519 if( pAddr
&& pByteSeq
)
521 struct sockaddr_in
* pSystemInetAddr
;
523 assert( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
524 assert( pByteSeq
->nElements
== 4 );
526 pSystemInetAddr
= reinterpret_cast<sockaddr_in
*>(&pAddr
->m_sockaddr
);
527 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
533 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
535 oslSocketResult res
= osl_Socket_Error
;
537 SAL_WARN_IF( !pAddr
, "sal.osl", "getting address of undefined socket address" );
538 SAL_WARN_IF( !ppByteSeq
, "sal.osl", "getting address to undefined address pointer" );
540 if( pAddr
&& ppByteSeq
)
542 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<sockaddr_in
*>(&pAddr
->m_sockaddr
);
543 rtl_byte_sequence_constructFromArray( ppByteSeq
, reinterpret_cast<sal_Int8
*>(&pSystemInetAddr
->sin_addr
), 4);
549 /** try to figure out a full-qualified hostname, by adding the current domain
550 as given by the domainname program to the given hostname.
551 This function MUST NOT call gethostbyname since pHostName already points
552 to data returned by gethostname and would be garbled: use gethostname_r
560 addrinfo
* pAddrInfoList
= nullptr;
563 oslAddrInfo(const char* name
, bool isInet
= false)
566 memset(&aHints
, 0, sizeof(addrinfo
));
568 aHints
.ai_family
= AF_INET
;
569 aHints
.ai_flags
= AI_CANONNAME
;
571 nError
= getaddrinfo(name
, nullptr, &aHints
, &pAddrInfoList
);
577 freeaddrinfo(pAddrInfoList
);
580 const char* getHostName() const
582 assert(pAddrInfoList
);
583 return pAddrInfoList
->ai_canonname
;
588 static bool isFullQualifiedDomainName (const char *pHostName
)
590 /* a FQDN (aka 'hostname.domain.top_level_domain' )
591 * is a name which contains a dot '.' in it ( would
592 * match as well for 'hostname.' but is good enough
594 return strchr( pHostName
, int('.') ) != nullptr;
597 static char* getFullQualifiedDomainName (const char *pHostName
)
599 char *pFullQualifiedName
= nullptr;
601 if (isFullQualifiedDomainName(pHostName
))
603 pFullQualifiedName
= strdup(pHostName
);
607 oslAddrInfo
aAddrInfo(pHostName
);
608 if (aAddrInfo
.nError
== 0)
609 pFullQualifiedName
= strdup(aAddrInfo
.getHostName());
612 return pFullQualifiedName
;
615 struct oslHostAddrImpl
618 oslSocketAddr pSockAddr
;
621 static oslHostAddr
addrinfoToHostAddr (const addrinfo
* ai
)
623 if (!ai
|| !ai
->ai_canonname
|| !ai
->ai_addr
)
626 char* cn
= getFullQualifiedDomainName(ai
->ai_canonname
);
627 SAL_WARN_IF( !cn
, "sal.osl", "couldn't get full qualified domain name" );
631 oslSocketAddr pSockAddr
= createSocketAddr();
632 SAL_WARN_IF( !pSockAddr
, "sal.osl", "insufficient memory" );
633 if (pSockAddr
== nullptr)
639 if (ai
->ai_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
642 &(pSockAddr
->m_sockaddr
),
648 /* unknown address family */
649 /* future extensions for new families might be implemented here */
651 SAL_WARN( "sal.osl", "unknown address family" );
653 destroySocketAddr( pSockAddr
);
658 oslHostAddr pAddr
= static_cast<oslHostAddr
>(malloc(sizeof(struct oslHostAddrImpl
)));
659 SAL_WARN_IF( !pAddr
, "sal.osl", "allocation error" );
660 if (pAddr
== nullptr)
662 destroySocketAddr( pSockAddr
);
667 pAddr
->pHostName
= cn
;
668 pAddr
->pSockAddr
= pSockAddr
;
673 oslHostAddr SAL_CALL
osl_createHostAddr (
674 rtl_uString
*ustrHostname
,
675 const oslSocketAddr Addr
)
677 oslHostAddr HostAddr
;
678 rtl_String
* strHostname
=nullptr;
679 char* pszHostName
=nullptr;
681 if ( ustrHostname
!= nullptr )
683 rtl_uString2String( &strHostname
,
684 rtl_uString_getStr(ustrHostname
),
685 rtl_uString_getLength(ustrHostname
),
686 RTL_TEXTENCODING_UTF8
,
687 OUSTRING_TO_OSTRING_CVTFLAGS
);
688 pszHostName
= rtl_string_getStr(strHostname
);
691 HostAddr
= osl_psz_createHostAddr(pszHostName
,Addr
);
693 if ( strHostname
!= nullptr )
695 rtl_string_release(strHostname
);
701 oslHostAddr
osl_psz_createHostAddr (
702 const char *pszHostname
,
703 const oslSocketAddr pAddr
)
705 oslHostAddr pHostAddr
;
708 SAL_WARN_IF( !pszHostname
, "sal.osl", "undefined hostname" );
709 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
710 if ((pszHostname
== nullptr) || (pAddr
== nullptr))
713 cn
= strdup(pszHostname
);
714 SAL_WARN_IF( !cn
, "sal.osl", "insufficient memory" );
718 pHostAddr
= static_cast<oslHostAddr
>(malloc(sizeof(struct oslHostAddrImpl
)));
719 SAL_WARN_IF( !pHostAddr
, "sal.osl", "allocation error" );
720 if (pHostAddr
== nullptr)
726 pHostAddr
->pHostName
= cn
;
727 pHostAddr
->pSockAddr
= osl_copySocketAddr( pAddr
);
732 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*ustrHostname
)
734 oslHostAddr HostAddr
;
735 rtl_String
* strHostname
=nullptr;
736 char* pszHostName
=nullptr;
738 if ( ustrHostname
!= nullptr )
740 rtl_uString2String( &strHostname
,
741 rtl_uString_getStr(ustrHostname
),
742 rtl_uString_getLength(ustrHostname
),
743 RTL_TEXTENCODING_UTF8
,
744 OUSTRING_TO_OSTRING_CVTFLAGS
);
745 pszHostName
=rtl_string_getStr(strHostname
);
748 HostAddr
= osl_psz_createHostAddrByName(pszHostName
);
750 if ( strHostname
!= nullptr )
752 rtl_string_release(strHostname
);
758 oslHostAddr
osl_psz_createHostAddrByName (const char *pszHostname
)
760 oslAddrInfo
aAddrInfo(pszHostname
, /* isInet */ true);
762 return addrinfoToHostAddr (aAddrInfo
.pAddrInfoList
);
765 oslHostAddr SAL_CALL
osl_createHostAddrByAddr (const oslSocketAddr pAddr
)
767 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
769 if (pAddr
== nullptr)
772 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
774 const struct sockaddr_in
*sin
= reinterpret_cast<sockaddr_in
*>(&pAddr
->m_sockaddr
);
775 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
778 char host
[MAX_HOSTBUFFER_SIZE
];
779 int res
= getnameinfo(&pAddr
->m_sockaddr
, sizeof(struct sockaddr_in
),
780 host
, sizeof(host
), nullptr, 0, NI_NAMEREQD
);
784 char *cn
= getFullQualifiedDomainName(host
);
785 SAL_WARN_IF( !cn
, "sal.osl", "couldn't get full qualified domain name" );
789 oslSocketAddr pSockAddr
= createSocketAddr();
790 SAL_WARN_IF( !pSockAddr
, "sal.osl", "insufficient memory" );
791 if (pSockAddr
== nullptr)
797 memcpy(&pSockAddr
->m_sockaddr
, &pAddr
->m_sockaddr
, sizeof(pAddr
->m_sockaddr
));
799 oslHostAddr pHostAddr
= static_cast<oslHostAddr
>(malloc(sizeof(struct oslHostAddrImpl
)));
800 SAL_WARN_IF( !pAddr
, "sal.osl", "allocation error" );
801 if (pHostAddr
== nullptr)
803 destroySocketAddr(pSockAddr
);
808 pHostAddr
->pHostName
= cn
;
809 pHostAddr
->pSockAddr
= pSockAddr
;
817 oslHostAddr SAL_CALL
osl_copyHostAddr (const oslHostAddr pAddr
)
819 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
822 return osl_psz_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
826 void SAL_CALL
osl_getHostnameOfHostAddr (
827 const oslHostAddr Addr
,
828 rtl_uString
**ustrHostname
)
830 const char* pHostname
= osl_psz_getHostnameOfHostAddr(Addr
);
832 rtl_uString_newFromAscii (ustrHostname
, pHostname
);
835 const char* osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr
)
838 return pAddr
->pHostName
;
842 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr
)
844 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
847 return pAddr
->pSockAddr
;
851 void SAL_CALL
osl_destroyHostAddr (oslHostAddr pAddr
)
855 if (pAddr
->pHostName
)
856 free (pAddr
->pHostName
);
857 if (pAddr
->pSockAddr
)
858 osl_destroySocketAddr (pAddr
->pSockAddr
);
865 oslSocketResult
lcl_getLocalHostname(rtl_uString
**ustrLocalHostname
, bool bUseFQDN
)
867 static auto const init
= [bUseFQDN
]() -> std::pair
<oslSocketResult
, OUString
> {
868 char LocalHostname
[256] = "";
874 return {osl_Socket_Error
, OUString()};
876 if ((strlen(uts
.nodename
) + 1) > nBufLen
)
877 return {osl_Socket_Error
, OUString()};
879 strncpy(LocalHostname
, uts
.nodename
, sizeof( LocalHostname
));
880 #else /* BSD compatible */
881 if (gethostname(LocalHostname
, sizeof(LocalHostname
)-1) != 0)
882 return {osl_Socket_Error
, OUString()};
884 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
886 /* check if we have an FQDN */
887 if (bUseFQDN
&& strchr(LocalHostname
, '.') == nullptr)
891 /* no, determine it via dns */
892 Addr
= osl_psz_createHostAddrByName(LocalHostname
);
895 if ((pStr
= osl_psz_getHostnameOfHostAddr(Addr
)) != nullptr)
897 strncpy(LocalHostname
, pStr
, sizeof( LocalHostname
));
898 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
900 osl_destroyHostAddr(Addr
);
903 if (LocalHostname
[0] != '\0')
905 return {osl_Socket_Ok
, OUString::createFromAscii(LocalHostname
)};
908 return {osl_Socket_Error
, OUString()};
911 rtl_uString_assign(ustrLocalHostname
,init
.second
.pData
);
917 oslSocketResult SAL_CALL
osl_getLocalHostname(rtl_uString
**ustrLocalHostname
)
919 return lcl_getLocalHostname(ustrLocalHostname
, false);
922 oslSocketResult
osl_getLocalHostnameFQDN(rtl_uString
**ustrLocalHostname
)
924 return lcl_getLocalHostname(ustrLocalHostname
, true);
927 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
*ustrHostname
)
930 rtl_String
* strHostname
=nullptr;
931 char* pszHostName
=nullptr;
933 if ( ustrHostname
!= nullptr )
935 rtl_uString2String( &strHostname
,
936 rtl_uString_getStr(ustrHostname
),
937 rtl_uString_getLength(ustrHostname
),
938 RTL_TEXTENCODING_UTF8
,
939 OUSTRING_TO_OSTRING_CVTFLAGS
);
940 pszHostName
= rtl_string_getStr(strHostname
);
943 Addr
= osl_psz_resolveHostname(pszHostName
);
945 if ( strHostname
!= nullptr )
947 rtl_string_release(strHostname
);
953 oslSocketAddr
osl_psz_resolveHostname(const char* pszHostname
)
955 struct oslHostAddrImpl
*pAddr
= osl_psz_createHostAddrByName(pszHostname
);
959 oslSocketAddr SockAddr
= osl_copySocketAddr(pAddr
->pSockAddr
);
961 osl_destroyHostAddr(pAddr
);
969 sal_Int32 SAL_CALL
osl_getServicePort(rtl_uString
*ustrServicename
, rtl_uString
*ustrProtocol
)
972 rtl_String
* strServicename
=nullptr;
973 rtl_String
* strProtocol
=nullptr;
974 char* pszServiceName
=nullptr;
975 char* pszProtocol
=nullptr;
977 if ( ustrServicename
!= nullptr )
979 rtl_uString2String( &strServicename
,
980 rtl_uString_getStr(ustrServicename
),
981 rtl_uString_getLength(ustrServicename
),
982 RTL_TEXTENCODING_UTF8
,
983 OUSTRING_TO_OSTRING_CVTFLAGS
);
984 pszServiceName
= rtl_string_getStr(strServicename
);
987 if ( ustrProtocol
!= nullptr )
989 rtl_uString2String( &strProtocol
,
990 rtl_uString_getStr(ustrProtocol
),
991 rtl_uString_getLength(ustrProtocol
),
992 RTL_TEXTENCODING_UTF8
,
993 OUSTRING_TO_OSTRING_CVTFLAGS
);
994 pszProtocol
= rtl_string_getStr(strProtocol
);
997 nPort
= osl_psz_getServicePort(pszServiceName
,pszProtocol
);
999 if ( strServicename
!= nullptr )
1001 rtl_string_release(strServicename
);
1004 if ( strProtocol
!= nullptr )
1006 rtl_string_release(strProtocol
);
1012 sal_Int32
osl_psz_getServicePort(const char* pszServicename
,
1013 const char* pszProtocol
)
1017 ps
= getservbyname(pszServicename
, pszProtocol
);
1020 return ntohs(ps
->s_port
);
1022 return OSL_INVALID_PORT
;
1025 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
1027 destroySocketAddr( pAddr
);
1030 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
1032 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
1035 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1036 return osl_Socket_FamilyInvalid
;
1039 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
1041 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
1045 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<sockaddr_in
*>(&pAddr
->m_sockaddr
);
1047 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1048 return ntohs(pSystemInetAddr
->sin_port
);
1050 return OSL_INVALID_PORT
;
1053 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr
, sal_Int32 Port
)
1055 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
1059 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<sockaddr_in
*>(&pAddr
->m_sockaddr
);
1060 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1062 pSystemInetAddr
->sin_port
= htons(static_cast<short>(Port
));
1067 /* this is not a inet-addr => can't set port */
1071 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrHostname
)
1073 oslHostAddr pHostAddr
= osl_createHostAddrByAddr(Addr
);
1077 return osl_Socket_Error
;
1080 rtl_uString_newFromAscii(ustrHostname
,pHostAddr
->pHostName
);
1082 osl_destroyHostAddr(pHostAddr
);
1084 return osl_Socket_Ok
;
1087 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrDottedInetAddr
)
1091 return osl_Socket_Error
;
1094 struct sockaddr_in
* pSystemInetAddr
= reinterpret_cast<sockaddr_in
*>(&Addr
->m_sockaddr
);
1096 if (pSystemInetAddr
->sin_family
!= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1098 return osl_Socket_Error
;
1101 char buf
[INET_ADDRSTRLEN
];
1102 auto const text
= inet_ntop(AF_INET
, &pSystemInetAddr
->sin_addr
, buf
, INET_ADDRSTRLEN
);
1103 assert(text
!= nullptr);
1104 rtl_uString_newFromAscii(ustrDottedInetAddr
,text
);
1106 return osl_Socket_Ok
;
1110 oslSocket SAL_CALL
osl_createSocket(
1111 oslAddrFamily Family
,
1113 oslProtocol Protocol
)
1118 pSocket
= createSocketImpl();
1121 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
1122 TYPE_TO_NATIVE(Type
),
1123 PROTOCOL_TO_NATIVE(Protocol
));
1125 /* creation failed => free memory */
1126 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
1129 SAL_WARN( "sal.osl", "socket creation failed: " << UnixErrnoString(nErrno
) );
1131 destroySocketImpl(pSocket
);
1137 /* set close-on-exec flag */
1138 if ((nFlags
= fcntl(pSocket
->m_Socket
, F_GETFD
, 0)) != -1)
1140 nFlags
|= FD_CLOEXEC
;
1141 if (fcntl(pSocket
->m_Socket
, F_SETFD
, nFlags
) == -1)
1143 pSocket
->m_nLastError
=errno
;
1145 SAL_WARN( "sal.osl", "failed changing socket flags: " << UnixErrnoString(nErrno
) );
1150 pSocket
->m_nLastError
=errno
;
1157 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
1159 osl_atomic_increment(&(pSocket
->m_nRefCount
));
1162 void SAL_CALL
osl_releaseSocket(oslSocket pSocket
)
1164 if (pSocket
&& osl_atomic_decrement(&(pSocket
->m_nRefCount
)) == 0)
1166 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1167 if (pSocket
->m_bIsAccepting
)
1169 SAL_WARN( "sal.osl", "attempt to destroy socket while accepting" );
1172 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1173 osl_closeSocket(pSocket
);
1174 destroySocketImpl(pSocket
);
1178 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
1180 /* socket already invalid */
1184 pSocket
->m_nLastError
=0;
1185 sal_Int32 nFD
= pSocket
->m_Socket
;
1187 if (nFD
== OSL_INVALID_SOCKET
)
1190 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1193 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1194 pSocket
->m_bIsInShutdown
= true;
1196 if (pSocket
->m_bIsAccepting
)
1199 struct sockaddr aSockAddr
;
1200 struct sockaddr_in aSockAddrIn
;
1202 socklen_t nSockLen
= sizeof(s
.aSockAddr
);
1204 nRet
= getsockname(nFD
, &s
.aSockAddr
, &nSockLen
);
1208 SAL_WARN( "sal.osl", "getsockname call failed: " << UnixErrnoString(nErrno
) );
1211 if (s
.aSockAddr
.sa_family
== AF_INET
)
1213 if (s
.aSockAddrIn
.sin_addr
.s_addr
== htonl(INADDR_ANY
))
1215 s
.aSockAddrIn
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1218 int nConnFD
= socket(AF_INET
, SOCK_STREAM
, 0);
1222 SAL_WARN( "sal.osl", "socket call failed: " << UnixErrnoString(nErrno
) );
1226 nRet
= connect(nConnFD
, &s
.aSockAddr
, sizeof(s
.aSockAddr
));
1230 SAL_WARN( "sal.osl", "connect call failed: " << UnixErrnoString(nErrno
) );
1235 pSocket
->m_bIsAccepting
= false;
1237 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1242 pSocket
->m_nLastError
=errno
;
1244 SAL_WARN( "sal.osl", "closeSocket close failed: " << UnixErrnoString(nErrno
) );
1247 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1250 /* Note from function creator: I rely on the fact that oslSocketAddr and struct sockaddr
1251 are the same! I don't like it very much but see no other easy way to conceal
1252 the struct sockaddr from the eyes of the user. */
1253 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
1256 struct sockaddr Addr
;
1257 oslSocketAddr pAddr
;
1259 if (pSocket
== nullptr) /* ENOTSOCK */
1262 AddrLen
= sizeof(struct sockaddr
);
1264 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1267 pAddr
= createSocketAddrFromSystem( &Addr
);
1271 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1274 struct sockaddr Addr
;
1276 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1277 if ( pSocket
== nullptr )
1282 pSocket
->m_nLastError
=0;
1283 AddrLen
= sizeof(struct sockaddr
);
1285 if(getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1287 pSocket
->m_nLastError
=errno
;
1290 return createSocketAddrFromSystem( &Addr
);
1293 sal_Bool SAL_CALL
osl_bindAddrToSocket(oslSocket pSocket
,
1294 oslSocketAddr pAddr
)
1298 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1299 SAL_WARN_IF( !pAddr
, "sal.osl", "undefined address" );
1300 if ( pSocket
== nullptr || pAddr
== nullptr )
1305 pSocket
->m_nLastError
=0;
1307 nRet
= bind(pSocket
->m_Socket
, &(pAddr
->m_sockaddr
), sizeof(struct sockaddr
));
1309 if ( nRet
== OSL_SOCKET_ERROR
)
1311 pSocket
->m_nLastError
=errno
;
1318 sal_Bool SAL_CALL
osl_listenOnSocket(oslSocket pSocket
,
1319 sal_Int32 MaxPendingConnections
)
1323 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1324 if ( pSocket
== nullptr )
1329 pSocket
->m_nLastError
=0;
1331 nRet
= listen(pSocket
->m_Socket
,
1332 MaxPendingConnections
== -1 ?
1334 MaxPendingConnections
);
1335 if ( nRet
== OSL_SOCKET_ERROR
)
1337 pSocket
->m_nLastError
=errno
;
1344 oslSocketResult SAL_CALL
osl_connectSocketTo(oslSocket pSocket
,
1345 oslSocketAddr pAddr
,
1346 const TimeValue
* pTimeout
)
1350 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1352 if ( pSocket
== nullptr )
1354 return osl_Socket_Error
;
1357 pSocket
->m_nLastError
=0;
1359 if (osl_isNonBlockingMode(pSocket
))
1361 if (connect(pSocket
->m_Socket
,
1362 &(pAddr
->m_sockaddr
),
1363 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1364 return osl_Socket_Ok
;
1366 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
1368 pSocket
->m_nLastError
=EINPROGRESS
;
1369 return osl_Socket_InProgress
;
1372 pSocket
->m_nLastError
=errno
;
1374 SAL_WARN( "sal.osl", "connection failed: " << UnixErrnoString(nErrno
) );
1375 return osl_Socket_Error
;
1378 /* set socket temporarily to non-blocking */
1379 if( !osl_enableNonBlockingMode(pSocket
, true) )
1380 SAL_WARN( "sal.osl", "failed to enable non-blocking mode" );
1382 /* initiate connect */
1383 if(connect(pSocket
->m_Socket
,
1384 &(pAddr
->m_sockaddr
),
1385 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1387 /* immediate connection */
1388 osl_enableNonBlockingMode(pSocket
, false);
1390 return osl_Socket_Ok
;
1393 /* really an error or just delayed? */
1394 if (errno
!= EINPROGRESS
)
1396 pSocket
->m_nLastError
=errno
;
1398 SAL_WARN( "sal.osl", "connection failed: " << UnixErrnoString(nErrno
) );
1400 osl_enableNonBlockingMode(pSocket
, false);
1401 return osl_Socket_Error
;
1404 /* prepare poll set for socket */
1405 pollfd Set
= {pSocket
->m_Socket
, POLLPRI
| POLLOUT
, 0};
1408 ReadyHandles
= poll(&Set
, 1,
1409 pTimeout
? convertToMs(pTimeout
) : -1);
1411 if (ReadyHandles
> 0) /* connected */
1413 if ( (Set
.revents
& POLLOUT
) != 0 )
1416 socklen_t nErrorSize
= sizeof( nErrorCode
);
1420 nSockOpt
= getsockopt ( pSocket
->m_Socket
, SOL_SOCKET
, SO_ERROR
,
1421 &nErrorCode
, &nErrorSize
);
1422 if ( (nSockOpt
== 0) && (nErrorCode
== 0))
1424 osl_enableNonBlockingMode(pSocket
, false);
1425 return osl_Socket_Ok
;
1429 pSocket
->m_nLastError
= (nSockOpt
== 0) ? nErrorCode
: errno
;
1430 return osl_Socket_Error
;
1435 return osl_Socket_Error
;
1438 else if (ReadyHandles
< 0) /* error */
1440 if (errno
== EBADF
) /* most probably interrupted by close() */
1442 /* do not access pSockImpl because it is about to be or */
1443 /* already destroyed */
1444 return osl_Socket_Interrupted
;
1446 pSocket
->m_nLastError
=errno
;
1447 return osl_Socket_Error
;
1451 pSocket
->m_nLastError
=errno
;
1452 return osl_Socket_TimedOut
;
1456 oslSocket SAL_CALL
osl_acceptConnectionOnSocket(oslSocket pSocket
,
1457 oslSocketAddr
* ppAddr
)
1459 struct sockaddr Addr
;
1460 int Connection
, Flags
;
1461 oslSocket pConnectionSockImpl
;
1463 socklen_t AddrLen
= sizeof(struct sockaddr
);
1464 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1465 if ( pSocket
== nullptr )
1470 pSocket
->m_nLastError
=0;
1471 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1472 pSocket
->m_bIsAccepting
= true;
1473 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1475 if( ppAddr
&& *ppAddr
)
1477 osl_destroySocketAddr( *ppAddr
);
1481 /* prevent Linux EINTR behaviour */
1484 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
1485 } while (Connection
== -1 && errno
== EINTR
);
1487 /* accept failed? */
1488 if( Connection
== OSL_SOCKET_ERROR
)
1490 pSocket
->m_nLastError
=errno
;
1492 SAL_WARN( "sal.osl", "accept connection failed: " << UnixErrnoString(nErrno
) );
1494 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1495 pSocket
->m_bIsAccepting
= false;
1496 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1500 assert(AddrLen
== sizeof(struct sockaddr
));
1502 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1503 if ( pSocket
->m_bIsInShutdown
)
1506 SAL_WARN( "sal.osl", "close while accept" );
1509 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1513 *ppAddr
= createSocketAddrFromSystem(&Addr
);
1517 pConnectionSockImpl
= createSocketImpl();
1519 /* set close-on-exec flag */
1520 if ((Flags
= fcntl(Connection
, F_GETFD
, 0)) != -1)
1522 Flags
|= FD_CLOEXEC
;
1523 if (fcntl(Connection
, F_SETFD
, Flags
) == -1)
1525 pSocket
->m_nLastError
=errno
;
1527 SAL_WARN( "sal.osl", "fcntl failed: " << UnixErrnoString(nErrno
) );
1532 pConnectionSockImpl
->m_Socket
= Connection
;
1533 pConnectionSockImpl
->m_nLastError
= 0;
1534 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1535 pConnectionSockImpl
->m_bIsAccepting
= false;
1537 pSocket
->m_bIsAccepting
= false;
1538 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1539 return pConnectionSockImpl
;
1542 sal_Int32 SAL_CALL
osl_receiveSocket(oslSocket pSocket
,
1544 sal_uInt32 BytesToRead
,
1545 oslSocketMsgFlag Flag
)
1549 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1550 if ( pSocket
== nullptr )
1555 pSocket
->m_nLastError
=0;
1559 nRead
= recv(pSocket
->m_Socket
,
1562 MSG_FLAG_TO_NATIVE(Flag
));
1563 } while ( nRead
< 0 && errno
== EINTR
);
1567 pSocket
->m_nLastError
=errno
;
1569 SAL_WARN( "sal.osl", "receive socket [" << nRead
<< "] failed: " << UnixErrnoString(nErrno
) );
1571 else if ( nRead
== 0 )
1573 SAL_WARN( "sal.osl", "receive socket [" << nRead
<< "] failed: EOL" );
1579 sal_Int32 SAL_CALL
osl_receiveFromSocket(oslSocket pSocket
,
1580 oslSocketAddr pSenderAddr
,
1582 sal_uInt32 BufferSize
,
1583 oslSocketMsgFlag Flag
)
1586 struct sockaddr
*pSystemSockAddr
= nullptr;
1587 socklen_t AddrLen
= 0;
1590 AddrLen
= sizeof( struct sockaddr
);
1591 pSystemSockAddr
= &(pSenderAddr
->m_sockaddr
);
1594 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1595 if ( pSocket
== nullptr )
1600 pSocket
->m_nLastError
=0;
1602 nRead
= recvfrom(pSocket
->m_Socket
,
1605 MSG_FLAG_TO_NATIVE(Flag
),
1611 pSocket
->m_nLastError
=errno
;
1613 SAL_WARN( "sal.osl", "receive socket [" << nRead
<< "] failed: " << UnixErrnoString(nErrno
) );
1615 else if ( nRead
== 0 )
1617 SAL_WARN( "sal.osl", "receive socket [" << nRead
<< "] failed: EOL" );
1623 sal_Int32 SAL_CALL
osl_sendSocket(oslSocket pSocket
,
1624 const void* pBuffer
,
1625 sal_uInt32 BytesToSend
,
1626 oslSocketMsgFlag Flag
)
1630 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1631 if ( pSocket
== nullptr )
1636 pSocket
->m_nLastError
=0;
1640 nWritten
= send(pSocket
->m_Socket
,
1643 MSG_FLAG_TO_NATIVE(Flag
));
1644 } while ( nWritten
< 0 && errno
== EINTR
);
1648 pSocket
->m_nLastError
=errno
;
1650 SAL_WARN( "sal.osl", "send socket [" << nWritten
<< "] failed: " << UnixErrnoString(nErrno
) );
1652 else if ( nWritten
== 0 )
1654 SAL_WARN( "sal.osl", "send socket [" << nWritten
<< "] failed: EOL" );
1660 sal_Int32 SAL_CALL
osl_sendToSocket(oslSocket pSocket
,
1661 oslSocketAddr ReceiverAddr
,
1662 const void* pBuffer
,
1663 sal_uInt32 BytesToSend
,
1664 oslSocketMsgFlag Flag
)
1668 struct sockaddr
*pSystemSockAddr
= nullptr;
1672 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
1673 AddrLen
= sizeof( struct sockaddr
);
1676 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1677 if ( pSocket
== nullptr )
1682 pSocket
->m_nLastError
=0;
1684 /* ReceiverAddr might be 0 when used on a connected socket. */
1685 /* Then sendto should behave like send. */
1687 nWritten
= sendto(pSocket
->m_Socket
,
1690 MSG_FLAG_TO_NATIVE(Flag
),
1696 pSocket
->m_nLastError
=errno
;
1698 SAL_WARN( "sal.osl", "send socket [" << nWritten
<< "] failed: " << UnixErrnoString(nErrno
) );
1700 else if ( nWritten
== 0 )
1702 SAL_WARN( "sal.osl", "send socket [" << nWritten
<< "] failed: EOL" );
1708 sal_Int32 SAL_CALL
osl_readSocket (
1709 oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
1711 sal_uInt8
* Ptr
= static_cast<sal_uInt8
*>(pBuffer
);
1712 sal_uInt32 BytesRead
= 0;
1713 sal_uInt32 BytesToRead
= n
;
1715 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1717 /* loop until all desired bytes were read or an error occurred */
1718 while (BytesToRead
> 0)
1721 RetVal
= osl_receiveSocket(pSocket
,
1724 osl_Socket_MsgNormal
);
1726 /* error occurred? */
1732 BytesToRead
-= RetVal
;
1733 BytesRead
+= RetVal
;
1740 sal_Int32 SAL_CALL
osl_writeSocket(
1741 oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
1743 /* loop until all desired bytes were send or an error occurred */
1744 sal_uInt32 BytesSend
= 0;
1745 sal_uInt32 BytesToSend
= n
;
1746 sal_uInt8
const *Ptr
= static_cast<sal_uInt8
const *>(pBuffer
);
1748 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1750 while (BytesToSend
> 0)
1754 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
1756 /* error occurred? */
1762 BytesToSend
-= RetVal
;
1763 BytesSend
+= RetVal
;
1770 static bool socket_poll (
1772 const TimeValue
* pTimeout
,
1779 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1780 if (pSocket
== nullptr)
1781 return false; /* EINVAL */
1783 pSocket
->m_nLastError
= 0;
1785 fds
.fd
= pSocket
->m_Socket
;
1786 fds
.events
= nEvent
;
1792 timeout
= convertToMs(pTimeout
);
1795 result
= poll (&fds
, 1, timeout
);
1798 pSocket
->m_nLastError
= errno
;
1800 SAL_WARN( "sal.osl", "poll failed: " << UnixErrnoString(nErrno
) );
1809 return ((fds
.revents
& nEvent
) == nEvent
);
1812 sal_Bool SAL_CALL
osl_isReceiveReady (
1813 oslSocket pSocket
, const TimeValue
* pTimeout
)
1815 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1816 if (pSocket
== nullptr)
1822 return socket_poll (pSocket
, pTimeout
, POLLIN
);
1825 sal_Bool SAL_CALL
osl_isSendReady (
1826 oslSocket pSocket
, const TimeValue
* pTimeout
)
1828 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1829 if (pSocket
== nullptr)
1835 return socket_poll (pSocket
, pTimeout
, POLLOUT
);
1838 sal_Bool SAL_CALL
osl_isExceptionPending (
1839 oslSocket pSocket
, const TimeValue
* pTimeout
)
1841 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1842 if (pSocket
== nullptr)
1848 return socket_poll (pSocket
, pTimeout
, POLLPRI
);
1851 sal_Bool SAL_CALL
osl_shutdownSocket(oslSocket pSocket
,
1852 oslSocketDirection Direction
)
1856 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1857 if ( pSocket
== nullptr )
1862 pSocket
->m_nLastError
=0;
1864 nRet
=shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
));
1867 pSocket
->m_nLastError
=errno
;
1869 SAL_WARN( "sal.osl", "shutdown failed: " << UnixErrnoString(nErrno
) );
1874 sal_Int32 SAL_CALL
osl_getSocketOption(oslSocket pSocket
,
1875 oslSocketOptionLevel Level
,
1876 oslSocketOption Option
,
1878 sal_uInt32 BufferLen
)
1880 socklen_t nOptLen
= static_cast<socklen_t
>(BufferLen
);
1882 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1883 if ( pSocket
== nullptr )
1888 pSocket
->m_nLastError
=0;
1890 if(getsockopt(pSocket
->m_Socket
,
1891 OPTION_LEVEL_TO_NATIVE(Level
),
1892 OPTION_TO_NATIVE(Option
),
1896 pSocket
->m_nLastError
=errno
;
1903 sal_Bool SAL_CALL
osl_setSocketOption(oslSocket pSocket
,
1904 oslSocketOptionLevel Level
,
1905 oslSocketOption Option
,
1907 sal_uInt32 BufferLen
)
1911 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1912 if ( pSocket
== nullptr )
1917 pSocket
->m_nLastError
=0;
1919 nRet
= setsockopt(pSocket
->m_Socket
,
1920 OPTION_LEVEL_TO_NATIVE(Level
),
1921 OPTION_TO_NATIVE(Option
),
1927 pSocket
->m_nLastError
=errno
;
1934 sal_Bool SAL_CALL
osl_enableNonBlockingMode(oslSocket pSocket
,
1940 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1941 if ( pSocket
== nullptr )
1946 pSocket
->m_nLastError
=0;
1948 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
1951 flags
|= O_NONBLOCK
;
1953 flags
&= ~(O_NONBLOCK
);
1955 nRet
= fcntl(pSocket
->m_Socket
, F_SETFL
, flags
);
1959 pSocket
->m_nLastError
=errno
;
1966 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
1970 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1971 if ( pSocket
== nullptr )
1976 pSocket
->m_nLastError
=0;
1978 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
1980 if (flags
== -1 || !(flags
& O_NONBLOCK
))
1986 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
1989 socklen_t TypeSize
= sizeof(Type
);
1991 SAL_WARN_IF( !pSocket
, "sal.osl", "undefined socket" );
1992 if ( pSocket
== nullptr )
1994 return osl_Socket_TypeInvalid
;
1997 pSocket
->m_nLastError
=0;
1999 if(getsockopt(pSocket
->m_Socket
,
2000 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
2001 OPTION_TO_NATIVE(osl_Socket_OptionType
),
2006 pSocket
->m_nLastError
=errno
;
2007 return osl_Socket_TypeInvalid
;
2010 return TYPE_FROM_NATIVE(Type
);
2014 void SAL_CALL
osl_getLastSocketErrorDescription(oslSocket Socket
, rtl_uString
**ustrError
)
2016 char pszError
[1024];
2020 osl_psz_getLastSocketErrorDescription(Socket
,pszError
,sizeof(pszError
));
2022 rtl_uString_newFromAscii(ustrError
,pszError
);
2025 void osl_psz_getLastSocketErrorDescription(oslSocket pSocket
, char* pBuffer
, sal_uInt32 BufferSize
)
2027 /* make sure pBuffer will be a zero-terminated string even when strncpy has to cut */
2028 pBuffer
[BufferSize
-1]= '\0';
2030 if ( pSocket
== nullptr )
2032 strncpy(pBuffer
, strerror(EINVAL
), BufferSize
-1);
2036 strncpy(pBuffer
, strerror(pSocket
->m_nLastError
), BufferSize
-1);
2039 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket pSocket
)
2041 if ( pSocket
== nullptr )
2043 return ERROR_FROM_NATIVE(EINVAL
);
2046 return ERROR_FROM_NATIVE(pSocket
->m_nLastError
);
2049 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */