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 */
57 /* defines for shutdown */
64 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
65 I refrained from using sockaddr_in because of possible further
66 extensions of this socket-interface (IP-NG?).
67 The intention was to hide all Berkeley data-structures from
68 direct access past the osl-interface.
70 The current implementation is internet (IP) centered. All
71 the constructor-functions (osl_create...) take parameters
72 that will probably make sense only in the IP-environment
73 (e.g. because of using the dotted-address-format).
75 If the interface will be extended to host other protocol-
76 families, I expect no externally visible changes in the
77 existing functions. You'll probably need only new
78 constructor-functions who take the different address
79 formats into consideration (maybe a long dotted address
83 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
84 /* are the same! I don't like it very much but see no other easy way to */
85 /* conceal the struct sockaddr from the eyes of the user. */
88 #define OSL_INVALID_SOCKET -1
89 #define OSL_SOCKET_ERROR -1
92 /* Buffer size for gethostbyname */
93 #define MAX_HOSTBUFFER_SIZE 2048
95 /*****************************************************************************/
96 /* enum oslAddrFamily */
97 /*****************************************************************************/
100 static unsigned long FamilyMap
[]= {
101 AF_INET
, /* osl_Socket_FamilyInet */
102 AF_IPX
, /* osl_Socket_FamilyIpx */
103 0 /* osl_Socket_FamilyInvalid */
107 static oslAddrFamily
osl_AddrFamilyFromNative(sal_uInt32 nativeType
)
109 oslAddrFamily i
= (oslAddrFamily
)0;
111 while(i
!= osl_Socket_FamilyInvalid
)
113 if(FamilyMap
[i
] == nativeType
)
115 i
= (oslAddrFamily
) ( i
+ 1 );
122 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
123 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
125 /*****************************************************************************/
126 /* enum oslProtocol */
127 /*****************************************************************************/
130 static sal_uInt32 ProtocolMap
[]= {
131 0, /* osl_Socket_ProtocolIp */
132 NSPROTO_IPX
, /* osl_Socket_ProtocolIpx */
133 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
134 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpxII */
135 0 /* osl_Socket_ProtocolInvalid */
140 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
142 oslProtocol i= (oslProtocol)0;
144 while(i != osl_Socket_ProtocolInvalid)
146 if(ProtocolMap[i] == nativeType)
148 i = (oslProtocol) ( i + 1);
156 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
159 /*****************************************************************************/
160 /* enum oslSocketType */
161 /*****************************************************************************/
164 static sal_uInt32 TypeMap
[]= {
165 SOCK_STREAM
, /* osl_Socket_TypeStream */
166 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
167 SOCK_RAW
, /* osl_Socket_TypeRaw */
168 SOCK_RDM
, /* osl_Socket_TypeRdm */
169 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
170 0 /* osl_Socket_TypeInvalid */
174 static oslSocketType
osl_SocketTypeFromNative(sal_uInt32 nativeType
)
176 oslSocketType i
= (oslSocketType
)0;
178 while(i
!= osl_Socket_TypeInvalid
)
180 if(TypeMap
[i
] == nativeType
)
182 i
= (oslSocketType
)(i
+ 1);
189 #define TYPE_TO_NATIVE(x) TypeMap[x]
190 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
193 /*****************************************************************************/
194 /* enum oslSocketOption */
195 /*****************************************************************************/
198 static sal_uInt32 OptionMap
[]= {
199 SO_DEBUG
, /* osl_Socket_OptionDebug */
200 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
201 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
202 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
203 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
204 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
205 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
206 SO_LINGER
, /* osl_Socket_OptionLinger */
207 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
208 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
209 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
210 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
211 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
212 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
213 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
214 SO_ERROR
, /* osl_Socket_OptionError */
215 SO_TYPE
, /* osl_Socket_OptionType */
216 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
217 0 /* osl_Socket_OptionInvalid */
222 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
224 oslSocketOption i= (oslSocketOption)0;
226 while(i != osl_Socket_OptionInvalid)
228 if(OptionMap[i] == nativeType)
230 i = (oslSocketOption) ( i + 1 );
237 #define OPTION_TO_NATIVE(x) OptionMap[x]
239 /*****************************************************************************/
240 /* enum oslSocketOptionLevel */
241 /*****************************************************************************/
243 static sal_uInt32 OptionLevelMap
[]= {
244 SOL_SOCKET
, /* osl_Socket_LevelSocket */
245 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
246 0 /* osl_Socket_LevelInvalid */
251 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
253 oslSocketOptionLevel i= (oslSocketOptionLevel)0;
255 while(i != osl_Socket_LevelInvalid)
257 if(OptionLevelMap[i] == nativeType)
259 i = (oslSocketOptionLevel) ( i + 1 );
266 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
268 /*****************************************************************************/
269 /* enum oslSocketMsgFlag */
270 /*****************************************************************************/
272 static sal_uInt32 SocketMsgFlagMap
[]= {
273 0, /* osl_Socket_MsgNormal */
274 MSG_OOB
, /* osl_Socket_MsgOOB */
275 MSG_PEEK
, /* osl_Socket_MsgPeek */
276 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
277 MSG_MAXIOVLEN
, /* osl_Socket_MsgMaxIOVLen */
278 0 /* osl_Socket_MsgInvalid */
283 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
285 oslSocketMsgFlag i= (oslSocketMsgFlag)0;
287 while(i != osl_Socket_MsgInvalid)
289 if(SocketMsgFlagMap[i] == nativeType)
291 i = (oslSocketMsgFlag) ( i + 1 );
299 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
301 /*****************************************************************************/
302 /* enum oslSocketDirection */
303 /*****************************************************************************/
305 static sal_uInt32 SocketDirection
[]= {
306 SD_RECEIVE
, /* osl_Socket_DirRead */
307 SD_SEND
, /* osl_Socket_DirWrite */
308 SD_BOTH
, /* osl_Socket_DirReadWrite */
309 0 /* osl_Socket_DirInvalid */
314 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
316 oslSocketDirection i= (oslSocketDirection)0;
318 while(i != osl_Socket_DirInvalid)
320 if(SocketDirection[i] == nativeType)
322 i = (oslSocketDirection) ( i + 1 );
330 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
332 /*****************************************************************************/
333 /* enum oslSocketError */
334 /*****************************************************************************/
339 oslSocketError error
;
341 { 0, osl_Socket_E_None
}, /* no error */
342 { ENOTSOCK
, osl_Socket_E_NotSocket
}, /* Socket operation on non-socket */
343 { EDESTADDRREQ
, osl_Socket_E_DestAddrReq
}, /* Destination address required */
344 { EMSGSIZE
, osl_Socket_E_MsgSize
}, /* Message too long */
345 { EPROTOTYPE
, osl_Socket_E_Prototype
}, /* Protocol wrong type for socket */
346 { ENOPROTOOPT
, osl_Socket_E_NoProtocol
}, /* Protocol not available */
347 { EPROTONOSUPPORT
, osl_Socket_E_ProtocolNoSupport
}, /* Protocol not supported */
348 { ESOCKTNOSUPPORT
, osl_Socket_E_TypeNoSupport
}, /* Socket type not supported */
349 { EOPNOTSUPP
, osl_Socket_E_OpNotSupport
}, /* Operation not supported on socket */
350 { EPFNOSUPPORT
, osl_Socket_E_PfNoSupport
}, /* Protocol family not supported */
351 { EAFNOSUPPORT
, osl_Socket_E_AfNoSupport
}, /* Address family not supported by */
352 /* protocol family */
353 { EADDRINUSE
, osl_Socket_E_AddrInUse
}, /* Address already in use */
354 { EADDRNOTAVAIL
, osl_Socket_E_AddrNotAvail
}, /* Can't assign requested address */
355 { ENETDOWN
, osl_Socket_E_NetDown
}, /* Network is down */
356 { ENETUNREACH
, osl_Socket_E_NetUnreachable
}, /* Network is unreachable */
357 { ENETRESET
, osl_Socket_E_NetReset
}, /* Network dropped connection because */
359 { ECONNABORTED
, osl_Socket_E_ConnAborted
}, /* Software caused connection abort */
360 { ECONNRESET
, osl_Socket_E_ConnReset
}, /* Connection reset by peer */
361 { ENOBUFS
, osl_Socket_E_NoBufferSpace
}, /* No buffer space available */
362 { EISCONN
, osl_Socket_E_IsConnected
}, /* Socket is already connected */
363 { ENOTCONN
, osl_Socket_E_NotConnected
}, /* Socket is not connected */
364 { ESHUTDOWN
, osl_Socket_E_Shutdown
}, /* Can't send after socket shutdown */
365 { ETOOMANYREFS
, osl_Socket_E_TooManyRefs
}, /* Too many references: can't splice */
366 { ETIMEDOUT
, osl_Socket_E_TimedOut
}, /* Connection timed out */
367 { ECONNREFUSED
, osl_Socket_E_ConnRefused
}, /* Connection refused */
368 { EHOSTDOWN
, osl_Socket_E_HostDown
}, /* Host is down */
369 { EHOSTUNREACH
, osl_Socket_E_HostUnreachable
}, /* No route to host */
370 { EWOULDBLOCK
, osl_Socket_E_WouldBlock
}, /* call would block on non-blocking socket */
371 { EALREADY
, osl_Socket_E_Already
}, /* operation already in progress */
372 { EINPROGRESS
, osl_Socket_E_InProgress
}, /* operation now in progress */
373 { EAGAIN
, osl_Socket_E_WouldBlock
}, /* same as EWOULDBLOCK */
374 { -1, osl_Socket_E_InvalidError
}
379 static int osl_NativeFromSocketError(oslSocketError errorCode)
383 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
384 (SocketError[i].error != errorCode)) i++;
386 return SocketError[i].errcode;
391 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
395 while ((SocketError
[i
].error
!= osl_Socket_E_InvalidError
) &&
396 (SocketError
[i
].errcode
!= nativeType
)) i
++;
398 return SocketError
[i
].error
;
402 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
404 /*****************************************************************************/
405 /* local function prototypes */
406 /*****************************************************************************/
408 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
409 const sal_Char
* pszDottedAddr
, sal_Int32 Port
);
411 oslSocketAddr SAL_CALL
osl_psz_createIpxSocketAddr (
412 const sal_Char NetNumber
[4],
413 const sal_Char NodeNumber
[6],
414 sal_uInt32 SocketNumber
);
416 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
417 const sal_Char
*pszHostname
, const oslSocketAddr Addr
);
419 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (
420 const sal_Char
*pszHostname
);
422 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (
423 const oslHostAddr Addr
);
425 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
426 sal_Char
*pBuffer
, sal_uInt32 nBufLen
);
428 oslSocketAddr SAL_CALL
osl_psz_resolveHostname (
429 const sal_Char
* pszHostname
);
431 sal_Int32 SAL_CALL
osl_psz_getServicePort (
432 const sal_Char
* pszServicename
, const sal_Char
* pszProtocol
);
434 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr (
435 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
437 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr (
438 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
440 void SAL_CALL
osl_psz_getLastSocketErrorDescription (
441 oslSocket Socket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
);
443 /*****************************************************************************/
444 /* osl_create/destroy-SocketImpl */
445 /*****************************************************************************/
447 #if OSL_DEBUG_LEVEL > 1
448 static sal_uInt32 g_nSocketImpl
= 0;
449 static sal_uInt32 g_nSocketAddr
= 0;
451 /* sorry, must be implemented otherwise */
453 #endif /* OSL_DEBUG_LEVEL */
456 oslSocket
__osl_createSocketImpl(int Socket
)
460 pSocket
= (oslSocket
)calloc(1, sizeof(struct oslSocketImpl
));
462 pSocket
->m_Socket
= Socket
;
463 pSocket
->m_nLastError
= 0;
464 pSocket
->m_nRefCount
= 1;
467 pSocket
->m_bIsAccepting
= sal_False
;
470 #if OSL_DEBUG_LEVEL > 1
476 void __osl_destroySocketImpl(oslSocket Socket
)
479 free((struct oslSocketImpl
*) Socket
);
480 #if OSL_DEBUG_LEVEL > 1
485 static oslSocketAddr
__osl_createSocketAddr( )
487 oslSocketAddr pAddr
= (oslSocketAddr
) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
));
488 #if OSL_DEBUG_LEVEL > 1
494 static oslSocketAddr
__osl_createSocketAddrWithFamily(
495 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
499 OSL_ASSERT( family
== osl_Socket_FamilyInet
);
501 pAddr
= __osl_createSocketAddr();
504 case osl_Socket_FamilyInet
:
506 struct sockaddr_in
* pInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
508 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
509 pInetAddr
->sin_addr
.s_addr
= nAddr
;
510 pInetAddr
->sin_port
= (sal_uInt16
)(port
&0xffff);
514 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
519 static oslSocketAddr
__osl_createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
521 oslSocketAddr pAddr
= __osl_createSocketAddr();
522 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( struct sockaddr
) );
526 static void __osl_destroySocketAddr( oslSocketAddr addr
)
528 #if OSL_DEBUG_LEVEL > 1
531 rtl_freeMemory( addr
);
534 /*****************************************************************************/
535 /* osl_createEmptySocketAddr */
536 /*****************************************************************************/
537 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
539 oslSocketAddr pAddr
= 0;
541 /* is it an internet-Addr? */
542 if (Family
== osl_Socket_FamilyInet
)
544 pAddr
= __osl_createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
548 pAddr
= __osl_createSocketAddrWithFamily( Family
, 0 , 0 );
554 /*****************************************************************************/
555 /* osl_copySocketAddr */
556 /*****************************************************************************/
557 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
559 oslSocketAddr pCopy
= 0;
562 pCopy
= __osl_createSocketAddr();
565 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
570 /*****************************************************************************/
571 /* osl_isEqualSocketAddr */
572 /*****************************************************************************/
573 sal_Bool SAL_CALL
osl_isEqualSocketAddr (
577 struct sockaddr
* pAddr1
= NULL
;
578 struct sockaddr
* pAddr2
= NULL
;
582 pAddr1
= &(Addr1
->m_sockaddr
);
583 pAddr2
= &(Addr2
->m_sockaddr
);
585 if (pAddr1
== pAddr2
)
590 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
592 switch (pAddr1
->sa_family
)
596 struct sockaddr_in
* pInetAddr1
= (struct sockaddr_in
*)pAddr1
;
597 struct sockaddr_in
* pInetAddr2
= (struct sockaddr_in
*)pAddr2
;
599 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
600 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
601 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
607 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
615 /*****************************************************************************/
616 /* osl_createInetBroadcastAddr */
617 /*****************************************************************************/
618 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
619 rtl_uString
*strDottedAddr
,
622 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
625 if (strDottedAddr
&& strDottedAddr
->length
)
627 /* Dotted host address for limited broadcast */
628 rtl_String
*pDottedAddr
= NULL
;
631 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
632 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
634 nAddr
= inet_addr (pDottedAddr
->buffer
);
635 rtl_string_release (pDottedAddr
);
638 if (nAddr
!= OSL_INADDR_NONE
)
640 /* Limited broadcast */
641 nAddr
= ntohl(nAddr
);
642 if (IN_CLASSA(nAddr
))
644 nAddr
&= IN_CLASSA_NET
;
645 nAddr
|= IN_CLASSA_HOST
;
647 else if (IN_CLASSB(nAddr
))
649 nAddr
&= IN_CLASSB_NET
;
650 nAddr
|= IN_CLASSB_HOST
;
652 else if (IN_CLASSC(nAddr
))
654 nAddr
&= IN_CLASSC_NET
;
655 nAddr
|= IN_CLASSC_HOST
;
659 /* No broadcast in class D */
660 return ((oslSocketAddr
)NULL
);
662 nAddr
= htonl(nAddr
);
665 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
), nAddr
);
669 /*****************************************************************************/
670 /* osl_createInetSocketAddr */
671 /*****************************************************************************/
672 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
673 rtl_uString
*ustrDottedAddr
,
676 rtl_String
* strDottedAddr
=0;
678 sal_Char
* pszDottedAddr
=0;
680 if ( ustrDottedAddr
!= 0 )
682 rtl_uString2String( &strDottedAddr
,
683 rtl_uString_getStr(ustrDottedAddr
),
684 rtl_uString_getLength(ustrDottedAddr
),
685 RTL_TEXTENCODING_UTF8
,
686 OUSTRING_TO_OSTRING_CVTFLAGS
);
687 pszDottedAddr
= rtl_string_getStr(strDottedAddr
);
691 Addr
= osl_psz_createInetSocketAddr(pszDottedAddr
, Port
);
693 if ( strDottedAddr
!= 0 )
695 rtl_string_release(strDottedAddr
);
701 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
702 const sal_Char
* pszDottedAddr
,
705 oslSocketAddr pAddr
= 0;
706 sal_Int32 Addr
= inet_addr(pszDottedAddr
);
709 /* valid dotted addr */
710 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
) , Addr
);
715 /*****************************************************************************/
716 /* osl_setAddrOfSocketAddr */
717 /*****************************************************************************/
718 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
720 oslSocketResult res
= osl_Socket_Error
;
723 OSL_ASSERT( pByteSeq
);
725 if( pAddr
&& pByteSeq
)
727 struct sockaddr_in
* pSystemInetAddr
;
729 OSL_ASSERT( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
730 OSL_ASSERT( pByteSeq
->nElements
== 4 );
732 pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
733 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
739 /*****************************************************************************/
740 /* osl_getAddrOfSocketAddr */
741 /*****************************************************************************/
742 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
744 oslSocketResult res
= osl_Socket_Error
;
747 OSL_ASSERT( ppByteSeq
);
749 if( pAddr
&& ppByteSeq
)
751 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
752 rtl_byte_sequence_constructFromArray( ppByteSeq
, (sal_Int8
*) &(pSystemInetAddr
->sin_addr
),4);
759 /*****************************************************************************/
760 /* _osl_getFullQualifiedDomainName */
761 /*****************************************************************************/
763 /** try to figure out a full-qualified hostname, by adding the current domain
764 as given by the domainname program to the given hostname.
765 This function MUST NOT call gethostbyname since pHostName already points
766 to data returned by gethostname and would be garbled: use gethostname_r
770 /* wrap around different interfaces to reentrant gethostbyname */
771 static struct hostent
* _osl_gethostbyname_r (
772 const char *name
, struct hostent
*result
,
773 char *buffer
, int buflen
, int *h_errnop
)
775 #if defined(LINUX) || defined(ANDROID) || (defined(FREEBSD) && (__FreeBSD_version >= 601103)) || defined(DRAGONFLY)
776 struct hostent
*__result
; /* will be the same as result */
778 __error
= gethostbyname_r (name
, result
, buffer
, buflen
,
779 &__result
, h_errnop
);
780 return __error
? NULL
: __result
;
782 *h_errnop
= gethostbyname_r (name
, result
, (struct hostent_data
*)buffer
);
784 return *h_errnop
? NULL
: result
;
786 return gethostbyname_r( name
, result
, buffer
, buflen
, h_errnop
);
790 static sal_Char
* _osl_getFullQualifiedDomainName (const sal_Char
*pHostName
)
792 struct hostent aHostByName
;
793 struct hostent
*pHostByName
;
794 sal_Char pQualifiedHostBuffer
[ MAX_HOSTBUFFER_SIZE
];
795 sal_Char
*pFullQualifiedName
= NULL
;
798 pHostByName
= _osl_gethostbyname_r (
800 &aHostByName
, pQualifiedHostBuffer
,
801 sizeof(pQualifiedHostBuffer
), &nErrorNo
);
802 if (pHostByName
!= NULL
)
804 pFullQualifiedName
= strdup(pHostByName
->h_name
);
806 return pFullQualifiedName
;
808 /*****************************************************************************/
809 /* _osl_isFullQualifiedDomainName */
810 /*****************************************************************************/
811 static sal_Bool
_osl_isFullQualifiedDomainName (const sal_Char
*pHostName
)
813 /* a FQDN (aka 'hostname.domain.top_level_domain' )
814 * is a name which contains a dot '.' in it ( would
815 * match as well for 'hostname.' but is good enough
817 return (sal_Bool
)( strchr( pHostName
, (int)'.' ) != NULL
);
820 /*****************************************************************************/
822 /*****************************************************************************/
823 struct oslHostAddrImpl
826 oslSocketAddr pSockAddr
;
829 static oslHostAddr
_osl_hostentToHostAddr (const struct hostent
*he
)
831 oslHostAddr pAddr
= NULL
;
832 oslSocketAddr pSockAddr
= 0;
836 if ((he
== NULL
) || (he
->h_name
== NULL
) || (he
->h_addr_list
[0] == NULL
))
837 return ((oslHostAddr
)NULL
);
839 if (_osl_isFullQualifiedDomainName(he
->h_name
))
841 cn
= (sal_Char
*)malloc(strlen (he
->h_name
) + 1);
844 return ((oslHostAddr
)NULL
);
846 strcpy(cn
, he
->h_name
);
850 cn
=_osl_getFullQualifiedDomainName (he
->h_name
);
853 return ((oslHostAddr
)NULL
);
856 pSockAddr
= __osl_createSocketAddr();
857 OSL_ASSERT(pSockAddr
);
858 if (pSockAddr
== NULL
)
861 return ((oslHostAddr
)NULL
);
864 pSockAddr
->m_sockaddr
.sa_family
= he
->h_addrtype
;
865 if (pSockAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
867 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&(pSockAddr
->m_sockaddr
);
869 &(sin
->sin_addr
.s_addr
),
875 /* unknown address family */
876 /* future extensions for new families might be implemented here */
878 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.");
879 OSL_ASSERT(sal_False
);
881 __osl_destroySocketAddr( pSockAddr
);
883 return ((oslHostAddr
)NULL
);
886 pAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
890 __osl_destroySocketAddr( pSockAddr
);
892 return ((oslHostAddr
)NULL
);
895 pAddr
->pHostName
= cn
;
896 pAddr
->pSockAddr
= pSockAddr
;
901 /*****************************************************************************/
902 /* osl_createHostAddr */
903 /*****************************************************************************/
904 oslHostAddr SAL_CALL
osl_createHostAddr (
905 rtl_uString
*ustrHostname
,
906 const oslSocketAddr Addr
)
908 oslHostAddr HostAddr
;
909 rtl_String
* strHostname
=0;
910 sal_Char
* pszHostName
=0;
912 if ( ustrHostname
!= 0 )
914 rtl_uString2String( &strHostname
,
915 rtl_uString_getStr(ustrHostname
),
916 rtl_uString_getLength(ustrHostname
),
917 RTL_TEXTENCODING_UTF8
,
918 OUSTRING_TO_OSTRING_CVTFLAGS
);
919 pszHostName
= rtl_string_getStr(strHostname
);
922 HostAddr
= osl_psz_createHostAddr(pszHostName
,Addr
);
924 if ( strHostname
!= 0 )
926 rtl_string_release(strHostname
);
932 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
933 const sal_Char
*pszHostname
,
934 const oslSocketAddr pAddr
)
936 oslHostAddr pHostAddr
;
939 OSL_ASSERT(pszHostname
&& pAddr
);
940 if ((pszHostname
== NULL
) || (pAddr
== NULL
))
941 return ((oslHostAddr
)NULL
);
943 cn
= (sal_Char
*)malloc(strlen (pszHostname
) + 1);
946 return ((oslHostAddr
)NULL
);
948 strcpy (cn
, pszHostname
);
950 pHostAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
951 OSL_ASSERT(pHostAddr
);
952 if (pHostAddr
== NULL
)
955 return ((oslHostAddr
)NULL
);
958 pHostAddr
->pHostName
= cn
;
959 pHostAddr
->pSockAddr
= osl_copySocketAddr( pAddr
);
964 /*****************************************************************************/
965 /* osl_createHostAddrByName */
966 /*****************************************************************************/
967 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*ustrHostname
)
969 oslHostAddr HostAddr
;
970 rtl_String
* strHostname
=0;
971 sal_Char
* pszHostName
=0;
973 if ( ustrHostname
!= 0 )
975 rtl_uString2String( &strHostname
,
976 rtl_uString_getStr(ustrHostname
),
977 rtl_uString_getLength(ustrHostname
),
978 RTL_TEXTENCODING_UTF8
,
979 OUSTRING_TO_OSTRING_CVTFLAGS
);
980 pszHostName
=rtl_string_getStr(strHostname
);
983 HostAddr
= osl_psz_createHostAddrByName(pszHostName
);
985 if ( strHostname
!= 0 )
987 rtl_string_release(strHostname
);
993 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (const sal_Char
*pszHostname
)
997 sal_Char heBuffer
[ MAX_HOSTBUFFER_SIZE
];
1000 pHe
= _osl_gethostbyname_r (
1003 sizeof(heBuffer
), &nErrorNo
);
1005 return _osl_hostentToHostAddr (pHe
);
1008 /*****************************************************************************/
1009 /* osl_createHostAddrByAddr */
1010 /*****************************************************************************/
1011 oslHostAddr SAL_CALL
osl_createHostAddrByAddr (const oslSocketAddr pAddr
)
1016 return ((oslHostAddr
)NULL
);
1018 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1020 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1023 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
1024 return ((oslHostAddr
)NULL
);
1026 he
= gethostbyaddr((sal_Char
*)&(sin
->sin_addr
),
1027 sizeof (sin
->sin_addr
),
1029 return _osl_hostentToHostAddr (he
);
1032 return ((oslHostAddr
)NULL
);
1035 /*****************************************************************************/
1036 /* osl_copyHostAddr */
1037 /*****************************************************************************/
1038 oslHostAddr SAL_CALL
osl_copyHostAddr (const oslHostAddr pAddr
)
1043 return osl_psz_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
1045 return ((oslHostAddr
)NULL
);
1048 /*****************************************************************************/
1049 /* osl_getHostnameOfHostAddr */
1050 /*****************************************************************************/
1051 void SAL_CALL
osl_getHostnameOfHostAddr (
1052 const oslHostAddr Addr
,
1053 rtl_uString
**ustrHostname
)
1055 const sal_Char
* pHostname
=0;
1057 pHostname
= osl_psz_getHostnameOfHostAddr(Addr
);
1059 rtl_uString_newFromAscii (ustrHostname
, pHostname
);
1064 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr
)
1067 return pAddr
->pHostName
;
1072 /*****************************************************************************/
1073 /* osl_getSocketAddrOfHostAddr */
1074 /*****************************************************************************/
1075 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr
)
1080 return ((oslSocketAddr
)(pAddr
->pSockAddr
));
1085 /*****************************************************************************/
1086 /* osl_destroyHostAddr */
1087 /*****************************************************************************/
1088 void SAL_CALL
osl_destroyHostAddr (oslHostAddr pAddr
)
1092 if (pAddr
->pHostName
)
1093 free (pAddr
->pHostName
);
1094 if (pAddr
->pSockAddr
)
1095 osl_destroySocketAddr (pAddr
->pSockAddr
);
1100 /*****************************************************************************/
1101 /* osl_getLocalHostname */
1102 /*****************************************************************************/
1103 oslSocketResult SAL_CALL
osl_getLocalHostname(rtl_uString
**ustrLocalHostname
)
1105 oslSocketResult Result
;
1106 sal_Char pszHostname
[1024];
1108 pszHostname
[0] = '\0';
1110 Result
= osl_psz_getLocalHostname(pszHostname
,sizeof(pszHostname
));
1112 rtl_uString_newFromAscii(ustrLocalHostname
,pszHostname
);
1117 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
1118 sal_Char
*pBuffer
, sal_uInt32 nBufLen
)
1120 static sal_Char LocalHostname
[256] = "";
1122 if (strlen(LocalHostname
) == 0)
1124 const sal_Char
*pStr
;
1129 if (uname(&uts
) < 0)
1130 return osl_Socket_Error
;
1132 if ((strlen(uts
.nodename
) + 1) > nBufLen
)
1133 return osl_Socket_Error
;
1135 strncpy(LocalHostname
, uts
.nodename
, sizeof( LocalHostname
));
1136 #else /* BSD compatible */
1138 if (gethostname(LocalHostname
, sizeof(LocalHostname
)-1) != 0)
1139 return osl_Socket_Error
;
1140 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
1143 /* check if we have an FQDN */
1144 if (strchr(LocalHostname
, '.') == NULL
)
1148 /* no, determine it via dns */
1149 Addr
= osl_psz_createHostAddrByName(LocalHostname
);
1151 if ((pStr
= osl_psz_getHostnameOfHostAddr(Addr
)) != NULL
)
1153 strcpy(LocalHostname
, pStr
);
1155 osl_destroyHostAddr(Addr
);
1159 if (strlen(LocalHostname
) > 0)
1161 strncpy(pBuffer
, LocalHostname
, nBufLen
);
1162 pBuffer
[nBufLen
- 1] = '\0';
1164 return osl_Socket_Ok
;
1167 return osl_Socket_Error
;
1170 /*****************************************************************************/
1171 /* osl_resolveHostname */
1172 /*****************************************************************************/
1173 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
*ustrHostname
)
1176 rtl_String
* strHostname
=0;
1177 sal_Char
* pszHostName
=0;
1179 if ( ustrHostname
!= 0 )
1181 rtl_uString2String( &strHostname
,
1182 rtl_uString_getStr(ustrHostname
),
1183 rtl_uString_getLength(ustrHostname
),
1184 RTL_TEXTENCODING_UTF8
,
1185 OUSTRING_TO_OSTRING_CVTFLAGS
);
1186 pszHostName
= rtl_string_getStr(strHostname
);
1190 Addr
= osl_psz_resolveHostname(pszHostName
);
1192 if ( strHostname
!= 0 )
1194 rtl_string_release(strHostname
);
1202 oslSocketAddr SAL_CALL
osl_psz_resolveHostname(const sal_Char
* pszHostname
)
1204 struct oslHostAddrImpl
*pAddr
= (oslHostAddr
)osl_psz_createHostAddrByName(pszHostname
);
1208 oslSocketAddr SockAddr
= osl_copySocketAddr(pAddr
->pSockAddr
);
1210 osl_destroyHostAddr(pAddr
);
1215 return ((oslSocketAddr
)NULL
);
1218 /*****************************************************************************/
1219 /* osl_getServicePort */
1220 /*****************************************************************************/
1221 sal_Int32 SAL_CALL
osl_getServicePort(rtl_uString
*ustrServicename
, rtl_uString
*ustrProtocol
)
1224 rtl_String
* strServicename
=0;
1225 rtl_String
* strProtocol
=0;
1226 sal_Char
* pszServiceName
=0;
1227 sal_Char
* pszProtocol
=0;
1229 if ( ustrServicename
!= 0 )
1231 rtl_uString2String( &strServicename
,
1232 rtl_uString_getStr(ustrServicename
),
1233 rtl_uString_getLength(ustrServicename
),
1234 RTL_TEXTENCODING_UTF8
,
1235 OUSTRING_TO_OSTRING_CVTFLAGS
);
1236 pszServiceName
= rtl_string_getStr(strServicename
);
1239 if ( ustrProtocol
!= 0 )
1241 rtl_uString2String( &strProtocol
,
1242 rtl_uString_getStr(ustrProtocol
),
1243 rtl_uString_getLength(ustrProtocol
),
1244 RTL_TEXTENCODING_UTF8
,
1245 OUSTRING_TO_OSTRING_CVTFLAGS
);
1246 pszProtocol
= rtl_string_getStr(strProtocol
);
1249 nPort
= osl_psz_getServicePort(pszServiceName
,pszProtocol
);
1251 if ( strServicename
!= 0 )
1253 rtl_string_release(strServicename
);
1256 if ( strProtocol
!= 0 )
1258 rtl_string_release(strProtocol
);
1266 sal_Int32 SAL_CALL
osl_psz_getServicePort(const sal_Char
* pszServicename
,
1267 const sal_Char
* pszProtocol
)
1271 ps
= getservbyname(pszServicename
, pszProtocol
);
1274 return ntohs(ps
->s_port
);
1276 return OSL_INVALID_PORT
;
1279 /*****************************************************************************/
1280 /* osl_destroySocketAddr */
1281 /*****************************************************************************/
1282 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
1284 __osl_destroySocketAddr( pAddr
);
1287 /*****************************************************************************/
1288 /* osl_getFamilyOfSocketAddr */
1289 /*****************************************************************************/
1290 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
1295 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1297 return osl_Socket_FamilyInvalid
;
1300 /*****************************************************************************/
1301 /* osl_getInetPortOfSocketAddr */
1302 /*****************************************************************************/
1303 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
1308 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1310 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1311 return ntohs(pSystemInetAddr
->sin_port
);
1313 return OSL_INVALID_PORT
;
1316 /*****************************************************************************/
1317 /* osl_setInetPortOfSocketAddr */
1318 /*****************************************************************************/
1319 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr
, sal_Int32 Port
)
1324 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1325 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1327 pSystemInetAddr
->sin_port
= htons((short)Port
);
1332 /* this is not a inet-addr => can't set port */
1336 /*****************************************************************************/
1337 /* osl_getHostnameOfSocketAddr */
1338 /*****************************************************************************/
1339 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrHostname
)
1341 oslSocketResult Result
;
1342 sal_Char pszHostname
[1024];
1344 pszHostname
[0] = '\0';
1346 Result
= osl_psz_getHostnameOfSocketAddr(Addr
,pszHostname
,sizeof(pszHostname
));
1348 rtl_uString_newFromAscii(ustrHostname
,pszHostname
);
1354 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr
,
1355 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1357 oslHostAddr pHostAddr
= (oslHostAddr
)osl_createHostAddrByAddr(pAddr
);
1361 strncpy(pBuffer
, pHostAddr
->pHostName
, BufferSize
);
1363 pBuffer
[BufferSize
- 1] = '\0';
1365 osl_destroyHostAddr(pHostAddr
);
1367 return osl_Socket_Ok
;
1370 return osl_Socket_Error
;
1373 /*****************************************************************************/
1374 /* osl_getDottedInetAddrOfSocketAddr */
1375 /*****************************************************************************/
1376 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrDottedInetAddr
)
1378 oslSocketResult Result
;
1379 sal_Char pszDottedInetAddr
[1024];
1381 pszDottedInetAddr
[0] = '\0';
1383 Result
= osl_psz_getDottedInetAddrOfSocketAddr(Addr
,pszDottedInetAddr
,sizeof(pszDottedInetAddr
));
1385 rtl_uString_newFromAscii(ustrDottedInetAddr
,pszDottedInetAddr
);
1391 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr
,
1392 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1398 struct sockaddr_in
* pSystemInetAddr
= ( struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
1400 if (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1402 strncpy(pBuffer
, inet_ntoa(pSystemInetAddr
->sin_addr
), BufferSize
);
1403 pBuffer
[BufferSize
- 1] = '\0';
1405 return osl_Socket_Ok
;
1409 return osl_Socket_Error
;
1412 /*****************************************************************************/
1413 /* osl_createSocket */
1414 /*****************************************************************************/
1415 oslSocket SAL_CALL
osl_createSocket(oslAddrFamily Family
,
1417 oslProtocol Protocol
)
1423 pSocket
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1426 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
1427 TYPE_TO_NATIVE(Type
),
1428 PROTOCOL_TO_NATIVE(Protocol
));
1430 /* creation failed => free memory */
1431 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
1433 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1437 __osl_destroySocketImpl((pSocket
));
1442 /* set close-on-exec flag */
1443 if ((Flags
= fcntl(pSocket
->m_Socket
, F_GETFD
, 0)) != -1)
1445 Flags
|= FD_CLOEXEC
;
1446 if (fcntl(pSocket
->m_Socket
, F_SETFD
, Flags
) == -1)
1448 pSocket
->m_nLastError
=errno
;
1449 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1456 pSocket
->m_nLastError
=errno
;
1463 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
1465 osl_atomic_increment( &(pSocket
->m_nRefCount
) );
1468 void SAL_CALL
osl_releaseSocket( oslSocket pSocket
)
1470 if( pSocket
&& 0 == osl_atomic_decrement( &(pSocket
->m_nRefCount
) ) )
1473 if ( pSocket
->m_bIsAccepting
== sal_True
)
1475 OSL_FAIL("osl_destroySocket : attempt to destroy socket while accepting\n");
1479 osl_closeSocket( pSocket
);
1480 __osl_destroySocketImpl( pSocket
);
1486 /*****************************************************************************/
1487 /* osl_closeSocket */
1488 /*****************************************************************************/
1489 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
1494 /* socket already invalid */
1498 pSocket
->m_nLastError
=0;
1499 nFD
= pSocket
->m_Socket
;
1501 if (nFD
== OSL_INVALID_SOCKET
)
1504 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1507 pSocket
->m_bIsInShutdown
= sal_True
;
1509 if ( pSocket
->m_bIsAccepting
== sal_True
)
1513 struct sockaddr aSockAddr
;
1514 struct sockaddr_in aSockAddrIn
;
1516 socklen_t nSockLen
= sizeof(s
.aSockAddr
);
1518 nRet
= getsockname(nFD
, &s
.aSockAddr
, &nSockLen
);
1521 OSL_TRACE("getsockname call failed with error: %s", strerror(errno
));
1524 if ( s
.aSockAddr
.sa_family
== AF_INET
)
1526 if ( s
.aSockAddrIn
.sin_addr
.s_addr
== htonl(INADDR_ANY
) )
1528 s
.aSockAddrIn
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1531 nConnFD
= socket(AF_INET
, SOCK_STREAM
, 0);
1534 OSL_TRACE("socket call failed with error: %s", strerror(errno
));
1537 nRet
= connect(nConnFD
, &s
.aSockAddr
, sizeof(s
.aSockAddr
));
1540 OSL_TRACE("connect call failed with error: %s", strerror(errno
));
1544 pSocket
->m_bIsAccepting
= sal_False
;
1551 pSocket
->m_nLastError
=errno
;
1552 OSL_TRACE("closeSocket close error '%s'",strerror(errno
));
1555 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1558 /*****************************************************************************/
1559 /* osl_getLocalAddrOfSocket */
1560 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1561 /* are the same! I don't like it very much but see no other easy way to conceal */
1562 /* the struct sockaddr from the eyes of the user. */
1563 /*****************************************************************************/
1564 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
1567 struct sockaddr Addr
;
1568 oslSocketAddr pAddr
;
1570 if (pSocket
== NULL
) /* ENOTSOCK */
1571 return ((oslSocketAddr
)NULL
);
1573 AddrLen
= sizeof(struct sockaddr
);
1575 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1576 return ((oslSocketAddr
)NULL
);
1578 pAddr
= __osl_createSocketAddrFromSystem( &Addr
);
1582 /*****************************************************************************/
1583 /* osl_getPeerAddrOfSocket */
1584 /*****************************************************************************/
1585 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1588 struct sockaddr Addr
;
1590 OSL_ASSERT(pSocket
);
1596 pSocket
->m_nLastError
=0;
1597 AddrLen
= sizeof(struct sockaddr
);
1599 if(getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1601 pSocket
->m_nLastError
=errno
;
1604 return __osl_createSocketAddrFromSystem( &Addr
);
1607 /*****************************************************************************/
1608 /* osl_bindAddrToSocket */
1609 /*****************************************************************************/
1610 sal_Bool SAL_CALL
osl_bindAddrToSocket(oslSocket pSocket
,
1611 oslSocketAddr pAddr
)
1615 OSL_ASSERT(pSocket
&& pAddr
);
1616 if ( pSocket
== 0 || pAddr
== 0 )
1621 pSocket
->m_nLastError
=0;
1623 nRet
= bind(pSocket
->m_Socket
, &(pAddr
->m_sockaddr
), sizeof(struct sockaddr
));
1625 if ( nRet
== OSL_SOCKET_ERROR
)
1627 pSocket
->m_nLastError
=errno
;
1635 /*****************************************************************************/
1636 /* osl_listenOnSocket */
1637 /*****************************************************************************/
1638 sal_Bool SAL_CALL
osl_listenOnSocket(oslSocket pSocket
,
1639 sal_Int32 MaxPendingConnections
)
1643 OSL_ASSERT(pSocket
);
1649 pSocket
->m_nLastError
=0;
1651 nRet
= listen(pSocket
->m_Socket
,
1652 MaxPendingConnections
== -1 ?
1654 MaxPendingConnections
);
1655 if ( nRet
== OSL_SOCKET_ERROR
)
1657 pSocket
->m_nLastError
=errno
;
1665 /*****************************************************************************/
1666 /* osl_connectSocketTo */
1667 /*****************************************************************************/
1668 oslSocketResult SAL_CALL
osl_connectSocketTo(oslSocket pSocket
,
1669 oslSocketAddr pAddr
,
1670 const TimeValue
* pTimeout
)
1676 oslSocketResult Result
= osl_Socket_Ok
;
1678 OSL_PRECOND(pSocket
, "osl_connectSocketTo(): need a valid socket!\n");
1682 return osl_Socket_Error
;
1685 pSocket
->m_nLastError
=0;
1687 if (osl_isNonBlockingMode(pSocket
))
1689 if (connect(pSocket
->m_Socket
,
1690 &(pAddr
->m_sockaddr
),
1691 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1692 return osl_Socket_Ok
;
1694 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
1696 pSocket
->m_nLastError
=EINPROGRESS
;
1697 return osl_Socket_InProgress
;
1701 pSocket
->m_nLastError
=errno
;
1702 OSL_TRACE("can't connect : '%s'",strerror(errno
));
1703 return osl_Socket_Error
;
1706 /* set socket temporarily to non-blocking */
1707 OSL_VERIFY(osl_enableNonBlockingMode(pSocket
, sal_True
));
1709 /* initiate connect */
1710 if(connect(pSocket
->m_Socket
,
1711 &(pAddr
->m_sockaddr
),
1712 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1714 /* immediate connection */
1715 osl_enableNonBlockingMode(pSocket
, sal_False
);
1717 return osl_Socket_Ok
;
1721 /* really an error or just delayed? */
1722 if (errno
!= EINPROGRESS
)
1724 pSocket
->m_nLastError
=errno
;
1726 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
1727 errno
, strerror(errno
));
1729 osl_enableNonBlockingMode(pSocket
, sal_False
);
1730 return osl_Socket_Error
;
1735 /* prepare select set for socket */
1738 FD_SET(pSocket
->m_Socket
, &WriteSet
);
1739 FD_SET(pSocket
->m_Socket
, &ExcptSet
);
1741 /* prepare timeout */
1744 /* divide milliseconds into seconds and microseconds */
1745 tv
.tv_sec
= pTimeout
->Seconds
;
1746 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1750 ReadyHandles
= select(pSocket
->m_Socket
+1,
1752 PTR_FD_SET(WriteSet
),
1753 PTR_FD_SET(ExcptSet
),
1754 (pTimeout
) ? &tv
: 0);
1756 if (ReadyHandles
> 0) /* connected */
1758 if ( FD_ISSET(pSocket
->m_Socket
, &WriteSet
) )
1761 socklen_t nErrorSize
= sizeof( nErrorCode
);
1765 nSockOpt
= getsockopt ( pSocket
->m_Socket
, SOL_SOCKET
, SO_ERROR
,
1766 &nErrorCode
, &nErrorSize
);
1767 if ( (nSockOpt
== 0) && (nErrorCode
== 0))
1768 Result
= osl_Socket_Ok
;
1770 Result
= osl_Socket_Error
;
1774 Result
= osl_Socket_Error
;
1777 else if (ReadyHandles
< 0) /* error */
1779 if (errno
== EBADF
) /* most probably interrupted by close() */
1781 /* do not access pSockImpl because it is about to be or */
1782 /* already destroyed */
1783 return osl_Socket_Interrupted
;
1787 pSocket
->m_nLastError
=errno
;
1788 Result
= osl_Socket_Error
;
1793 pSocket
->m_nLastError
=errno
;
1794 Result
= osl_Socket_TimedOut
;
1797 osl_enableNonBlockingMode(pSocket
, sal_False
);
1803 /*****************************************************************************/
1804 /* osl_acceptConnectionOnSocket */
1805 /*****************************************************************************/
1806 oslSocket SAL_CALL
osl_acceptConnectionOnSocket(oslSocket pSocket
,
1807 oslSocketAddr
* ppAddr
)
1809 struct sockaddr Addr
;
1810 int Connection
, Flags
;
1811 oslSocket pConnectionSockImpl
;
1813 socklen_t AddrLen
= sizeof(struct sockaddr
);
1814 OSL_ASSERT(pSocket
);
1820 pSocket
->m_nLastError
=0;
1822 pSocket
->m_bIsAccepting
= sal_True
;
1825 if( ppAddr
&& *ppAddr
)
1827 osl_destroySocketAddr( *ppAddr
);
1831 /* prevent Linux EINTR behaviour */
1834 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
1835 } while (Connection
== -1 && errno
== EINTR
);
1838 /* accept failed? */
1839 if( Connection
== OSL_SOCKET_ERROR
)
1841 pSocket
->m_nLastError
=errno
;
1842 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'",strerror(errno
));
1845 pSocket
->m_bIsAccepting
= sal_False
;
1850 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
1854 if ( pSocket
->m_bIsInShutdown
== sal_True
)
1857 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept");
1865 *ppAddr
= __osl_createSocketAddrFromSystem(&Addr
);
1869 pConnectionSockImpl
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1871 /* set close-on-exec flag */
1872 if ((Flags
= fcntl(Connection
, F_GETFD
, 0)) != -1)
1874 Flags
|= FD_CLOEXEC
;
1875 if (fcntl(Connection
, F_SETFD
, Flags
) == -1)
1877 pSocket
->m_nLastError
=errno
;
1878 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
1885 pConnectionSockImpl
->m_Socket
= Connection
;
1886 pConnectionSockImpl
->m_nLastError
= 0;
1888 pConnectionSockImpl
->m_bIsAccepting
= sal_False
;
1890 pSocket
->m_bIsAccepting
= sal_False
;
1892 return pConnectionSockImpl
;
1895 /*****************************************************************************/
1896 /* osl_receiveSocket */
1897 /*****************************************************************************/
1898 sal_Int32 SAL_CALL
osl_receiveSocket(oslSocket pSocket
,
1900 sal_uInt32 BytesToRead
,
1901 oslSocketMsgFlag Flag
)
1905 OSL_ASSERT(pSocket
);
1908 OSL_TRACE("osl_receiveSocket : Invalid socket");
1912 pSocket
->m_nLastError
=0;
1916 nRead
= recv(pSocket
->m_Socket
,
1919 MSG_FLAG_TO_NATIVE(Flag
));
1920 } while ( nRead
< 0 && errno
== EINTR
);
1924 pSocket
->m_nLastError
=errno
;
1925 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,strerror(errno
));
1927 else if ( nRead
== 0 )
1929 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
1936 /*****************************************************************************/
1937 /* osl_receiveFromSocket */
1938 /*****************************************************************************/
1939 sal_Int32 SAL_CALL
osl_receiveFromSocket(oslSocket pSocket
,
1940 oslSocketAddr pSenderAddr
,
1942 sal_uInt32 BufferSize
,
1943 oslSocketMsgFlag Flag
)
1946 struct sockaddr
*pSystemSockAddr
= 0;
1947 socklen_t AddrLen
= 0;
1950 AddrLen
= sizeof( struct sockaddr
);
1951 pSystemSockAddr
= &(pSenderAddr
->m_sockaddr
);
1954 OSL_ASSERT(pSocket
);
1957 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
1961 pSocket
->m_nLastError
=0;
1963 nRead
= recvfrom(pSocket
->m_Socket
,
1966 MSG_FLAG_TO_NATIVE(Flag
),
1972 pSocket
->m_nLastError
=errno
;
1973 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead
,strerror(errno
));
1975 else if ( nRead
== 0 )
1977 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
1984 /*****************************************************************************/
1985 /* osl_sendSocket */
1986 /*****************************************************************************/
1987 sal_Int32 SAL_CALL
osl_sendSocket(oslSocket pSocket
,
1988 const void* pBuffer
,
1989 sal_uInt32 BytesToSend
,
1990 oslSocketMsgFlag Flag
)
1994 OSL_ASSERT(pSocket
);
1997 OSL_TRACE("osl_sendSocket : Invalid socket");
2001 pSocket
->m_nLastError
=0;
2005 nWritten
= send(pSocket
->m_Socket
,
2008 MSG_FLAG_TO_NATIVE(Flag
));
2009 } while ( nWritten
< 0 && errno
== EINTR
);
2014 pSocket
->m_nLastError
=errno
;
2015 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,strerror(errno
));
2017 else if ( nWritten
== 0 )
2019 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,"EOL");
2025 /*****************************************************************************/
2026 /* osl_sendToSocket */
2027 /*****************************************************************************/
2028 sal_Int32 SAL_CALL
osl_sendToSocket(oslSocket pSocket
,
2029 oslSocketAddr ReceiverAddr
,
2030 const void* pBuffer
,
2031 sal_uInt32 BytesToSend
,
2032 oslSocketMsgFlag Flag
)
2036 struct sockaddr
*pSystemSockAddr
= 0;
2040 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
2041 AddrLen
= sizeof( struct sockaddr
);
2044 OSL_ASSERT(pSocket
);
2047 OSL_TRACE("osl_sendToSocket : Invalid socket");
2051 pSocket
->m_nLastError
=0;
2053 /* ReceiverAddr might be 0 when used on a connected socket. */
2054 /* Then sendto should behave like send. */
2056 nWritten
= sendto(pSocket
->m_Socket
,
2059 MSG_FLAG_TO_NATIVE(Flag
),
2065 pSocket
->m_nLastError
=errno
;
2066 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,strerror(errno
));
2068 else if ( nWritten
== 0 )
2070 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,"EOL");
2076 /*****************************************************************************/
2077 /* osl_readSocket */
2078 /*****************************************************************************/
2079 sal_Int32 SAL_CALL
osl_readSocket (
2080 oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
2082 sal_uInt8
* Ptr
= (sal_uInt8
*)pBuffer
;
2083 sal_uInt32 BytesRead
= 0;
2084 sal_uInt32 BytesToRead
= n
;
2086 OSL_ASSERT( pSocket
);
2088 /* loop until all desired bytes were read or an error occurred */
2089 while (BytesToRead
> 0)
2092 RetVal
= osl_receiveSocket(pSocket
,
2095 osl_Socket_MsgNormal
);
2097 /* error occurred? */
2103 BytesToRead
-= RetVal
;
2104 BytesRead
+= RetVal
;
2111 /*****************************************************************************/
2112 /* osl_writeSocket */
2113 /*****************************************************************************/
2114 sal_Int32 SAL_CALL
osl_writeSocket(
2115 oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
2117 /* loop until all desired bytes were send or an error occurred */
2118 sal_uInt32 BytesSend
= 0;
2119 sal_uInt32 BytesToSend
= n
;
2120 sal_uInt8
*Ptr
= ( sal_uInt8
* )pBuffer
;
2122 OSL_ASSERT( pSocket
);
2124 while (BytesToSend
> 0)
2128 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
2130 /* error occurred? */
2136 BytesToSend
-= RetVal
;
2137 BytesSend
+= RetVal
;
2144 /*****************************************************************************/
2145 /* __osl_socket_poll */
2146 /*****************************************************************************/
2148 #ifdef HAVE_POLL_H /* poll() */
2150 sal_Bool
__osl_socket_poll (
2152 const TimeValue
* pTimeout
,
2159 OSL_ASSERT(0 != pSocket
);
2161 return sal_False
; /* EINVAL */
2163 pSocket
->m_nLastError
= 0;
2165 fds
.fd
= pSocket
->m_Socket
;
2166 fds
.events
= nEvent
;
2172 /* Convert to [ms] */
2173 timeout
= pTimeout
->Seconds
* 1000;
2174 timeout
+= pTimeout
->Nanosec
/ (1000 * 1000);
2177 result
= poll (&fds
, 1, timeout
);
2180 pSocket
->m_nLastError
= errno
;
2181 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2182 errno
, strerror(errno
));
2191 return ((fds
.revents
& nEvent
) == nEvent
);
2194 #else /* select() */
2196 sal_Bool
__osl_socket_poll (
2198 const TimeValue
* pTimeout
,
2205 OSL_ASSERT(0 != pSocket
);
2207 return sal_False
; /* EINVAL */
2209 pSocket
->m_nLastError
= 0;
2212 FD_SET(pSocket
->m_Socket
, &fds
);
2216 /* Convert to 'timeval' */
2217 tv
.tv_sec
= pTimeout
->Seconds
;
2218 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000;
2222 pSocket
->m_Socket
+ 1,
2223 (nEvent
== POLLIN
) ? PTR_FD_SET(fds
) : NULL
,
2224 (nEvent
== POLLOUT
) ? PTR_FD_SET(fds
) : NULL
,
2225 (nEvent
== POLLPRI
) ? PTR_FD_SET(fds
) : NULL
,
2226 (pTimeout
) ? &tv
: NULL
);
2230 pSocket
->m_nLastError
= errno
;
2231 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2232 errno
, strerror(errno
));
2241 return (FD_ISSET(pSocket
->m_Socket
, &fds
) ? sal_True
: sal_False
);
2244 #endif /* HAVE_POLL_H */
2246 /*****************************************************************************/
2247 /* osl_isReceiveReady */
2248 /*****************************************************************************/
2249 sal_Bool SAL_CALL
osl_isReceiveReady (
2250 oslSocket pSocket
, const TimeValue
* pTimeout
)
2252 OSL_ASSERT(pSocket
);
2253 if (pSocket
== NULL
)
2259 return __osl_socket_poll (pSocket
, pTimeout
, POLLIN
);
2262 /*****************************************************************************/
2263 /* osl_isSendReady */
2264 /*****************************************************************************/
2265 sal_Bool SAL_CALL
osl_isSendReady (
2266 oslSocket pSocket
, const TimeValue
* pTimeout
)
2268 OSL_ASSERT(pSocket
);
2269 if (pSocket
== NULL
)
2275 return __osl_socket_poll (pSocket
, pTimeout
, POLLOUT
);
2278 /*****************************************************************************/
2279 /* osl_isExceptionPending */
2280 /*****************************************************************************/
2281 sal_Bool SAL_CALL
osl_isExceptionPending (
2282 oslSocket pSocket
, const TimeValue
* pTimeout
)
2284 OSL_ASSERT(pSocket
);
2285 if (pSocket
== NULL
)
2291 return __osl_socket_poll (pSocket
, pTimeout
, POLLPRI
);
2294 /*****************************************************************************/
2295 /* osl_shutdownSocket */
2296 /*****************************************************************************/
2297 sal_Bool SAL_CALL
osl_shutdownSocket(oslSocket pSocket
,
2298 oslSocketDirection Direction
)
2302 OSL_ASSERT(pSocket
);
2308 pSocket
->m_nLastError
=0;
2310 nRet
=shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
));
2313 pSocket
->m_nLastError
=errno
;
2314 OSL_TRACE("shutdown error '%s'",strerror(errno
));
2320 /*****************************************************************************/
2321 /* osl_getSocketOption */
2322 /*****************************************************************************/
2323 sal_Int32 SAL_CALL
osl_getSocketOption(oslSocket pSocket
,
2324 oslSocketOptionLevel Level
,
2325 oslSocketOption Option
,
2327 sal_uInt32 BufferLen
)
2329 socklen_t nOptLen
= (socklen_t
) BufferLen
;
2331 OSL_ASSERT(pSocket
);
2337 pSocket
->m_nLastError
=0;
2339 if(getsockopt(pSocket
->m_Socket
,
2340 OPTION_LEVEL_TO_NATIVE(Level
),
2341 OPTION_TO_NATIVE(Option
),
2345 pSocket
->m_nLastError
=errno
;
2352 /*****************************************************************************/
2353 /* osl_setSocketOption */
2354 /*****************************************************************************/
2355 sal_Bool SAL_CALL
osl_setSocketOption(oslSocket pSocket
,
2356 oslSocketOptionLevel Level
,
2357 oslSocketOption Option
,
2359 sal_uInt32 BufferLen
)
2363 OSL_ASSERT(pSocket
);
2369 pSocket
->m_nLastError
=0;
2371 nRet
= setsockopt(pSocket
->m_Socket
,
2372 OPTION_LEVEL_TO_NATIVE(Level
),
2373 OPTION_TO_NATIVE(Option
),
2379 pSocket
->m_nLastError
=errno
;
2386 /*****************************************************************************/
2387 /* osl_enableNonBlockingMode */
2388 /*****************************************************************************/
2389 sal_Bool SAL_CALL
osl_enableNonBlockingMode(oslSocket pSocket
,
2395 OSL_ASSERT(pSocket
);
2401 pSocket
->m_nLastError
=0;
2403 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2406 flags
|= O_NONBLOCK
;
2408 flags
&= ~(O_NONBLOCK
);
2410 nRet
= fcntl(pSocket
->m_Socket
, F_SETFL
, flags
);
2414 pSocket
->m_nLastError
=errno
;
2421 /*****************************************************************************/
2422 /* osl_isNonBlockingMode */
2423 /*****************************************************************************/
2424 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
2428 OSL_ASSERT(pSocket
);
2434 pSocket
->m_nLastError
=0;
2436 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2438 if (flags
== -1 || !(flags
& O_NONBLOCK
))
2444 /*****************************************************************************/
2445 /* osl_getSocketType */
2446 /*****************************************************************************/
2447 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
2450 socklen_t TypeSize
= sizeof(Type
);
2452 OSL_ASSERT(pSocket
);
2455 return osl_Socket_TypeInvalid
;
2458 pSocket
->m_nLastError
=0;
2460 if(getsockopt(pSocket
->m_Socket
,
2461 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
2462 OPTION_TO_NATIVE(osl_Socket_OptionType
),
2467 pSocket
->m_nLastError
=errno
;
2468 return osl_Socket_TypeInvalid
;
2471 return TYPE_FROM_NATIVE(Type
);
2475 /*****************************************************************************/
2476 /* osl_getLastSocketErrorDescription */
2477 /*****************************************************************************/
2478 void SAL_CALL
osl_getLastSocketErrorDescription(oslSocket Socket
, rtl_uString
**ustrError
)
2480 sal_Char pszError
[1024];
2484 osl_psz_getLastSocketErrorDescription(Socket
,pszError
,sizeof(pszError
));
2486 rtl_uString_newFromAscii(ustrError
,pszError
);
2492 void SAL_CALL
osl_psz_getLastSocketErrorDescription(oslSocket pSocket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
)
2494 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2495 pBuffer
[BufferSize
-1]= '\0';
2499 strncpy(pBuffer
, strerror(EINVAL
), BufferSize
-1);
2503 strncpy(pBuffer
, strerror(pSocket
->m_nLastError
), BufferSize
-1);
2507 /*****************************************************************************/
2508 /* osl_getLastSocketError */
2509 /*****************************************************************************/
2510 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket pSocket
)
2514 return ERROR_FROM_NATIVE(EINVAL
);
2517 return ERROR_FROM_NATIVE(pSocket
->m_nLastError
);
2520 /*****************************************************************************/
2522 /*****************************************************************************/
2523 typedef struct _TSocketSetImpl
2525 int m_MaxHandle
; /* for select(), the largest descriptor in the set */
2526 fd_set m_Set
; /* the set of descriptors */
2530 /*****************************************************************************/
2531 /* osl_createSocketSet */
2532 /*****************************************************************************/
2533 oslSocketSet SAL_CALL
osl_createSocketSet()
2535 TSocketSetImpl
* pSet
;
2537 pSet
= (TSocketSetImpl
*)malloc(sizeof(TSocketSetImpl
));
2543 pSet
->m_MaxHandle
= 0;
2544 FD_ZERO(&pSet
->m_Set
);
2547 return (oslSocketSet
)pSet
;
2550 /*****************************************************************************/
2551 /* osl_destroySocketSet */
2552 /*****************************************************************************/
2553 void SAL_CALL
osl_destroySocketSet(oslSocketSet Set
)
2559 /*****************************************************************************/
2560 /* osl_clearSocketSet */
2561 /*****************************************************************************/
2562 void SAL_CALL
osl_clearSocketSet(oslSocketSet Set
)
2564 TSocketSetImpl
* pSet
;
2571 pSet
= (TSocketSetImpl
*)Set
;
2572 pSet
->m_MaxHandle
= 0;
2574 FD_ZERO(&pSet
->m_Set
);
2577 /*****************************************************************************/
2578 /* osl_addToSocketSet */
2579 /*****************************************************************************/
2580 void SAL_CALL
osl_addToSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2582 TSocketSetImpl
* pSet
;
2585 OSL_ASSERT(pSocket
);
2587 if ( Set
== 0 || pSocket
== 0)
2592 pSet
= (TSocketSetImpl
*)Set
;
2594 /* correct max handle */
2595 if(pSocket
->m_Socket
> pSet
->m_MaxHandle
)
2596 pSet
->m_MaxHandle
= pSocket
->m_Socket
;
2597 FD_SET(pSocket
->m_Socket
, &pSet
->m_Set
);
2601 /*****************************************************************************/
2602 /* osl_removeFromSocketSet */
2603 /*****************************************************************************/
2604 void SAL_CALL
osl_removeFromSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2606 TSocketSetImpl
* pSet
;
2609 OSL_ASSERT(pSocket
);
2611 if ( Set
== 0 || pSocket
== 0)
2616 pSet
= (TSocketSetImpl
*)Set
;
2618 /* correct max handle */
2619 if(pSocket
->m_Socket
== pSet
->m_MaxHandle
)
2621 /* not optimal, since the next used descriptor might be */
2622 /* much smaller than m_Socket-1, but it will do */
2623 pSet
->m_MaxHandle
--;
2624 if(pSet
->m_MaxHandle
< 0)
2626 pSet
->m_MaxHandle
= 0; /* avoid underflow */
2630 FD_CLR(pSocket
->m_Socket
, &pSet
->m_Set
);
2633 /*****************************************************************************/
2634 /* osl_isInSocketSet */
2635 /*****************************************************************************/
2636 sal_Bool SAL_CALL
osl_isInSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2638 TSocketSetImpl
* pSet
;
2641 OSL_ASSERT(pSocket
);
2642 if ( Set
== 0 || pSocket
== 0 )
2647 pSet
= (TSocketSetImpl
*)Set
;
2649 return (FD_ISSET(pSocket
->m_Socket
, &pSet
->m_Set
) != 0);
2652 /*****************************************************************************/
2653 /* osl_demultiplexSocketEvents */
2654 /*****************************************************************************/
2655 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents(oslSocketSet IncomingSet
,
2656 oslSocketSet OutgoingSet
,
2657 oslSocketSet OutOfBandSet
,
2658 const TimeValue
* pTimeout
)
2662 TSocketSetImpl
* pInSet
;
2663 TSocketSetImpl
* pOutSet
;
2664 TSocketSetImpl
* pOOBSet
;
2668 /* non-blocking call */
2669 tv
.tv_sec
= pTimeout
->Seconds
;
2670 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
2673 /* map opaque data to impl-types */
2674 pInSet
= (TSocketSetImpl
*)IncomingSet
;
2675 pOutSet
= (TSocketSetImpl
*)OutgoingSet
;
2676 pOOBSet
= (TSocketSetImpl
*)OutOfBandSet
;
2678 /* get max handle from all sets */
2680 MaxHandle
= pInSet
->m_MaxHandle
;
2682 if (pOutSet
&& (pOutSet
->m_MaxHandle
> MaxHandle
))
2683 MaxHandle
= pOutSet
->m_MaxHandle
;
2685 if (pOOBSet
&& (pOOBSet
->m_MaxHandle
> MaxHandle
))
2686 MaxHandle
= pOOBSet
->m_MaxHandle
;
2688 return select(MaxHandle
+1,
2689 pInSet
? PTR_FD_SET(pInSet
->m_Set
) : 0,
2690 pOutSet
? PTR_FD_SET(pOutSet
->m_Set
) : 0,
2691 pOOBSet
? PTR_FD_SET(pOOBSet
->m_Set
) : 0,
2692 pTimeout
? &tv
: 0);
2695 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */