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 .
22 #include <osl/socket.h>
23 #include <osl/diagnose.h>
24 #include <osl/mutex.h>
25 #include <osl/signal.h>
27 #include <rtl/alloc.h>
30 #include <sal/types.h>
34 /* defines for poll */
39 #if defined(LINUX) || defined(NETBSD) || defined ( FREEBSD ) || \
40 defined (MACOSX) || defined (OPENBSD) || defined(DRAGONFLY)
43 #endif /* HAVE_POLL_H */
52 #define POLLOUT 0x0002
53 #define POLLPRI 0x0004
54 #endif /* HAVE_POLL_H */
56 /* defines for shutdown */
62 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
63 I refrained from using sockaddr_in because of possible further
64 extensions of this socket-interface (IP-NG?).
65 The intention was to hide all Berkeley data-structures from
66 direct access past the osl-interface.
68 The current implementation is internet (IP) centered. All
69 the constructor-functions (osl_create...) take parameters
70 that will probably make sense only in the IP-environment
71 (e.g. because of using the dotted-address-format).
73 If the interface will be extended to host other protocol-
74 families, I expect no externally visible changes in the
75 existing functions. You'll probably need only new
76 constructor-functions who take the different address
77 formats into consideration (maybe a long dotted address
81 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
82 /* are the same! I don't like it very much but see no other easy way to */
83 /* conceal the struct sockaddr from the eyes of the user. */
85 #define OSL_INVALID_SOCKET -1
86 #define OSL_SOCKET_ERROR -1
88 /* Buffer size for gethostbyname */
89 #define MAX_HOSTBUFFER_SIZE 2048
91 /*****************************************************************************/
92 /* enum oslAddrFamily */
93 /*****************************************************************************/
96 static const unsigned long FamilyMap
[]= {
97 AF_INET
, /* osl_Socket_FamilyInet */
98 AF_IPX
, /* osl_Socket_FamilyIpx */
99 0 /* osl_Socket_FamilyInvalid */
103 static oslAddrFamily
osl_AddrFamilyFromNative(sal_uInt32 nativeType
)
105 oslAddrFamily i
= (oslAddrFamily
)0;
107 while(i
!= osl_Socket_FamilyInvalid
)
109 if(FamilyMap
[i
] == nativeType
)
111 i
= (oslAddrFamily
) ( i
+ 1 );
118 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
119 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
121 /*****************************************************************************/
122 /* enum oslProtocol */
123 /*****************************************************************************/
126 static const sal_uInt32 ProtocolMap
[]= {
127 0, /* osl_Socket_ProtocolIp */
128 NSPROTO_IPX
, /* osl_Socket_ProtocolIpx */
129 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
130 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpxII */
131 0 /* osl_Socket_ProtocolInvalid */
136 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
138 oslProtocol i= (oslProtocol)0;
140 while(i != osl_Socket_ProtocolInvalid)
142 if(ProtocolMap[i] == nativeType)
144 i = (oslProtocol) ( i + 1);
152 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
154 /*****************************************************************************/
155 /* enum oslSocketType */
156 /*****************************************************************************/
159 static const sal_uInt32 TypeMap
[]= {
160 SOCK_STREAM
, /* osl_Socket_TypeStream */
161 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
162 SOCK_RAW
, /* osl_Socket_TypeRaw */
163 SOCK_RDM
, /* osl_Socket_TypeRdm */
164 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
165 0 /* osl_Socket_TypeInvalid */
169 static oslSocketType
osl_SocketTypeFromNative(sal_uInt32 nativeType
)
171 oslSocketType i
= (oslSocketType
)0;
173 while(i
!= osl_Socket_TypeInvalid
)
175 if(TypeMap
[i
] == nativeType
)
177 i
= (oslSocketType
)(i
+ 1);
184 #define TYPE_TO_NATIVE(x) TypeMap[x]
185 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
187 /*****************************************************************************/
188 /* enum oslSocketOption */
189 /*****************************************************************************/
192 static const sal_uInt32 OptionMap
[]= {
193 SO_DEBUG
, /* osl_Socket_OptionDebug */
194 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
195 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
196 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
197 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
198 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
199 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
200 SO_LINGER
, /* osl_Socket_OptionLinger */
201 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
202 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
203 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
204 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
205 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
206 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
207 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
208 SO_ERROR
, /* osl_Socket_OptionError */
209 SO_TYPE
, /* osl_Socket_OptionType */
210 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
211 0 /* osl_Socket_OptionInvalid */
216 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
218 oslSocketOption i= (oslSocketOption)0;
220 while(i != osl_Socket_OptionInvalid)
222 if(OptionMap[i] == nativeType)
224 i = (oslSocketOption) ( i + 1 );
231 #define OPTION_TO_NATIVE(x) OptionMap[x]
233 /*****************************************************************************/
234 /* enum oslSocketOptionLevel */
235 /*****************************************************************************/
237 static const sal_uInt32 OptionLevelMap
[]= {
238 SOL_SOCKET
, /* osl_Socket_LevelSocket */
239 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
240 0 /* osl_Socket_LevelInvalid */
245 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
247 oslSocketOptionLevel i= (oslSocketOptionLevel)0;
249 while(i != osl_Socket_LevelInvalid)
251 if(OptionLevelMap[i] == nativeType)
253 i = (oslSocketOptionLevel) ( i + 1 );
260 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
262 /*****************************************************************************/
263 /* enum oslSocketMsgFlag */
264 /*****************************************************************************/
266 static const sal_uInt32 SocketMsgFlagMap
[]= {
267 0, /* osl_Socket_MsgNormal */
268 MSG_OOB
, /* osl_Socket_MsgOOB */
269 MSG_PEEK
, /* osl_Socket_MsgPeek */
270 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
271 MSG_MAXIOVLEN
, /* osl_Socket_MsgMaxIOVLen */
272 0 /* osl_Socket_MsgInvalid */
277 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
279 oslSocketMsgFlag i= (oslSocketMsgFlag)0;
281 while(i != osl_Socket_MsgInvalid)
283 if(SocketMsgFlagMap[i] == nativeType)
285 i = (oslSocketMsgFlag) ( i + 1 );
293 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
295 /*****************************************************************************/
296 /* enum oslSocketDirection */
297 /*****************************************************************************/
299 static const sal_uInt32 SocketDirection
[]= {
300 SD_RECEIVE
, /* osl_Socket_DirRead */
301 SD_SEND
, /* osl_Socket_DirWrite */
302 SD_BOTH
, /* osl_Socket_DirReadWrite */
303 0 /* osl_Socket_DirInvalid */
308 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
310 oslSocketDirection i= (oslSocketDirection)0;
312 while(i != osl_Socket_DirInvalid)
314 if(SocketDirection[i] == nativeType)
316 i = (oslSocketDirection) ( i + 1 );
324 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
326 /*****************************************************************************/
327 /* enum oslSocketError */
328 /*****************************************************************************/
333 oslSocketError error
;
335 { 0, osl_Socket_E_None
}, /* no error */
336 { ENOTSOCK
, osl_Socket_E_NotSocket
}, /* Socket operation on non-socket */
337 { EDESTADDRREQ
, osl_Socket_E_DestAddrReq
}, /* Destination address required */
338 { EMSGSIZE
, osl_Socket_E_MsgSize
}, /* Message too long */
339 { EPROTOTYPE
, osl_Socket_E_Prototype
}, /* Protocol wrong type for socket */
340 { ENOPROTOOPT
, osl_Socket_E_NoProtocol
}, /* Protocol not available */
341 { EPROTONOSUPPORT
, osl_Socket_E_ProtocolNoSupport
}, /* Protocol not supported */
342 { ESOCKTNOSUPPORT
, osl_Socket_E_TypeNoSupport
}, /* Socket type not supported */
343 { EOPNOTSUPP
, osl_Socket_E_OpNotSupport
}, /* Operation not supported on socket */
344 { EPFNOSUPPORT
, osl_Socket_E_PfNoSupport
}, /* Protocol family not supported */
345 { EAFNOSUPPORT
, osl_Socket_E_AfNoSupport
}, /* Address family not supported by */
346 /* protocol family */
347 { EADDRINUSE
, osl_Socket_E_AddrInUse
}, /* Address already in use */
348 { EADDRNOTAVAIL
, osl_Socket_E_AddrNotAvail
}, /* Can't assign requested address */
349 { ENETDOWN
, osl_Socket_E_NetDown
}, /* Network is down */
350 { ENETUNREACH
, osl_Socket_E_NetUnreachable
}, /* Network is unreachable */
351 { ENETRESET
, osl_Socket_E_NetReset
}, /* Network dropped connection because */
353 { ECONNABORTED
, osl_Socket_E_ConnAborted
}, /* Software caused connection abort */
354 { ECONNRESET
, osl_Socket_E_ConnReset
}, /* Connection reset by peer */
355 { ENOBUFS
, osl_Socket_E_NoBufferSpace
}, /* No buffer space available */
356 { EISCONN
, osl_Socket_E_IsConnected
}, /* Socket is already connected */
357 { ENOTCONN
, osl_Socket_E_NotConnected
}, /* Socket is not connected */
358 { ESHUTDOWN
, osl_Socket_E_Shutdown
}, /* Can't send after socket shutdown */
359 { ETOOMANYREFS
, osl_Socket_E_TooManyRefs
}, /* Too many references: can't splice */
360 { ETIMEDOUT
, osl_Socket_E_TimedOut
}, /* Connection timed out */
361 { ECONNREFUSED
, osl_Socket_E_ConnRefused
}, /* Connection refused */
362 { EHOSTDOWN
, osl_Socket_E_HostDown
}, /* Host is down */
363 { EHOSTUNREACH
, osl_Socket_E_HostUnreachable
}, /* No route to host */
364 { EWOULDBLOCK
, osl_Socket_E_WouldBlock
}, /* call would block on non-blocking socket */
365 { EALREADY
, osl_Socket_E_Already
}, /* operation already in progress */
366 { EINPROGRESS
, osl_Socket_E_InProgress
}, /* operation now in progress */
367 { EAGAIN
, osl_Socket_E_WouldBlock
}, /* same as EWOULDBLOCK */
368 { -1, osl_Socket_E_InvalidError
}
373 static int osl_NativeFromSocketError(oslSocketError errorCode)
377 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
378 (SocketError[i].error != errorCode)) i++;
380 return SocketError[i].errcode;
385 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
389 while ((SocketError
[i
].error
!= osl_Socket_E_InvalidError
) &&
390 (SocketError
[i
].errcode
!= nativeType
)) i
++;
392 return SocketError
[i
].error
;
396 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
398 /*****************************************************************************/
399 /* local function prototypes */
400 /*****************************************************************************/
402 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
403 const sal_Char
* pszDottedAddr
, sal_Int32 Port
);
405 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
406 const sal_Char
*pszHostname
, const oslSocketAddr Addr
);
408 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (
409 const sal_Char
*pszHostname
);
411 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (
412 const oslHostAddr Addr
);
414 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
415 sal_Char
*pBuffer
, sal_uInt32 nBufLen
);
417 oslSocketAddr SAL_CALL
osl_psz_resolveHostname (
418 const sal_Char
* pszHostname
);
420 sal_Int32 SAL_CALL
osl_psz_getServicePort (
421 const sal_Char
* pszServicename
, const sal_Char
* pszProtocol
);
423 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr (
424 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
426 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr (
427 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
429 void SAL_CALL
osl_psz_getLastSocketErrorDescription (
430 oslSocket Socket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
);
432 #if OSL_DEBUG_LEVEL > 1
433 static sal_uInt32 g_nSocketImpl
= 0;
434 static sal_uInt32 g_nSocketAddr
= 0;
436 /* sorry, must be implemented otherwise */
438 #endif /* OSL_DEBUG_LEVEL */
440 oslSocket
__osl_createSocketImpl(int Socket
)
444 pSocket
= (oslSocket
)calloc(1, sizeof(struct oslSocketImpl
));
446 pSocket
->m_Socket
= Socket
;
447 pSocket
->m_nLastError
= 0;
448 pSocket
->m_nRefCount
= 1;
451 pSocket
->m_bIsAccepting
= sal_False
;
454 #if OSL_DEBUG_LEVEL > 1
460 void __osl_destroySocketImpl(oslSocket Socket
)
463 free((struct oslSocketImpl
*) Socket
);
464 #if OSL_DEBUG_LEVEL > 1
469 static oslSocketAddr
__osl_createSocketAddr( )
471 oslSocketAddr pAddr
= (oslSocketAddr
) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
));
472 #if OSL_DEBUG_LEVEL > 1
478 static oslSocketAddr
__osl_createSocketAddrWithFamily(
479 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
483 OSL_ASSERT( family
== osl_Socket_FamilyInet
);
485 pAddr
= __osl_createSocketAddr();
488 case osl_Socket_FamilyInet
:
490 struct sockaddr_in
* pInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
492 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
493 pInetAddr
->sin_addr
.s_addr
= nAddr
;
494 pInetAddr
->sin_port
= (sal_uInt16
)(port
&0xffff);
498 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
503 static oslSocketAddr
__osl_createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
505 oslSocketAddr pAddr
= __osl_createSocketAddr();
506 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( struct sockaddr
) );
510 static void __osl_destroySocketAddr( oslSocketAddr addr
)
512 #if OSL_DEBUG_LEVEL > 1
515 rtl_freeMemory( addr
);
518 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
520 oslSocketAddr pAddr
= 0;
522 /* is it an internet-Addr? */
523 if (Family
== osl_Socket_FamilyInet
)
525 pAddr
= __osl_createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
529 pAddr
= __osl_createSocketAddrWithFamily( Family
, 0 , 0 );
535 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
537 oslSocketAddr pCopy
= 0;
540 pCopy
= __osl_createSocketAddr();
543 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
548 sal_Bool SAL_CALL
osl_isEqualSocketAddr (
552 struct sockaddr
* pAddr1
= NULL
;
553 struct sockaddr
* pAddr2
= NULL
;
557 pAddr1
= &(Addr1
->m_sockaddr
);
558 pAddr2
= &(Addr2
->m_sockaddr
);
560 if (pAddr1
== pAddr2
)
565 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
567 switch (pAddr1
->sa_family
)
571 struct sockaddr_in
* pInetAddr1
= (struct sockaddr_in
*)pAddr1
;
572 struct sockaddr_in
* pInetAddr2
= (struct sockaddr_in
*)pAddr2
;
574 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
575 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
576 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
582 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
590 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
591 rtl_uString
*strDottedAddr
,
594 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
597 if (strDottedAddr
&& strDottedAddr
->length
)
599 /* Dotted host address for limited broadcast */
600 rtl_String
*pDottedAddr
= NULL
;
603 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
604 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
606 nAddr
= inet_addr (pDottedAddr
->buffer
);
607 rtl_string_release (pDottedAddr
);
610 if (nAddr
!= OSL_INADDR_NONE
)
612 /* Limited broadcast */
613 nAddr
= ntohl(nAddr
);
614 if (IN_CLASSA(nAddr
))
616 nAddr
&= IN_CLASSA_NET
;
617 nAddr
|= IN_CLASSA_HOST
;
619 else if (IN_CLASSB(nAddr
))
621 nAddr
&= IN_CLASSB_NET
;
622 nAddr
|= IN_CLASSB_HOST
;
624 else if (IN_CLASSC(nAddr
))
626 nAddr
&= IN_CLASSC_NET
;
627 nAddr
|= IN_CLASSC_HOST
;
631 /* No broadcast in class D */
632 return ((oslSocketAddr
)NULL
);
634 nAddr
= htonl(nAddr
);
637 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
), nAddr
);
641 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
642 rtl_uString
*ustrDottedAddr
,
645 rtl_String
* strDottedAddr
=0;
647 sal_Char
* pszDottedAddr
=0;
649 if ( ustrDottedAddr
!= 0 )
651 rtl_uString2String( &strDottedAddr
,
652 rtl_uString_getStr(ustrDottedAddr
),
653 rtl_uString_getLength(ustrDottedAddr
),
654 RTL_TEXTENCODING_UTF8
,
655 OUSTRING_TO_OSTRING_CVTFLAGS
);
656 pszDottedAddr
= rtl_string_getStr(strDottedAddr
);
659 Addr
= osl_psz_createInetSocketAddr(pszDottedAddr
, Port
);
661 if ( strDottedAddr
!= 0 )
663 rtl_string_release(strDottedAddr
);
669 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
670 const sal_Char
* pszDottedAddr
,
673 oslSocketAddr pAddr
= 0;
674 sal_Int32 Addr
= inet_addr(pszDottedAddr
);
677 /* valid dotted addr */
678 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
) , Addr
);
683 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
685 oslSocketResult res
= osl_Socket_Error
;
688 OSL_ASSERT( pByteSeq
);
690 if( pAddr
&& pByteSeq
)
692 struct sockaddr_in
* pSystemInetAddr
;
694 OSL_ASSERT( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
695 OSL_ASSERT( pByteSeq
->nElements
== 4 );
697 pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
698 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
704 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
706 oslSocketResult res
= osl_Socket_Error
;
709 OSL_ASSERT( ppByteSeq
);
711 if( pAddr
&& ppByteSeq
)
713 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
714 rtl_byte_sequence_constructFromArray( ppByteSeq
, (sal_Int8
*) &(pSystemInetAddr
->sin_addr
),4);
720 /** try to figure out a full-qualified hostname, by adding the current domain
721 as given by the domainname program to the given hostname.
722 This function MUST NOT call gethostbyname since pHostName already points
723 to data returned by gethostname and would be garbled: use gethostname_r
727 /* wrap around different interfaces to reentrant gethostbyname */
728 static struct hostent
* _osl_gethostbyname_r (
729 const char *name
, struct hostent
*result
,
730 char *buffer
, int buflen
, int *h_errnop
)
732 #if defined(LINUX) || defined(ANDROID) || (defined(FREEBSD) && (__FreeBSD_version >= 601103)) || defined(DRAGONFLY)
733 struct hostent
*__result
; /* will be the same as result */
735 __error
= gethostbyname_r (name
, result
, buffer
, buflen
,
736 &__result
, h_errnop
);
737 return __error
? NULL
: __result
;
739 *h_errnop
= gethostbyname_r (name
, result
, (struct hostent_data
*)buffer
);
741 return *h_errnop
? NULL
: result
;
743 return gethostbyname_r( name
, result
, buffer
, buflen
, h_errnop
);
747 static sal_Char
* _osl_getFullQualifiedDomainName (const sal_Char
*pHostName
)
749 struct hostent aHostByName
;
750 struct hostent
*pHostByName
;
751 sal_Char pQualifiedHostBuffer
[ MAX_HOSTBUFFER_SIZE
];
752 sal_Char
*pFullQualifiedName
= NULL
;
755 pHostByName
= _osl_gethostbyname_r (
757 &aHostByName
, pQualifiedHostBuffer
,
758 sizeof(pQualifiedHostBuffer
), &nErrorNo
);
759 if (pHostByName
!= NULL
)
761 pFullQualifiedName
= strdup(pHostByName
->h_name
);
763 return pFullQualifiedName
;
766 static sal_Bool
_osl_isFullQualifiedDomainName (const sal_Char
*pHostName
)
768 /* a FQDN (aka 'hostname.domain.top_level_domain' )
769 * is a name which contains a dot '.' in it ( would
770 * match as well for 'hostname.' but is good enough
772 return (sal_Bool
)( strchr( pHostName
, (int)'.' ) != NULL
);
775 struct oslHostAddrImpl
778 oslSocketAddr pSockAddr
;
781 static oslHostAddr
_osl_hostentToHostAddr (const struct hostent
*he
)
783 oslHostAddr pAddr
= NULL
;
784 oslSocketAddr pSockAddr
= 0;
788 if ((he
== NULL
) || (he
->h_name
== NULL
) || (he
->h_addr_list
[0] == NULL
))
789 return ((oslHostAddr
)NULL
);
791 if (_osl_isFullQualifiedDomainName(he
->h_name
))
793 cn
= strdup(he
->h_name
);
796 return ((oslHostAddr
)NULL
);
800 cn
=_osl_getFullQualifiedDomainName (he
->h_name
);
803 return ((oslHostAddr
)NULL
);
806 pSockAddr
= __osl_createSocketAddr();
807 OSL_ASSERT(pSockAddr
);
808 if (pSockAddr
== NULL
)
811 return ((oslHostAddr
)NULL
);
814 pSockAddr
->m_sockaddr
.sa_family
= he
->h_addrtype
;
815 if (pSockAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
817 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&(pSockAddr
->m_sockaddr
);
819 &(sin
->sin_addr
.s_addr
),
825 /* unknown address family */
826 /* future extensions for new families might be implemented here */
828 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.");
829 OSL_ASSERT(sal_False
);
831 __osl_destroySocketAddr( pSockAddr
);
833 return ((oslHostAddr
)NULL
);
836 pAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
840 __osl_destroySocketAddr( pSockAddr
);
842 return ((oslHostAddr
)NULL
);
845 pAddr
->pHostName
= cn
;
846 pAddr
->pSockAddr
= pSockAddr
;
851 oslHostAddr SAL_CALL
osl_createHostAddr (
852 rtl_uString
*ustrHostname
,
853 const oslSocketAddr Addr
)
855 oslHostAddr HostAddr
;
856 rtl_String
* strHostname
=0;
857 sal_Char
* pszHostName
=0;
859 if ( ustrHostname
!= 0 )
861 rtl_uString2String( &strHostname
,
862 rtl_uString_getStr(ustrHostname
),
863 rtl_uString_getLength(ustrHostname
),
864 RTL_TEXTENCODING_UTF8
,
865 OUSTRING_TO_OSTRING_CVTFLAGS
);
866 pszHostName
= rtl_string_getStr(strHostname
);
869 HostAddr
= osl_psz_createHostAddr(pszHostName
,Addr
);
871 if ( strHostname
!= 0 )
873 rtl_string_release(strHostname
);
879 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
880 const sal_Char
*pszHostname
,
881 const oslSocketAddr pAddr
)
883 oslHostAddr pHostAddr
;
886 OSL_ASSERT(pszHostname
&& pAddr
);
887 if ((pszHostname
== NULL
) || (pAddr
== NULL
))
888 return ((oslHostAddr
)NULL
);
890 cn
= strdup(pszHostname
);
893 return ((oslHostAddr
)NULL
);
895 pHostAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
896 OSL_ASSERT(pHostAddr
);
897 if (pHostAddr
== NULL
)
900 return ((oslHostAddr
)NULL
);
903 pHostAddr
->pHostName
= cn
;
904 pHostAddr
->pSockAddr
= osl_copySocketAddr( pAddr
);
909 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*ustrHostname
)
911 oslHostAddr HostAddr
;
912 rtl_String
* strHostname
=0;
913 sal_Char
* pszHostName
=0;
915 if ( ustrHostname
!= 0 )
917 rtl_uString2String( &strHostname
,
918 rtl_uString_getStr(ustrHostname
),
919 rtl_uString_getLength(ustrHostname
),
920 RTL_TEXTENCODING_UTF8
,
921 OUSTRING_TO_OSTRING_CVTFLAGS
);
922 pszHostName
=rtl_string_getStr(strHostname
);
925 HostAddr
= osl_psz_createHostAddrByName(pszHostName
);
927 if ( strHostname
!= 0 )
929 rtl_string_release(strHostname
);
935 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (const sal_Char
*pszHostname
)
939 sal_Char heBuffer
[ MAX_HOSTBUFFER_SIZE
];
942 pHe
= _osl_gethostbyname_r (
945 sizeof(heBuffer
), &nErrorNo
);
947 return _osl_hostentToHostAddr (pHe
);
950 oslHostAddr SAL_CALL
osl_createHostAddrByAddr (const oslSocketAddr pAddr
)
955 return ((oslHostAddr
)NULL
);
957 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
959 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
962 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
963 return ((oslHostAddr
)NULL
);
965 he
= gethostbyaddr((sal_Char
*)&(sin
->sin_addr
),
966 sizeof (sin
->sin_addr
),
968 return _osl_hostentToHostAddr (he
);
971 return ((oslHostAddr
)NULL
);
974 oslHostAddr SAL_CALL
osl_copyHostAddr (const oslHostAddr pAddr
)
979 return osl_psz_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
981 return ((oslHostAddr
)NULL
);
984 void SAL_CALL
osl_getHostnameOfHostAddr (
985 const oslHostAddr Addr
,
986 rtl_uString
**ustrHostname
)
988 const sal_Char
* pHostname
=0;
990 pHostname
= osl_psz_getHostnameOfHostAddr(Addr
);
992 rtl_uString_newFromAscii (ustrHostname
, pHostname
);
997 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr
)
1000 return pAddr
->pHostName
;
1005 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr
)
1010 return ((oslSocketAddr
)(pAddr
->pSockAddr
));
1015 void SAL_CALL
osl_destroyHostAddr (oslHostAddr pAddr
)
1019 if (pAddr
->pHostName
)
1020 free (pAddr
->pHostName
);
1021 if (pAddr
->pSockAddr
)
1022 osl_destroySocketAddr (pAddr
->pSockAddr
);
1027 oslSocketResult SAL_CALL
osl_getLocalHostname(rtl_uString
**ustrLocalHostname
)
1029 oslSocketResult Result
;
1030 sal_Char pszHostname
[1024];
1032 pszHostname
[0] = '\0';
1034 Result
= osl_psz_getLocalHostname(pszHostname
,sizeof(pszHostname
));
1036 rtl_uString_newFromAscii(ustrLocalHostname
,pszHostname
);
1041 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
1042 sal_Char
*pBuffer
, sal_uInt32 nBufLen
)
1044 static sal_Char LocalHostname
[256] = "";
1046 if (strlen(LocalHostname
) == 0)
1048 const sal_Char
*pStr
;
1053 if (uname(&uts
) < 0)
1054 return osl_Socket_Error
;
1056 if ((strlen(uts
.nodename
) + 1) > nBufLen
)
1057 return osl_Socket_Error
;
1059 strncpy(LocalHostname
, uts
.nodename
, sizeof( LocalHostname
));
1060 #else /* BSD compatible */
1062 if (gethostname(LocalHostname
, sizeof(LocalHostname
)-1) != 0)
1063 return osl_Socket_Error
;
1064 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
1067 /* check if we have an FQDN */
1068 if (strchr(LocalHostname
, '.') == NULL
)
1072 /* no, determine it via dns */
1073 Addr
= osl_psz_createHostAddrByName(LocalHostname
);
1075 if ((pStr
= osl_psz_getHostnameOfHostAddr(Addr
)) != NULL
)
1077 strcpy(LocalHostname
, pStr
);
1079 osl_destroyHostAddr(Addr
);
1083 if (strlen(LocalHostname
) > 0)
1085 strncpy(pBuffer
, LocalHostname
, nBufLen
);
1086 pBuffer
[nBufLen
- 1] = '\0';
1088 return osl_Socket_Ok
;
1091 return osl_Socket_Error
;
1094 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
*ustrHostname
)
1097 rtl_String
* strHostname
=0;
1098 sal_Char
* pszHostName
=0;
1100 if ( ustrHostname
!= 0 )
1102 rtl_uString2String( &strHostname
,
1103 rtl_uString_getStr(ustrHostname
),
1104 rtl_uString_getLength(ustrHostname
),
1105 RTL_TEXTENCODING_UTF8
,
1106 OUSTRING_TO_OSTRING_CVTFLAGS
);
1107 pszHostName
= rtl_string_getStr(strHostname
);
1110 Addr
= osl_psz_resolveHostname(pszHostName
);
1112 if ( strHostname
!= 0 )
1114 rtl_string_release(strHostname
);
1120 oslSocketAddr SAL_CALL
osl_psz_resolveHostname(const sal_Char
* pszHostname
)
1122 struct oslHostAddrImpl
*pAddr
= (oslHostAddr
)osl_psz_createHostAddrByName(pszHostname
);
1126 oslSocketAddr SockAddr
= osl_copySocketAddr(pAddr
->pSockAddr
);
1128 osl_destroyHostAddr(pAddr
);
1133 return ((oslSocketAddr
)NULL
);
1136 sal_Int32 SAL_CALL
osl_getServicePort(rtl_uString
*ustrServicename
, rtl_uString
*ustrProtocol
)
1139 rtl_String
* strServicename
=0;
1140 rtl_String
* strProtocol
=0;
1141 sal_Char
* pszServiceName
=0;
1142 sal_Char
* pszProtocol
=0;
1144 if ( ustrServicename
!= 0 )
1146 rtl_uString2String( &strServicename
,
1147 rtl_uString_getStr(ustrServicename
),
1148 rtl_uString_getLength(ustrServicename
),
1149 RTL_TEXTENCODING_UTF8
,
1150 OUSTRING_TO_OSTRING_CVTFLAGS
);
1151 pszServiceName
= rtl_string_getStr(strServicename
);
1154 if ( ustrProtocol
!= 0 )
1156 rtl_uString2String( &strProtocol
,
1157 rtl_uString_getStr(ustrProtocol
),
1158 rtl_uString_getLength(ustrProtocol
),
1159 RTL_TEXTENCODING_UTF8
,
1160 OUSTRING_TO_OSTRING_CVTFLAGS
);
1161 pszProtocol
= rtl_string_getStr(strProtocol
);
1164 nPort
= osl_psz_getServicePort(pszServiceName
,pszProtocol
);
1166 if ( strServicename
!= 0 )
1168 rtl_string_release(strServicename
);
1171 if ( strProtocol
!= 0 )
1173 rtl_string_release(strProtocol
);
1179 sal_Int32 SAL_CALL
osl_psz_getServicePort(const sal_Char
* pszServicename
,
1180 const sal_Char
* pszProtocol
)
1184 ps
= getservbyname(pszServicename
, pszProtocol
);
1187 return ntohs(ps
->s_port
);
1189 return OSL_INVALID_PORT
;
1192 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
1194 __osl_destroySocketAddr( pAddr
);
1197 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
1202 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1204 return osl_Socket_FamilyInvalid
;
1207 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
1212 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1214 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1215 return ntohs(pSystemInetAddr
->sin_port
);
1217 return OSL_INVALID_PORT
;
1220 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr
, sal_Int32 Port
)
1225 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1226 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1228 pSystemInetAddr
->sin_port
= htons((short)Port
);
1233 /* this is not a inet-addr => can't set port */
1237 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrHostname
)
1239 oslSocketResult Result
;
1240 sal_Char pszHostname
[1024];
1242 pszHostname
[0] = '\0';
1244 Result
= osl_psz_getHostnameOfSocketAddr(Addr
,pszHostname
,sizeof(pszHostname
));
1246 rtl_uString_newFromAscii(ustrHostname
,pszHostname
);
1251 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr
,
1252 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1254 oslHostAddr pHostAddr
= (oslHostAddr
)osl_createHostAddrByAddr(pAddr
);
1258 strncpy(pBuffer
, pHostAddr
->pHostName
, BufferSize
);
1260 pBuffer
[BufferSize
- 1] = '\0';
1262 osl_destroyHostAddr(pHostAddr
);
1264 return osl_Socket_Ok
;
1267 return osl_Socket_Error
;
1270 /*****************************************************************************/
1271 /* osl_getDottedInetAddrOfSocketAddr */
1272 /*****************************************************************************/
1273 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrDottedInetAddr
)
1275 oslSocketResult Result
;
1276 sal_Char pszDottedInetAddr
[1024];
1278 pszDottedInetAddr
[0] = '\0';
1280 Result
= osl_psz_getDottedInetAddrOfSocketAddr(Addr
,pszDottedInetAddr
,sizeof(pszDottedInetAddr
));
1282 rtl_uString_newFromAscii(ustrDottedInetAddr
,pszDottedInetAddr
);
1288 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr
,
1289 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1295 struct sockaddr_in
* pSystemInetAddr
= ( struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
1297 if (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1299 strncpy(pBuffer
, inet_ntoa(pSystemInetAddr
->sin_addr
), BufferSize
);
1300 pBuffer
[BufferSize
- 1] = '\0';
1302 return osl_Socket_Ok
;
1306 return osl_Socket_Error
;
1309 oslSocket SAL_CALL
osl_createSocket(oslAddrFamily Family
,
1311 oslProtocol Protocol
)
1317 pSocket
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1320 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
1321 TYPE_TO_NATIVE(Type
),
1322 PROTOCOL_TO_NATIVE(Protocol
));
1324 /* creation failed => free memory */
1325 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
1327 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1331 __osl_destroySocketImpl((pSocket
));
1336 /* set close-on-exec flag */
1337 if ((Flags
= fcntl(pSocket
->m_Socket
, F_GETFD
, 0)) != -1)
1339 Flags
|= FD_CLOEXEC
;
1340 if (fcntl(pSocket
->m_Socket
, F_SETFD
, Flags
) == -1)
1342 pSocket
->m_nLastError
=errno
;
1343 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1350 pSocket
->m_nLastError
=errno
;
1357 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
1359 osl_atomic_increment( &(pSocket
->m_nRefCount
) );
1362 void SAL_CALL
osl_releaseSocket( oslSocket pSocket
)
1364 if( pSocket
&& 0 == osl_atomic_decrement( &(pSocket
->m_nRefCount
) ) )
1367 if ( pSocket
->m_bIsAccepting
== sal_True
)
1369 OSL_FAIL("osl_destroySocket : attempt to destroy socket while accepting\n");
1373 osl_closeSocket( pSocket
);
1374 __osl_destroySocketImpl( pSocket
);
1378 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
1383 /* socket already invalid */
1387 pSocket
->m_nLastError
=0;
1388 nFD
= pSocket
->m_Socket
;
1390 if (nFD
== OSL_INVALID_SOCKET
)
1393 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1396 pSocket
->m_bIsInShutdown
= sal_True
;
1398 if ( pSocket
->m_bIsAccepting
== sal_True
)
1402 struct sockaddr aSockAddr
;
1403 struct sockaddr_in aSockAddrIn
;
1405 socklen_t nSockLen
= sizeof(s
.aSockAddr
);
1407 nRet
= getsockname(nFD
, &s
.aSockAddr
, &nSockLen
);
1410 OSL_TRACE("getsockname call failed with error: %s", strerror(errno
));
1413 if ( s
.aSockAddr
.sa_family
== AF_INET
)
1415 if ( s
.aSockAddrIn
.sin_addr
.s_addr
== htonl(INADDR_ANY
) )
1417 s
.aSockAddrIn
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1420 nConnFD
= socket(AF_INET
, SOCK_STREAM
, 0);
1423 OSL_TRACE("socket call failed with error: %s", strerror(errno
));
1427 nRet
= connect(nConnFD
, &s
.aSockAddr
, sizeof(s
.aSockAddr
));
1430 OSL_TRACE("connect call failed with error: %s", strerror(errno
));
1435 pSocket
->m_bIsAccepting
= sal_False
;
1442 pSocket
->m_nLastError
=errno
;
1443 OSL_TRACE("closeSocket close error '%s'",strerror(errno
));
1446 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1449 /*****************************************************************************/
1450 /* osl_getLocalAddrOfSocket */
1451 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1452 /* are the same! I don't like it very much but see no other easy way to conceal */
1453 /* the struct sockaddr from the eyes of the user. */
1454 /*****************************************************************************/
1455 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
1458 struct sockaddr Addr
;
1459 oslSocketAddr pAddr
;
1461 if (pSocket
== NULL
) /* ENOTSOCK */
1462 return ((oslSocketAddr
)NULL
);
1464 AddrLen
= sizeof(struct sockaddr
);
1466 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1467 return ((oslSocketAddr
)NULL
);
1469 pAddr
= __osl_createSocketAddrFromSystem( &Addr
);
1473 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1476 struct sockaddr Addr
;
1478 OSL_ASSERT(pSocket
);
1484 pSocket
->m_nLastError
=0;
1485 AddrLen
= sizeof(struct sockaddr
);
1487 if(getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1489 pSocket
->m_nLastError
=errno
;
1492 return __osl_createSocketAddrFromSystem( &Addr
);
1495 sal_Bool SAL_CALL
osl_bindAddrToSocket(oslSocket pSocket
,
1496 oslSocketAddr pAddr
)
1500 OSL_ASSERT(pSocket
&& pAddr
);
1501 if ( pSocket
== 0 || pAddr
== 0 )
1506 pSocket
->m_nLastError
=0;
1508 nRet
= bind(pSocket
->m_Socket
, &(pAddr
->m_sockaddr
), sizeof(struct sockaddr
));
1510 if ( nRet
== OSL_SOCKET_ERROR
)
1512 pSocket
->m_nLastError
=errno
;
1519 sal_Bool SAL_CALL
osl_listenOnSocket(oslSocket pSocket
,
1520 sal_Int32 MaxPendingConnections
)
1524 OSL_ASSERT(pSocket
);
1530 pSocket
->m_nLastError
=0;
1532 nRet
= listen(pSocket
->m_Socket
,
1533 MaxPendingConnections
== -1 ?
1535 MaxPendingConnections
);
1536 if ( nRet
== OSL_SOCKET_ERROR
)
1538 pSocket
->m_nLastError
=errno
;
1545 oslSocketResult SAL_CALL
osl_connectSocketTo(oslSocket pSocket
,
1546 oslSocketAddr pAddr
,
1547 const TimeValue
* pTimeout
)
1553 oslSocketResult Result
= osl_Socket_Ok
;
1555 OSL_PRECOND(pSocket
, "osl_connectSocketTo(): need a valid socket!\n");
1559 return osl_Socket_Error
;
1562 pSocket
->m_nLastError
=0;
1564 if (osl_isNonBlockingMode(pSocket
))
1566 if (connect(pSocket
->m_Socket
,
1567 &(pAddr
->m_sockaddr
),
1568 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1569 return osl_Socket_Ok
;
1571 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
1573 pSocket
->m_nLastError
=EINPROGRESS
;
1574 return osl_Socket_InProgress
;
1577 pSocket
->m_nLastError
=errno
;
1578 OSL_TRACE("can't connect : '%s'",strerror(errno
));
1579 return osl_Socket_Error
;
1582 /* set socket temporarily to non-blocking */
1583 OSL_VERIFY(osl_enableNonBlockingMode(pSocket
, sal_True
));
1585 /* initiate connect */
1586 if(connect(pSocket
->m_Socket
,
1587 &(pAddr
->m_sockaddr
),
1588 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1590 /* immediate connection */
1591 osl_enableNonBlockingMode(pSocket
, sal_False
);
1593 return osl_Socket_Ok
;
1597 /* really an error or just delayed? */
1598 if (errno
!= EINPROGRESS
)
1600 pSocket
->m_nLastError
=errno
;
1602 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
1603 errno
, strerror(errno
));
1605 osl_enableNonBlockingMode(pSocket
, sal_False
);
1606 return osl_Socket_Error
;
1610 /* prepare select set for socket */
1613 FD_SET(pSocket
->m_Socket
, &WriteSet
);
1614 FD_SET(pSocket
->m_Socket
, &ExcptSet
);
1616 /* prepare timeout */
1619 /* divide milliseconds into seconds and microseconds */
1620 tv
.tv_sec
= pTimeout
->Seconds
;
1621 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1625 ReadyHandles
= select(pSocket
->m_Socket
+1,
1627 PTR_FD_SET(WriteSet
),
1628 PTR_FD_SET(ExcptSet
),
1629 (pTimeout
) ? &tv
: 0);
1631 if (ReadyHandles
> 0) /* connected */
1633 if ( FD_ISSET(pSocket
->m_Socket
, &WriteSet
) )
1636 socklen_t nErrorSize
= sizeof( nErrorCode
);
1640 nSockOpt
= getsockopt ( pSocket
->m_Socket
, SOL_SOCKET
, SO_ERROR
,
1641 &nErrorCode
, &nErrorSize
);
1642 if ( (nSockOpt
== 0) && (nErrorCode
== 0))
1643 Result
= osl_Socket_Ok
;
1645 Result
= osl_Socket_Error
;
1649 Result
= osl_Socket_Error
;
1652 else if (ReadyHandles
< 0) /* error */
1654 if (errno
== EBADF
) /* most probably interrupted by close() */
1656 /* do not access pSockImpl because it is about to be or */
1657 /* already destroyed */
1658 return osl_Socket_Interrupted
;
1662 pSocket
->m_nLastError
=errno
;
1663 Result
= osl_Socket_Error
;
1668 pSocket
->m_nLastError
=errno
;
1669 Result
= osl_Socket_TimedOut
;
1672 osl_enableNonBlockingMode(pSocket
, sal_False
);
1677 oslSocket SAL_CALL
osl_acceptConnectionOnSocket(oslSocket pSocket
,
1678 oslSocketAddr
* ppAddr
)
1680 struct sockaddr Addr
;
1681 int Connection
, Flags
;
1682 oslSocket pConnectionSockImpl
;
1684 socklen_t AddrLen
= sizeof(struct sockaddr
);
1685 OSL_ASSERT(pSocket
);
1691 pSocket
->m_nLastError
=0;
1693 pSocket
->m_bIsAccepting
= sal_True
;
1696 if( ppAddr
&& *ppAddr
)
1698 osl_destroySocketAddr( *ppAddr
);
1702 /* prevent Linux EINTR behaviour */
1705 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
1706 } while (Connection
== -1 && errno
== EINTR
);
1708 /* accept failed? */
1709 if( Connection
== OSL_SOCKET_ERROR
)
1711 pSocket
->m_nLastError
=errno
;
1712 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'",strerror(errno
));
1715 pSocket
->m_bIsAccepting
= sal_False
;
1720 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
1723 if ( pSocket
->m_bIsInShutdown
== sal_True
)
1726 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept");
1733 *ppAddr
= __osl_createSocketAddrFromSystem(&Addr
);
1737 pConnectionSockImpl
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1739 /* set close-on-exec flag */
1740 if ((Flags
= fcntl(Connection
, F_GETFD
, 0)) != -1)
1742 Flags
|= FD_CLOEXEC
;
1743 if (fcntl(Connection
, F_SETFD
, Flags
) == -1)
1745 pSocket
->m_nLastError
=errno
;
1746 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
1753 pConnectionSockImpl
->m_Socket
= Connection
;
1754 pConnectionSockImpl
->m_nLastError
= 0;
1756 pConnectionSockImpl
->m_bIsAccepting
= sal_False
;
1758 pSocket
->m_bIsAccepting
= sal_False
;
1760 return pConnectionSockImpl
;
1763 sal_Int32 SAL_CALL
osl_receiveSocket(oslSocket pSocket
,
1765 sal_uInt32 BytesToRead
,
1766 oslSocketMsgFlag Flag
)
1770 OSL_ASSERT(pSocket
);
1773 OSL_TRACE("osl_receiveSocket : Invalid socket");
1777 pSocket
->m_nLastError
=0;
1781 nRead
= recv(pSocket
->m_Socket
,
1784 MSG_FLAG_TO_NATIVE(Flag
));
1785 } while ( nRead
< 0 && errno
== EINTR
);
1789 pSocket
->m_nLastError
=errno
;
1790 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,strerror(errno
));
1792 else if ( nRead
== 0 )
1794 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
1800 sal_Int32 SAL_CALL
osl_receiveFromSocket(oslSocket pSocket
,
1801 oslSocketAddr pSenderAddr
,
1803 sal_uInt32 BufferSize
,
1804 oslSocketMsgFlag Flag
)
1807 struct sockaddr
*pSystemSockAddr
= 0;
1808 socklen_t AddrLen
= 0;
1811 AddrLen
= sizeof( struct sockaddr
);
1812 pSystemSockAddr
= &(pSenderAddr
->m_sockaddr
);
1815 OSL_ASSERT(pSocket
);
1818 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
1822 pSocket
->m_nLastError
=0;
1824 nRead
= recvfrom(pSocket
->m_Socket
,
1827 MSG_FLAG_TO_NATIVE(Flag
),
1833 pSocket
->m_nLastError
=errno
;
1834 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead
,strerror(errno
));
1836 else if ( nRead
== 0 )
1838 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
1844 sal_Int32 SAL_CALL
osl_sendSocket(oslSocket pSocket
,
1845 const void* pBuffer
,
1846 sal_uInt32 BytesToSend
,
1847 oslSocketMsgFlag Flag
)
1851 OSL_ASSERT(pSocket
);
1854 OSL_TRACE("osl_sendSocket : Invalid socket");
1858 pSocket
->m_nLastError
=0;
1862 nWritten
= send(pSocket
->m_Socket
,
1865 MSG_FLAG_TO_NATIVE(Flag
));
1866 } while ( nWritten
< 0 && errno
== EINTR
);
1870 pSocket
->m_nLastError
=errno
;
1871 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,strerror(errno
));
1873 else if ( nWritten
== 0 )
1875 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,"EOL");
1881 sal_Int32 SAL_CALL
osl_sendToSocket(oslSocket pSocket
,
1882 oslSocketAddr ReceiverAddr
,
1883 const void* pBuffer
,
1884 sal_uInt32 BytesToSend
,
1885 oslSocketMsgFlag Flag
)
1889 struct sockaddr
*pSystemSockAddr
= 0;
1893 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
1894 AddrLen
= sizeof( struct sockaddr
);
1897 OSL_ASSERT(pSocket
);
1900 OSL_TRACE("osl_sendToSocket : Invalid socket");
1904 pSocket
->m_nLastError
=0;
1906 /* ReceiverAddr might be 0 when used on a connected socket. */
1907 /* Then sendto should behave like send. */
1909 nWritten
= sendto(pSocket
->m_Socket
,
1912 MSG_FLAG_TO_NATIVE(Flag
),
1918 pSocket
->m_nLastError
=errno
;
1919 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,strerror(errno
));
1921 else if ( nWritten
== 0 )
1923 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,"EOL");
1929 sal_Int32 SAL_CALL
osl_readSocket (
1930 oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
1932 sal_uInt8
* Ptr
= (sal_uInt8
*)pBuffer
;
1933 sal_uInt32 BytesRead
= 0;
1934 sal_uInt32 BytesToRead
= n
;
1936 OSL_ASSERT( pSocket
);
1938 /* loop until all desired bytes were read or an error occurred */
1939 while (BytesToRead
> 0)
1942 RetVal
= osl_receiveSocket(pSocket
,
1945 osl_Socket_MsgNormal
);
1947 /* error occurred? */
1953 BytesToRead
-= RetVal
;
1954 BytesRead
+= RetVal
;
1961 sal_Int32 SAL_CALL
osl_writeSocket(
1962 oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
1964 /* loop until all desired bytes were send or an error occurred */
1965 sal_uInt32 BytesSend
= 0;
1966 sal_uInt32 BytesToSend
= n
;
1967 sal_uInt8
*Ptr
= ( sal_uInt8
* )pBuffer
;
1969 OSL_ASSERT( pSocket
);
1971 while (BytesToSend
> 0)
1975 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
1977 /* error occurred? */
1983 BytesToSend
-= RetVal
;
1984 BytesSend
+= RetVal
;
1991 #ifdef HAVE_POLL_H /* poll() */
1993 sal_Bool
__osl_socket_poll (
1995 const TimeValue
* pTimeout
,
2002 OSL_ASSERT(0 != pSocket
);
2004 return sal_False
; /* EINVAL */
2006 pSocket
->m_nLastError
= 0;
2008 fds
.fd
= pSocket
->m_Socket
;
2009 fds
.events
= nEvent
;
2015 /* Convert to [ms] */
2016 timeout
= pTimeout
->Seconds
* 1000;
2017 timeout
+= pTimeout
->Nanosec
/ (1000 * 1000);
2020 result
= poll (&fds
, 1, timeout
);
2023 pSocket
->m_nLastError
= errno
;
2024 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2025 errno
, strerror(errno
));
2034 return ((fds
.revents
& nEvent
) == nEvent
);
2037 #else /* select() */
2039 sal_Bool
__osl_socket_poll (
2041 const TimeValue
* pTimeout
,
2048 OSL_ASSERT(0 != pSocket
);
2050 return sal_False
; /* EINVAL */
2052 pSocket
->m_nLastError
= 0;
2055 FD_SET(pSocket
->m_Socket
, &fds
);
2059 /* Convert to 'timeval' */
2060 tv
.tv_sec
= pTimeout
->Seconds
;
2061 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000;
2065 pSocket
->m_Socket
+ 1,
2066 (nEvent
== POLLIN
) ? PTR_FD_SET(fds
) : NULL
,
2067 (nEvent
== POLLOUT
) ? PTR_FD_SET(fds
) : NULL
,
2068 (nEvent
== POLLPRI
) ? PTR_FD_SET(fds
) : NULL
,
2069 (pTimeout
) ? &tv
: NULL
);
2073 pSocket
->m_nLastError
= errno
;
2074 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2075 errno
, strerror(errno
));
2084 return (FD_ISSET(pSocket
->m_Socket
, &fds
) ? sal_True
: sal_False
);
2087 #endif /* HAVE_POLL_H */
2089 sal_Bool SAL_CALL
osl_isReceiveReady (
2090 oslSocket pSocket
, const TimeValue
* pTimeout
)
2092 OSL_ASSERT(pSocket
);
2093 if (pSocket
== NULL
)
2099 return __osl_socket_poll (pSocket
, pTimeout
, POLLIN
);
2102 sal_Bool SAL_CALL
osl_isSendReady (
2103 oslSocket pSocket
, const TimeValue
* pTimeout
)
2105 OSL_ASSERT(pSocket
);
2106 if (pSocket
== NULL
)
2112 return __osl_socket_poll (pSocket
, pTimeout
, POLLOUT
);
2115 sal_Bool SAL_CALL
osl_isExceptionPending (
2116 oslSocket pSocket
, const TimeValue
* pTimeout
)
2118 OSL_ASSERT(pSocket
);
2119 if (pSocket
== NULL
)
2125 return __osl_socket_poll (pSocket
, pTimeout
, POLLPRI
);
2128 sal_Bool SAL_CALL
osl_shutdownSocket(oslSocket pSocket
,
2129 oslSocketDirection Direction
)
2133 OSL_ASSERT(pSocket
);
2139 pSocket
->m_nLastError
=0;
2141 nRet
=shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
));
2144 pSocket
->m_nLastError
=errno
;
2145 OSL_TRACE("shutdown error '%s'",strerror(errno
));
2150 sal_Int32 SAL_CALL
osl_getSocketOption(oslSocket pSocket
,
2151 oslSocketOptionLevel Level
,
2152 oslSocketOption Option
,
2154 sal_uInt32 BufferLen
)
2156 socklen_t nOptLen
= (socklen_t
) BufferLen
;
2158 OSL_ASSERT(pSocket
);
2164 pSocket
->m_nLastError
=0;
2166 if(getsockopt(pSocket
->m_Socket
,
2167 OPTION_LEVEL_TO_NATIVE(Level
),
2168 OPTION_TO_NATIVE(Option
),
2172 pSocket
->m_nLastError
=errno
;
2179 sal_Bool SAL_CALL
osl_setSocketOption(oslSocket pSocket
,
2180 oslSocketOptionLevel Level
,
2181 oslSocketOption Option
,
2183 sal_uInt32 BufferLen
)
2187 OSL_ASSERT(pSocket
);
2193 pSocket
->m_nLastError
=0;
2195 nRet
= setsockopt(pSocket
->m_Socket
,
2196 OPTION_LEVEL_TO_NATIVE(Level
),
2197 OPTION_TO_NATIVE(Option
),
2203 pSocket
->m_nLastError
=errno
;
2210 sal_Bool SAL_CALL
osl_enableNonBlockingMode(oslSocket pSocket
,
2216 OSL_ASSERT(pSocket
);
2222 pSocket
->m_nLastError
=0;
2224 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2227 flags
|= O_NONBLOCK
;
2229 flags
&= ~(O_NONBLOCK
);
2231 nRet
= fcntl(pSocket
->m_Socket
, F_SETFL
, flags
);
2235 pSocket
->m_nLastError
=errno
;
2242 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
2246 OSL_ASSERT(pSocket
);
2252 pSocket
->m_nLastError
=0;
2254 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2256 if (flags
== -1 || !(flags
& O_NONBLOCK
))
2262 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
2265 socklen_t TypeSize
= sizeof(Type
);
2267 OSL_ASSERT(pSocket
);
2270 return osl_Socket_TypeInvalid
;
2273 pSocket
->m_nLastError
=0;
2275 if(getsockopt(pSocket
->m_Socket
,
2276 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
2277 OPTION_TO_NATIVE(osl_Socket_OptionType
),
2282 pSocket
->m_nLastError
=errno
;
2283 return osl_Socket_TypeInvalid
;
2286 return TYPE_FROM_NATIVE(Type
);
2290 void SAL_CALL
osl_getLastSocketErrorDescription(oslSocket Socket
, rtl_uString
**ustrError
)
2292 sal_Char pszError
[1024];
2296 osl_psz_getLastSocketErrorDescription(Socket
,pszError
,sizeof(pszError
));
2298 rtl_uString_newFromAscii(ustrError
,pszError
);
2303 void SAL_CALL
osl_psz_getLastSocketErrorDescription(oslSocket pSocket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
)
2305 /* make sure pBuffer will be a zero-terminated string even when strncpy has to cut */
2306 pBuffer
[BufferSize
-1]= '\0';
2310 strncpy(pBuffer
, strerror(EINVAL
), BufferSize
-1);
2314 strncpy(pBuffer
, strerror(pSocket
->m_nLastError
), BufferSize
-1);
2318 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket pSocket
)
2322 return ERROR_FROM_NATIVE(EINVAL
);
2325 return ERROR_FROM_NATIVE(pSocket
->m_nLastError
);
2328 typedef struct _TSocketSetImpl
2330 int m_MaxHandle
; /* for select(), the largest descriptor in the set */
2331 fd_set m_Set
; /* the set of descriptors */
2335 oslSocketSet SAL_CALL
osl_createSocketSet()
2337 TSocketSetImpl
* pSet
;
2339 pSet
= (TSocketSetImpl
*)malloc(sizeof(TSocketSetImpl
));
2345 pSet
->m_MaxHandle
= 0;
2346 FD_ZERO(&pSet
->m_Set
);
2349 return (oslSocketSet
)pSet
;
2352 void SAL_CALL
osl_destroySocketSet(oslSocketSet Set
)
2358 void SAL_CALL
osl_clearSocketSet(oslSocketSet Set
)
2360 TSocketSetImpl
* pSet
;
2367 pSet
= (TSocketSetImpl
*)Set
;
2368 pSet
->m_MaxHandle
= 0;
2370 FD_ZERO(&pSet
->m_Set
);
2373 void SAL_CALL
osl_addToSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2375 TSocketSetImpl
* pSet
;
2378 OSL_ASSERT(pSocket
);
2380 if ( Set
== 0 || pSocket
== 0)
2385 pSet
= (TSocketSetImpl
*)Set
;
2387 /* correct max handle */
2388 if(pSocket
->m_Socket
> pSet
->m_MaxHandle
)
2389 pSet
->m_MaxHandle
= pSocket
->m_Socket
;
2390 FD_SET(pSocket
->m_Socket
, &pSet
->m_Set
);
2394 void SAL_CALL
osl_removeFromSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2396 TSocketSetImpl
* pSet
;
2399 OSL_ASSERT(pSocket
);
2401 if ( Set
== 0 || pSocket
== 0)
2406 pSet
= (TSocketSetImpl
*)Set
;
2408 /* correct max handle */
2409 if(pSocket
->m_Socket
== pSet
->m_MaxHandle
)
2411 /* not optimal, since the next used descriptor might be */
2412 /* much smaller than m_Socket-1, but it will do */
2413 pSet
->m_MaxHandle
--;
2414 if(pSet
->m_MaxHandle
< 0)
2416 pSet
->m_MaxHandle
= 0; /* avoid underflow */
2420 FD_CLR(pSocket
->m_Socket
, &pSet
->m_Set
);
2423 sal_Bool SAL_CALL
osl_isInSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2425 TSocketSetImpl
* pSet
;
2428 OSL_ASSERT(pSocket
);
2429 if ( Set
== 0 || pSocket
== 0 )
2434 pSet
= (TSocketSetImpl
*)Set
;
2436 return (FD_ISSET(pSocket
->m_Socket
, &pSet
->m_Set
) != 0);
2439 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents(oslSocketSet IncomingSet
,
2440 oslSocketSet OutgoingSet
,
2441 oslSocketSet OutOfBandSet
,
2442 const TimeValue
* pTimeout
)
2446 TSocketSetImpl
* pInSet
;
2447 TSocketSetImpl
* pOutSet
;
2448 TSocketSetImpl
* pOOBSet
;
2452 /* non-blocking call */
2453 tv
.tv_sec
= pTimeout
->Seconds
;
2454 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
2457 /* map opaque data to impl-types */
2458 pInSet
= (TSocketSetImpl
*)IncomingSet
;
2459 pOutSet
= (TSocketSetImpl
*)OutgoingSet
;
2460 pOOBSet
= (TSocketSetImpl
*)OutOfBandSet
;
2462 /* get max handle from all sets */
2464 MaxHandle
= pInSet
->m_MaxHandle
;
2466 if (pOutSet
&& (pOutSet
->m_MaxHandle
> MaxHandle
))
2467 MaxHandle
= pOutSet
->m_MaxHandle
;
2469 if (pOOBSet
&& (pOOBSet
->m_MaxHandle
> MaxHandle
))
2470 MaxHandle
= pOOBSet
->m_MaxHandle
;
2472 return select(MaxHandle
+1,
2473 pInSet
? PTR_FD_SET(pInSet
->m_Set
) : 0,
2474 pOutSet
? PTR_FD_SET(pOutSet
->m_Set
) : 0,
2475 pOOBSet
? PTR_FD_SET(pOOBSet
->m_Set
) : 0,
2476 pTimeout
? &tv
: 0);
2479 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */