1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include <osl/socket.h>
32 #include <osl/diagnose.h>
33 #include <osl/mutex.h>
34 #include <osl/signal.h>
36 #include <rtl/alloc.h>
39 #include <sal/types.h>
43 /* defines for poll */
48 #if defined(LINUX) || defined(NETBSD) || defined ( FREEBSD ) || \
49 defined (MACOSX) || defined (OPENBSD) || defined(DRAGONFLY)
52 #endif /* HAVE_POLL_H */
61 #define POLLOUT 0x0002
62 #define POLLPRI 0x0004
63 #endif /* HAVE_POLL_H */
66 /* defines for shutdown */
73 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
74 I refrained from using sockaddr_in because of possible further
75 extensions of this socket-interface (IP-NG?).
76 The intention was to hide all Berkeley data-structures from
77 direct access past the osl-interface.
79 The current implementation is internet (IP) centered. All
80 the constructor-functions (osl_create...) take parameters
81 that will probably make sense only in the IP-environment
82 (e.g. because of using the dotted-address-format).
84 If the interface will be extended to host other protocol-
85 families, I expect no externally visible changes in the
86 existing functions. You'll probably need only new
87 constructor-functions who take the different address
88 formats into consideration (maybe a long dotted address
92 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
93 /* are the same! I don't like it very much but see no other easy way to */
94 /* conceal the struct sockaddr from the eyes of the user. */
97 #define OSL_INVALID_SOCKET -1
98 #define OSL_SOCKET_ERROR -1
101 /* Buffer size for gethostbyname */
102 #define MAX_HOSTBUFFER_SIZE 2048
104 /*****************************************************************************/
105 /* enum oslAddrFamily */
106 /*****************************************************************************/
109 static unsigned long FamilyMap
[]= {
110 AF_INET
, /* osl_Socket_FamilyInet */
111 AF_IPX
, /* osl_Socket_FamilyIpx */
112 0 /* osl_Socket_FamilyInvalid */
116 static oslAddrFamily
osl_AddrFamilyFromNative(sal_uInt32 nativeType
)
118 oslAddrFamily i
= (oslAddrFamily
)0;
120 while(i
!= osl_Socket_FamilyInvalid
)
122 if(FamilyMap
[i
] == nativeType
)
124 i
= (oslAddrFamily
) ( i
+ 1 );
131 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
132 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
134 /*****************************************************************************/
135 /* enum oslProtocol */
136 /*****************************************************************************/
139 static sal_uInt32 ProtocolMap
[]= {
140 0, /* osl_Socket_ProtocolIp */
141 NSPROTO_IPX
, /* osl_Socket_ProtocolIpx */
142 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
143 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpxII */
144 0 /* osl_Socket_ProtocolInvalid */
149 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
151 oslProtocol i= (oslProtocol)0;
153 while(i != osl_Socket_ProtocolInvalid)
155 if(ProtocolMap[i] == nativeType)
157 i = (oslProtocol) ( i + 1);
165 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
166 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
169 /*****************************************************************************/
170 /* enum oslSocketType */
171 /*****************************************************************************/
174 static sal_uInt32 TypeMap
[]= {
175 SOCK_STREAM
, /* osl_Socket_TypeStream */
176 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
177 SOCK_RAW
, /* osl_Socket_TypeRaw */
178 SOCK_RDM
, /* osl_Socket_TypeRdm */
179 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
180 0 /* osl_Socket_TypeInvalid */
184 static oslSocketType
osl_SocketTypeFromNative(sal_uInt32 nativeType
)
186 oslSocketType i
= (oslSocketType
)0;
188 while(i
!= osl_Socket_TypeInvalid
)
190 if(TypeMap
[i
] == nativeType
)
192 i
= (oslSocketType
)(i
+ 1);
199 #define TYPE_TO_NATIVE(x) TypeMap[x]
200 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
203 /*****************************************************************************/
204 /* enum oslSocketOption */
205 /*****************************************************************************/
208 static sal_uInt32 OptionMap
[]= {
209 SO_DEBUG
, /* osl_Socket_OptionDebug */
210 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
211 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
212 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
213 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
214 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
215 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
216 SO_LINGER
, /* osl_Socket_OptionLinger */
217 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
218 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
219 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
220 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
221 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
222 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
223 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
224 SO_ERROR
, /* osl_Socket_OptionError */
225 SO_TYPE
, /* osl_Socket_OptionType */
226 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
227 0 /* osl_Socket_OptionInvalid */
232 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
234 oslSocketOption i= (oslSocketOption)0;
236 while(i != osl_Socket_OptionInvalid)
238 if(OptionMap[i] == nativeType)
240 i = (oslSocketOption) ( i + 1 );
247 #define OPTION_TO_NATIVE(x) OptionMap[x]
248 #define OPTION_FROM_NATIVE(y) osl_SocketOptionFromNative(y)
251 /*****************************************************************************/
252 /* enum oslSocketOptionLevel */
253 /*****************************************************************************/
255 static sal_uInt32 OptionLevelMap
[]= {
256 SOL_SOCKET
, /* osl_Socket_LevelSocket */
257 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
258 0 /* osl_Socket_LevelInvalid */
263 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
265 oslSocketOptionLevel i= (oslSocketOptionLevel)0;
267 while(i != osl_Socket_LevelInvalid)
269 if(OptionLevelMap[i] == nativeType)
271 i = (oslSocketOptionLevel) ( i + 1 );
278 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
279 #define OPTION_LEVEL_FROM_NATIVE(y) osl_SocketOptionLevelFromNative(y)
281 /*****************************************************************************/
282 /* enum oslSocketMsgFlag */
283 /*****************************************************************************/
285 static sal_uInt32 SocketMsgFlagMap
[]= {
286 0, /* osl_Socket_MsgNormal */
287 MSG_OOB
, /* osl_Socket_MsgOOB */
288 MSG_PEEK
, /* osl_Socket_MsgPeek */
289 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
290 MSG_MAXIOVLEN
, /* osl_Socket_MsgMaxIOVLen */
291 0 /* osl_Socket_MsgInvalid */
296 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
298 oslSocketMsgFlag i= (oslSocketMsgFlag)0;
300 while(i != osl_Socket_MsgInvalid)
302 if(SocketMsgFlagMap[i] == nativeType)
304 i = (oslSocketMsgFlag) ( i + 1 );
312 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
313 #define MSG_FLAG_FROM_NATIVE(y) osl_SocketMsgFlagFromNative(y)
316 /*****************************************************************************/
317 /* enum oslSocketDirection */
318 /*****************************************************************************/
320 static sal_uInt32 SocketDirection
[]= {
321 SD_RECEIVE
, /* osl_Socket_DirRead */
322 SD_SEND
, /* osl_Socket_DirWrite */
323 SD_BOTH
, /* osl_Socket_DirReadWrite */
324 0 /* osl_Socket_DirInvalid */
329 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
331 oslSocketDirection i= (oslSocketDirection)0;
333 while(i != osl_Socket_DirInvalid)
335 if(SocketDirection[i] == nativeType)
337 i = (oslSocketDirection) ( i + 1 );
345 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
346 #define DIRECTION_FROM_NATIVE(y) osl_SocketDirectionFromNative(y)
348 /*****************************************************************************/
349 /* enum oslSocketError */
350 /*****************************************************************************/
355 oslSocketError error
;
357 { 0, osl_Socket_E_None
}, /* no error */
358 { ENOTSOCK
, osl_Socket_E_NotSocket
}, /* Socket operation on non-socket */
359 { EDESTADDRREQ
, osl_Socket_E_DestAddrReq
}, /* Destination address required */
360 { EMSGSIZE
, osl_Socket_E_MsgSize
}, /* Message too long */
361 { EPROTOTYPE
, osl_Socket_E_Prototype
}, /* Protocol wrong type for socket */
362 { ENOPROTOOPT
, osl_Socket_E_NoProtocol
}, /* Protocol not available */
363 { EPROTONOSUPPORT
, osl_Socket_E_ProtocolNoSupport
}, /* Protocol not supported */
364 { ESOCKTNOSUPPORT
, osl_Socket_E_TypeNoSupport
}, /* Socket type not supported */
365 { EOPNOTSUPP
, osl_Socket_E_OpNotSupport
}, /* Operation not supported on socket */
366 { EPFNOSUPPORT
, osl_Socket_E_PfNoSupport
}, /* Protocol family not supported */
367 { EAFNOSUPPORT
, osl_Socket_E_AfNoSupport
}, /* Address family not supported by */
368 /* protocol family */
369 { EADDRINUSE
, osl_Socket_E_AddrInUse
}, /* Address already in use */
370 { EADDRNOTAVAIL
, osl_Socket_E_AddrNotAvail
}, /* Can't assign requested address */
371 { ENETDOWN
, osl_Socket_E_NetDown
}, /* Network is down */
372 { ENETUNREACH
, osl_Socket_E_NetUnreachable
}, /* Network is unreachable */
373 { ENETRESET
, osl_Socket_E_NetReset
}, /* Network dropped connection because */
375 { ECONNABORTED
, osl_Socket_E_ConnAborted
}, /* Software caused connection abort */
376 { ECONNRESET
, osl_Socket_E_ConnReset
}, /* Connection reset by peer */
377 { ENOBUFS
, osl_Socket_E_NoBufferSpace
}, /* No buffer space available */
378 { EISCONN
, osl_Socket_E_IsConnected
}, /* Socket is already connected */
379 { ENOTCONN
, osl_Socket_E_NotConnected
}, /* Socket is not connected */
380 { ESHUTDOWN
, osl_Socket_E_Shutdown
}, /* Can't send after socket shutdown */
381 { ETOOMANYREFS
, osl_Socket_E_TooManyRefs
}, /* Too many references: can't splice */
382 { ETIMEDOUT
, osl_Socket_E_TimedOut
}, /* Connection timed out */
383 { ECONNREFUSED
, osl_Socket_E_ConnRefused
}, /* Connection refused */
384 { EHOSTDOWN
, osl_Socket_E_HostDown
}, /* Host is down */
385 { EHOSTUNREACH
, osl_Socket_E_HostUnreachable
}, /* No route to host */
386 { EWOULDBLOCK
, osl_Socket_E_WouldBlock
}, /* call would block on non-blocking socket */
387 { EALREADY
, osl_Socket_E_Already
}, /* operation already in progress */
388 { EINPROGRESS
, osl_Socket_E_InProgress
}, /* operation now in progress */
389 { EAGAIN
, osl_Socket_E_WouldBlock
}, /* same as EWOULDBLOCK */
390 { -1, osl_Socket_E_InvalidError
}
395 static int osl_NativeFromSocketError(oslSocketError errorCode)
399 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
400 (SocketError[i].error != errorCode)) i++;
402 return SocketError[i].errcode;
407 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
411 while ((SocketError
[i
].error
!= osl_Socket_E_InvalidError
) &&
412 (SocketError
[i
].errcode
!= nativeType
)) i
++;
414 return SocketError
[i
].error
;
418 #define ERROR_TO_NATIVE(x) osl_NativeFromSocketError(x)
419 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
421 /*****************************************************************************/
422 /* local function prototypes */
423 /*****************************************************************************/
425 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
426 const sal_Char
* pszDottedAddr
, sal_Int32 Port
);
428 oslSocketAddr SAL_CALL
osl_psz_createIpxSocketAddr (
429 const sal_Char NetNumber
[4],
430 const sal_Char NodeNumber
[6],
431 sal_uInt32 SocketNumber
);
433 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
434 const sal_Char
*pszHostname
, const oslSocketAddr Addr
);
436 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (
437 const sal_Char
*pszHostname
);
439 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (
440 const oslHostAddr Addr
);
442 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
443 sal_Char
*pBuffer
, sal_uInt32 nBufLen
);
445 oslSocketAddr SAL_CALL
osl_psz_resolveHostname (
446 const sal_Char
* pszHostname
);
448 sal_Int32 SAL_CALL
osl_psz_getServicePort (
449 const sal_Char
* pszServicename
, const sal_Char
* pszProtocol
);
451 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr (
452 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
454 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr (
455 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
457 void SAL_CALL
osl_psz_getLastSocketErrorDescription (
458 oslSocket Socket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
);
460 /*****************************************************************************/
461 /* osl_create/destroy-SocketImpl */
462 /*****************************************************************************/
464 #if OSL_DEBUG_LEVEL > 1
465 static sal_uInt32 g_nSocketImpl
= 0;
466 static sal_uInt32 g_nSocketAddr
= 0;
468 /* sorry, must be implemented otherwise */
470 #endif /* OSL_DEBUG_LEVEL */
473 oslSocket
__osl_createSocketImpl(int Socket
)
477 pSocket
= (oslSocket
)calloc(1, sizeof(struct oslSocketImpl
));
479 pSocket
->m_Socket
= Socket
;
480 pSocket
->m_nLastError
= 0;
481 pSocket
->m_CloseCallback
= 0;
482 pSocket
->m_CallbackArg
= 0;
483 pSocket
->m_nRefCount
= 1;
486 pSocket
->m_bIsAccepting
= sal_False
;
489 #if OSL_DEBUG_LEVEL > 1
495 void __osl_destroySocketImpl(oslSocket Socket
)
498 free((struct oslSocketImpl
*) Socket
);
499 #if OSL_DEBUG_LEVEL > 1
504 static oslSocketAddr
__osl_createSocketAddr( )
506 oslSocketAddr pAddr
= (oslSocketAddr
) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
));
507 #if OSL_DEBUG_LEVEL > 1
513 static oslSocketAddr
__osl_createSocketAddrWithFamily(
514 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
518 OSL_ASSERT( family
== osl_Socket_FamilyInet
);
520 pAddr
= __osl_createSocketAddr();
523 case osl_Socket_FamilyInet
:
525 struct sockaddr_in
* pInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
527 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
528 pInetAddr
->sin_addr
.s_addr
= nAddr
;
529 pInetAddr
->sin_port
= (sal_uInt16
)(port
&0xffff);
533 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
538 static oslSocketAddr
__osl_createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
540 oslSocketAddr pAddr
= __osl_createSocketAddr();
541 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( struct sockaddr
) );
545 static void __osl_destroySocketAddr( oslSocketAddr addr
)
547 #if OSL_DEBUG_LEVEL > 1
550 rtl_freeMemory( addr
);
553 /*****************************************************************************/
554 /* osl_createEmptySocketAddr */
555 /*****************************************************************************/
556 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
558 oslSocketAddr pAddr
= 0;
560 /* is it an internet-Addr? */
561 if (Family
== osl_Socket_FamilyInet
)
563 pAddr
= __osl_createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
567 pAddr
= __osl_createSocketAddrWithFamily( Family
, 0 , 0 );
573 /*****************************************************************************/
574 /* osl_copySocketAddr */
575 /*****************************************************************************/
576 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
578 oslSocketAddr pCopy
= 0;
581 pCopy
= __osl_createSocketAddr();
584 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
589 /*****************************************************************************/
590 /* osl_isEqualSocketAddr */
591 /*****************************************************************************/
592 sal_Bool SAL_CALL
osl_isEqualSocketAddr (
596 struct sockaddr
* pAddr1
= NULL
;
597 struct sockaddr
* pAddr2
= NULL
;
601 pAddr1
= &(Addr1
->m_sockaddr
);
602 pAddr2
= &(Addr2
->m_sockaddr
);
606 if (pAddr1
== pAddr2
)
611 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
613 switch (pAddr1
->sa_family
)
617 struct sockaddr_in
* pInetAddr1
= (struct sockaddr_in
*)pAddr1
;
618 struct sockaddr_in
* pInetAddr2
= (struct sockaddr_in
*)pAddr2
;
620 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
621 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
622 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
628 return (memcmp(pAddr1
, pAddr2
, sizeof(struct sockaddr
)) == 0);
636 /*****************************************************************************/
637 /* osl_createInetBroadcastAddr */
638 /*****************************************************************************/
639 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
640 rtl_uString
*strDottedAddr
,
643 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
646 if (strDottedAddr
&& strDottedAddr
->length
)
648 /* Dotted host address for limited broadcast */
649 rtl_String
*pDottedAddr
= NULL
;
652 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
653 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
655 nAddr
= inet_addr (pDottedAddr
->buffer
);
656 rtl_string_release (pDottedAddr
);
659 if (nAddr
!= OSL_INADDR_NONE
)
661 /* Limited broadcast */
662 nAddr
= ntohl(nAddr
);
663 if (IN_CLASSA(nAddr
))
665 nAddr
&= IN_CLASSA_NET
;
666 nAddr
|= IN_CLASSA_HOST
;
668 else if (IN_CLASSB(nAddr
))
670 nAddr
&= IN_CLASSB_NET
;
671 nAddr
|= IN_CLASSB_HOST
;
673 else if (IN_CLASSC(nAddr
))
675 nAddr
&= IN_CLASSC_NET
;
676 nAddr
|= IN_CLASSC_HOST
;
680 /* No broadcast in class D */
681 return ((oslSocketAddr
)NULL
);
683 nAddr
= htonl(nAddr
);
686 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
), nAddr
);
690 /*****************************************************************************/
691 /* osl_createInetSocketAddr */
692 /*****************************************************************************/
693 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
694 rtl_uString
*ustrDottedAddr
,
697 rtl_String
* strDottedAddr
=0;
699 sal_Char
* pszDottedAddr
=0;
701 if ( ustrDottedAddr
!= 0 )
703 rtl_uString2String( &strDottedAddr
,
704 rtl_uString_getStr(ustrDottedAddr
),
705 rtl_uString_getLength(ustrDottedAddr
),
706 RTL_TEXTENCODING_UTF8
,
707 OUSTRING_TO_OSTRING_CVTFLAGS
);
708 pszDottedAddr
= rtl_string_getStr(strDottedAddr
);
712 Addr
= osl_psz_createInetSocketAddr(pszDottedAddr
, Port
);
714 if ( strDottedAddr
!= 0 )
716 rtl_string_release(strDottedAddr
);
722 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
723 const sal_Char
* pszDottedAddr
,
726 oslSocketAddr pAddr
= 0;
727 sal_Int32 Addr
= inet_addr(pszDottedAddr
);
730 /* valid dotted addr */
731 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
) , Addr
);
736 /*****************************************************************************/
737 /* osl_setAddrOfSocketAddr */
738 /*****************************************************************************/
739 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
741 oslSocketResult res
= osl_Socket_Error
;
744 OSL_ASSERT( pByteSeq
);
746 if( pAddr
&& pByteSeq
)
748 struct sockaddr_in
* pSystemInetAddr
;
750 OSL_ASSERT( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
751 OSL_ASSERT( pByteSeq
->nElements
== 4 );
753 pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
754 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
760 /*****************************************************************************/
761 /* osl_getAddrOfSocketAddr */
762 /*****************************************************************************/
763 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
765 oslSocketResult res
= osl_Socket_Error
;
768 OSL_ASSERT( ppByteSeq
);
770 if( pAddr
&& ppByteSeq
)
772 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
773 rtl_byte_sequence_constructFromArray( ppByteSeq
, (sal_Int8
*) &(pSystemInetAddr
->sin_addr
),4);
780 /*****************************************************************************/
781 /* _osl_getFullQualifiedDomainName */
782 /*****************************************************************************/
784 /** try to figure out a full-qualified hostname, by adding the current domain
785 as given by the domainname program to the given hostname.
786 This function MUST NOT call gethostbyname since pHostName allready points
787 to data returned by gethostname and would be garbled: use gethostname_r
791 /* wrap around different interfaces to reentrant gethostbyname */
792 static struct hostent
* _osl_gethostbyname_r (
793 const char *name
, struct hostent
*result
,
794 char *buffer
, int buflen
, int *h_errnop
)
796 #if defined(LINUX) || defined(ANDROID) || (defined(FREEBSD) && (__FreeBSD_version >= 601103)) || defined(DRAGONFLY)
797 struct hostent
*__result
; /* will be the same as result */
799 __error
= gethostbyname_r (name
, result
, buffer
, buflen
,
800 &__result
, h_errnop
);
801 return __error
? NULL
: __result
;
803 *h_errnop
= gethostbyname_r (name
, result
, (struct hostent_data
*)buffer
);
805 return *h_errnop
? NULL
: result
;
807 return gethostbyname_r( name
, result
, buffer
, buflen
, h_errnop
);
811 static sal_Char
* _osl_getFullQualifiedDomainName (const sal_Char
*pHostName
)
813 # define DOMAINNAME_LENGTH 512
814 struct hostent aHostByName
;
815 struct hostent
*pHostByName
;
816 sal_Char pQualifiedHostBuffer
[ MAX_HOSTBUFFER_SIZE
];
817 sal_Char
*pFullQualifiedName
= NULL
;
820 pHostByName
= _osl_gethostbyname_r (
822 &aHostByName
, pQualifiedHostBuffer
,
823 sizeof(pQualifiedHostBuffer
), &nErrorNo
);
824 if (pHostByName
!= NULL
)
826 pFullQualifiedName
= strdup(pHostByName
->h_name
);
828 return pFullQualifiedName
;
830 /*****************************************************************************/
831 /* _osl_isFullQualifiedDomainName */
832 /*****************************************************************************/
833 static sal_Bool
_osl_isFullQualifiedDomainName (const sal_Char
*pHostName
)
835 /* a FQDN (aka 'hostname.domain.top_level_domain' )
836 * is a name which contains a dot '.' in it ( would
837 * match as well for 'hostname.' but is good enough
839 return (sal_Bool
)( strchr( pHostName
, (int)'.' ) != NULL
);
842 /*****************************************************************************/
844 /*****************************************************************************/
845 struct oslHostAddrImpl
848 oslSocketAddr pSockAddr
;
851 static oslHostAddr
_osl_hostentToHostAddr (const struct hostent
*he
)
853 oslHostAddr pAddr
= NULL
;
854 oslSocketAddr pSockAddr
= 0;
858 if ((he
== NULL
) || (he
->h_name
== NULL
) || (he
->h_addr_list
[0] == NULL
))
859 return ((oslHostAddr
)NULL
);
861 if (_osl_isFullQualifiedDomainName(he
->h_name
))
863 cn
= (sal_Char
*)malloc(strlen (he
->h_name
) + 1);
866 return ((oslHostAddr
)NULL
);
868 strcpy(cn
, he
->h_name
);
872 cn
=_osl_getFullQualifiedDomainName (he
->h_name
);
875 return ((oslHostAddr
)NULL
);
878 pSockAddr
= __osl_createSocketAddr();
879 OSL_ASSERT(pSockAddr
);
880 if (pSockAddr
== NULL
)
883 return ((oslHostAddr
)NULL
);
886 pSockAddr
->m_sockaddr
.sa_family
= he
->h_addrtype
;
887 if (pSockAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
889 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&(pSockAddr
->m_sockaddr
);
891 &(sin
->sin_addr
.s_addr
),
897 /* unknown address family */
898 /* future extensions for new families might be implemented here */
900 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.");
901 OSL_ASSERT(sal_False
);
903 __osl_destroySocketAddr( pSockAddr
);
905 return ((oslHostAddr
)NULL
);
908 pAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
912 __osl_destroySocketAddr( pSockAddr
);
914 return ((oslHostAddr
)NULL
);
917 pAddr
->pHostName
= cn
;
918 pAddr
->pSockAddr
= pSockAddr
;
923 /*****************************************************************************/
924 /* osl_createHostAddr */
925 /*****************************************************************************/
926 oslHostAddr SAL_CALL
osl_createHostAddr (
927 rtl_uString
*ustrHostname
,
928 const oslSocketAddr Addr
)
930 oslHostAddr HostAddr
;
931 rtl_String
* strHostname
=0;
932 sal_Char
* pszHostName
=0;
934 if ( ustrHostname
!= 0 )
936 rtl_uString2String( &strHostname
,
937 rtl_uString_getStr(ustrHostname
),
938 rtl_uString_getLength(ustrHostname
),
939 RTL_TEXTENCODING_UTF8
,
940 OUSTRING_TO_OSTRING_CVTFLAGS
);
941 pszHostName
= rtl_string_getStr(strHostname
);
944 HostAddr
= osl_psz_createHostAddr(pszHostName
,Addr
);
946 if ( strHostname
!= 0 )
948 rtl_string_release(strHostname
);
954 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
955 const sal_Char
*pszHostname
,
956 const oslSocketAddr pAddr
)
958 oslHostAddr pHostAddr
;
961 OSL_ASSERT(pszHostname
&& pAddr
);
962 if ((pszHostname
== NULL
) || (pAddr
== NULL
))
963 return ((oslHostAddr
)NULL
);
965 cn
= (sal_Char
*)malloc(strlen (pszHostname
) + 1);
968 return ((oslHostAddr
)NULL
);
970 strcpy (cn
, pszHostname
);
972 pHostAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
973 OSL_ASSERT(pHostAddr
);
974 if (pHostAddr
== NULL
)
977 return ((oslHostAddr
)NULL
);
980 pHostAddr
->pHostName
= cn
;
981 pHostAddr
->pSockAddr
= osl_copySocketAddr( pAddr
);
986 /*****************************************************************************/
987 /* osl_createHostAddrByName */
988 /*****************************************************************************/
989 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*ustrHostname
)
991 oslHostAddr HostAddr
;
992 rtl_String
* strHostname
=0;
993 sal_Char
* pszHostName
=0;
995 if ( ustrHostname
!= 0 )
997 rtl_uString2String( &strHostname
,
998 rtl_uString_getStr(ustrHostname
),
999 rtl_uString_getLength(ustrHostname
),
1000 RTL_TEXTENCODING_UTF8
,
1001 OUSTRING_TO_OSTRING_CVTFLAGS
);
1002 pszHostName
=rtl_string_getStr(strHostname
);
1005 HostAddr
= osl_psz_createHostAddrByName(pszHostName
);
1007 if ( strHostname
!= 0 )
1009 rtl_string_release(strHostname
);
1015 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (const sal_Char
*pszHostname
)
1018 struct hostent
*pHe
;
1019 sal_Char heBuffer
[ MAX_HOSTBUFFER_SIZE
];
1022 pHe
= _osl_gethostbyname_r (
1025 sizeof(heBuffer
), &nErrorNo
);
1027 return _osl_hostentToHostAddr (pHe
);
1030 /*****************************************************************************/
1031 /* osl_createHostAddrByAddr */
1032 /*****************************************************************************/
1033 oslHostAddr SAL_CALL
osl_createHostAddrByAddr (const oslSocketAddr pAddr
)
1038 return ((oslHostAddr
)NULL
);
1040 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1042 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1045 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
1046 return ((oslHostAddr
)NULL
);
1048 he
= gethostbyaddr((sal_Char
*)&(sin
->sin_addr
),
1049 sizeof (sin
->sin_addr
),
1051 return _osl_hostentToHostAddr (he
);
1054 return ((oslHostAddr
)NULL
);
1057 /*****************************************************************************/
1058 /* osl_copyHostAddr */
1059 /*****************************************************************************/
1060 oslHostAddr SAL_CALL
osl_copyHostAddr (const oslHostAddr pAddr
)
1065 return osl_psz_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
1067 return ((oslHostAddr
)NULL
);
1070 /*****************************************************************************/
1071 /* osl_getHostnameOfHostAddr */
1072 /*****************************************************************************/
1073 void SAL_CALL
osl_getHostnameOfHostAddr (
1074 const oslHostAddr Addr
,
1075 rtl_uString
**ustrHostname
)
1077 const sal_Char
* pHostname
=0;
1079 pHostname
= osl_psz_getHostnameOfHostAddr(Addr
);
1081 rtl_uString_newFromAscii (ustrHostname
, pHostname
);
1086 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr
)
1089 return pAddr
->pHostName
;
1094 /*****************************************************************************/
1095 /* osl_getSocketAddrOfHostAddr */
1096 /*****************************************************************************/
1097 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr
)
1102 return ((oslSocketAddr
)(pAddr
->pSockAddr
));
1107 /*****************************************************************************/
1108 /* osl_destroyHostAddr */
1109 /*****************************************************************************/
1110 void SAL_CALL
osl_destroyHostAddr (oslHostAddr pAddr
)
1114 if (pAddr
->pHostName
)
1115 free (pAddr
->pHostName
);
1116 if (pAddr
->pSockAddr
)
1117 osl_destroySocketAddr (pAddr
->pSockAddr
);
1122 /*****************************************************************************/
1123 /* osl_getLocalHostname */
1124 /*****************************************************************************/
1125 oslSocketResult SAL_CALL
osl_getLocalHostname(rtl_uString
**ustrLocalHostname
)
1127 oslSocketResult Result
;
1128 sal_Char pszHostname
[1024];
1130 pszHostname
[0] = '\0';
1132 Result
= osl_psz_getLocalHostname(pszHostname
,sizeof(pszHostname
));
1134 rtl_uString_newFromAscii(ustrLocalHostname
,pszHostname
);
1139 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
1140 sal_Char
*pBuffer
, sal_uInt32 nBufLen
)
1142 static sal_Char LocalHostname
[256] = "";
1144 if (strlen(LocalHostname
) == 0)
1146 const sal_Char
*pStr
;
1151 if (uname(&uts
) < 0)
1152 return osl_Socket_Error
;
1154 if ((strlen(uts
.nodename
) + 1) > nBufLen
)
1155 return osl_Socket_Error
;
1157 strncpy(LocalHostname
, uts
.nodename
, sizeof( LocalHostname
));
1158 #else /* BSD compatible */
1160 if (gethostname(LocalHostname
, sizeof(LocalHostname
)-1) != 0)
1161 return osl_Socket_Error
;
1162 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
1165 /* check if we have an FQDN */
1166 if (strchr(LocalHostname
, '.') == NULL
)
1170 /* no, determine it via dns */
1171 Addr
= osl_psz_createHostAddrByName(LocalHostname
);
1173 if ((pStr
= osl_psz_getHostnameOfHostAddr(Addr
)) != NULL
)
1175 strcpy(LocalHostname
, pStr
);
1177 osl_destroyHostAddr(Addr
);
1181 if (strlen(LocalHostname
) > 0)
1183 strncpy(pBuffer
, LocalHostname
, nBufLen
);
1184 pBuffer
[nBufLen
- 1] = '\0';
1186 return osl_Socket_Ok
;
1189 return osl_Socket_Error
;
1192 /*****************************************************************************/
1193 /* osl_resolveHostname */
1194 /*****************************************************************************/
1195 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
*ustrHostname
)
1198 rtl_String
* strHostname
=0;
1199 sal_Char
* pszHostName
=0;
1201 if ( ustrHostname
!= 0 )
1203 rtl_uString2String( &strHostname
,
1204 rtl_uString_getStr(ustrHostname
),
1205 rtl_uString_getLength(ustrHostname
),
1206 RTL_TEXTENCODING_UTF8
,
1207 OUSTRING_TO_OSTRING_CVTFLAGS
);
1208 pszHostName
= rtl_string_getStr(strHostname
);
1212 Addr
= osl_psz_resolveHostname(pszHostName
);
1214 if ( strHostname
!= 0 )
1216 rtl_string_release(strHostname
);
1224 oslSocketAddr SAL_CALL
osl_psz_resolveHostname(const sal_Char
* pszHostname
)
1226 struct oslHostAddrImpl
*pAddr
= (oslHostAddr
)osl_psz_createHostAddrByName(pszHostname
);
1230 oslSocketAddr SockAddr
= osl_copySocketAddr(pAddr
->pSockAddr
);
1232 osl_destroyHostAddr(pAddr
);
1237 return ((oslSocketAddr
)NULL
);
1240 /*****************************************************************************/
1241 /* osl_getServicePort */
1242 /*****************************************************************************/
1243 sal_Int32 SAL_CALL
osl_getServicePort(rtl_uString
*ustrServicename
, rtl_uString
*ustrProtocol
)
1246 rtl_String
* strServicename
=0;
1247 rtl_String
* strProtocol
=0;
1248 sal_Char
* pszServiceName
=0;
1249 sal_Char
* pszProtocol
=0;
1251 if ( ustrServicename
!= 0 )
1253 rtl_uString2String( &strServicename
,
1254 rtl_uString_getStr(ustrServicename
),
1255 rtl_uString_getLength(ustrServicename
),
1256 RTL_TEXTENCODING_UTF8
,
1257 OUSTRING_TO_OSTRING_CVTFLAGS
);
1258 pszServiceName
= rtl_string_getStr(strServicename
);
1261 if ( ustrProtocol
!= 0 )
1263 rtl_uString2String( &strProtocol
,
1264 rtl_uString_getStr(ustrProtocol
),
1265 rtl_uString_getLength(ustrProtocol
),
1266 RTL_TEXTENCODING_UTF8
,
1267 OUSTRING_TO_OSTRING_CVTFLAGS
);
1268 pszProtocol
= rtl_string_getStr(strProtocol
);
1271 nPort
= osl_psz_getServicePort(pszServiceName
,pszProtocol
);
1273 if ( strServicename
!= 0 )
1275 rtl_string_release(strServicename
);
1278 if ( strProtocol
!= 0 )
1280 rtl_string_release(strProtocol
);
1288 sal_Int32 SAL_CALL
osl_psz_getServicePort(const sal_Char
* pszServicename
,
1289 const sal_Char
* pszProtocol
)
1293 ps
= getservbyname(pszServicename
, pszProtocol
);
1296 return ntohs(ps
->s_port
);
1298 return OSL_INVALID_PORT
;
1301 /*****************************************************************************/
1302 /* osl_destroySocketAddr */
1303 /*****************************************************************************/
1304 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
1306 __osl_destroySocketAddr( pAddr
);
1309 /*****************************************************************************/
1310 /* osl_getFamilyOfSocketAddr */
1311 /*****************************************************************************/
1312 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
1317 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1319 return osl_Socket_FamilyInvalid
;
1322 /*****************************************************************************/
1323 /* osl_getInetPortOfSocketAddr */
1324 /*****************************************************************************/
1325 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
1330 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1332 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1333 return ntohs(pSystemInetAddr
->sin_port
);
1335 return OSL_INVALID_PORT
;
1338 /*****************************************************************************/
1339 /* osl_setInetPortOfSocketAddr */
1340 /*****************************************************************************/
1341 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr
, sal_Int32 Port
)
1346 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1347 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1349 pSystemInetAddr
->sin_port
= htons((short)Port
);
1354 /* this is not a inet-addr => can't set port */
1358 /*****************************************************************************/
1359 /* osl_getHostnameOfSocketAddr */
1360 /*****************************************************************************/
1361 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrHostname
)
1363 oslSocketResult Result
;
1364 sal_Char pszHostname
[1024];
1366 pszHostname
[0] = '\0';
1368 Result
= osl_psz_getHostnameOfSocketAddr(Addr
,pszHostname
,sizeof(pszHostname
));
1370 rtl_uString_newFromAscii(ustrHostname
,pszHostname
);
1376 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr
,
1377 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1379 oslHostAddr pHostAddr
= (oslHostAddr
)osl_createHostAddrByAddr(pAddr
);
1383 strncpy(pBuffer
, pHostAddr
->pHostName
, BufferSize
);
1385 pBuffer
[BufferSize
- 1] = '\0';
1387 osl_destroyHostAddr(pHostAddr
);
1389 return osl_Socket_Ok
;
1392 return osl_Socket_Error
;
1395 /*****************************************************************************/
1396 /* osl_getDottedInetAddrOfSocketAddr */
1397 /*****************************************************************************/
1398 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrDottedInetAddr
)
1400 oslSocketResult Result
;
1401 sal_Char pszDottedInetAddr
[1024];
1403 pszDottedInetAddr
[0] = '\0';
1405 Result
= osl_psz_getDottedInetAddrOfSocketAddr(Addr
,pszDottedInetAddr
,sizeof(pszDottedInetAddr
));
1407 rtl_uString_newFromAscii(ustrDottedInetAddr
,pszDottedInetAddr
);
1413 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr
,
1414 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1420 struct sockaddr_in
* pSystemInetAddr
= ( struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
1422 if (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1424 strncpy(pBuffer
, inet_ntoa(pSystemInetAddr
->sin_addr
), BufferSize
);
1425 pBuffer
[BufferSize
- 1] = '\0';
1427 return osl_Socket_Ok
;
1431 return osl_Socket_Error
;
1434 /*****************************************************************************/
1435 /* osl_createSocket */
1436 /*****************************************************************************/
1437 oslSocket SAL_CALL
osl_createSocket(oslAddrFamily Family
,
1439 oslProtocol Protocol
)
1445 pSocket
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1448 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
1449 TYPE_TO_NATIVE(Type
),
1450 PROTOCOL_TO_NATIVE(Protocol
));
1452 /* creation failed => free memory */
1453 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
1455 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1459 __osl_destroySocketImpl((pSocket
));
1464 /* set close-on-exec flag */
1465 if ((Flags
= fcntl(pSocket
->m_Socket
, F_GETFD
, 0)) != -1)
1467 Flags
|= FD_CLOEXEC
;
1468 if (fcntl(pSocket
->m_Socket
, F_SETFD
, Flags
) == -1)
1470 pSocket
->m_nLastError
=errno
;
1471 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1478 pSocket
->m_nLastError
=errno
;
1482 pSocket
->m_CloseCallback
= NULL
;
1483 pSocket
->m_CallbackArg
= NULL
;
1489 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
1491 osl_incrementInterlockedCount( &(pSocket
->m_nRefCount
) );
1494 void SAL_CALL
osl_releaseSocket( oslSocket pSocket
)
1496 if( pSocket
&& 0 == osl_decrementInterlockedCount( &(pSocket
->m_nRefCount
) ) )
1499 if ( pSocket
->m_bIsAccepting
== sal_True
)
1501 OSL_FAIL("osl_destroySocket : attempt to destroy socket while accepting\n");
1505 osl_closeSocket( pSocket
);
1506 __osl_destroySocketImpl( pSocket
);
1512 /*****************************************************************************/
1513 /* osl_closeSocket */
1514 /*****************************************************************************/
1515 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
1520 /* socket already invalid */
1524 pSocket
->m_nLastError
=0;
1525 nFD
= pSocket
->m_Socket
;
1527 if (nFD
== OSL_INVALID_SOCKET
)
1530 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1533 pSocket
->m_bIsInShutdown
= sal_True
;
1535 if ( pSocket
->m_bIsAccepting
== sal_True
)
1539 struct sockaddr aSockAddr
;
1540 struct sockaddr_in aSockAddrIn
;
1542 socklen_t nSockLen
= sizeof(s
.aSockAddr
);
1544 nRet
= getsockname(nFD
, &s
.aSockAddr
, &nSockLen
);
1547 OSL_TRACE("getsockname call failed with error: %s", strerror(errno
));
1550 if ( s
.aSockAddr
.sa_family
== AF_INET
)
1552 if ( s
.aSockAddrIn
.sin_addr
.s_addr
== htonl(INADDR_ANY
) )
1554 s
.aSockAddrIn
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1557 nConnFD
= socket(AF_INET
, SOCK_STREAM
, 0);
1560 OSL_TRACE("socket call failed with error: %s", strerror(errno
));
1563 nRet
= connect(nConnFD
, &s
.aSockAddr
, sizeof(s
.aSockAddr
));
1566 OSL_TRACE("connect call failed with error: %s", strerror(errno
));
1570 pSocket
->m_bIsAccepting
= sal_False
;
1574 /* registrierten Callback ausfuehren */
1575 if (pSocket
->m_CloseCallback
!= NULL
)
1577 pSocket
->m_CloseCallback(pSocket
->m_CallbackArg
);
1583 pSocket
->m_nLastError
=errno
;
1584 OSL_TRACE("closeSocket close error '%s'",strerror(errno
));
1587 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1590 /*****************************************************************************/
1591 /* osl_getLocalAddrOfSocket */
1592 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1593 /* are the same! I don't like it very much but see no other easy way to conceal */
1594 /* the struct sockaddr from the eyes of the user. */
1595 /*****************************************************************************/
1596 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
1599 struct sockaddr Addr
;
1600 oslSocketAddr pAddr
;
1602 if (pSocket
== NULL
) /* ENOTSOCK */
1603 return ((oslSocketAddr
)NULL
);
1605 AddrLen
= sizeof(struct sockaddr
);
1607 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1608 return ((oslSocketAddr
)NULL
);
1610 pAddr
= __osl_createSocketAddrFromSystem( &Addr
);
1614 /*****************************************************************************/
1615 /* osl_getPeerAddrOfSocket */
1616 /*****************************************************************************/
1617 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1620 struct sockaddr Addr
;
1622 OSL_ASSERT(pSocket
);
1628 pSocket
->m_nLastError
=0;
1629 AddrLen
= sizeof(struct sockaddr
);
1631 if(getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1633 pSocket
->m_nLastError
=errno
;
1636 return __osl_createSocketAddrFromSystem( &Addr
);
1639 /*****************************************************************************/
1640 /* osl_bindAddrToSocket */
1641 /*****************************************************************************/
1642 sal_Bool SAL_CALL
osl_bindAddrToSocket(oslSocket pSocket
,
1643 oslSocketAddr pAddr
)
1647 OSL_ASSERT(pSocket
&& pAddr
);
1648 if ( pSocket
== 0 || pAddr
== 0 )
1653 pSocket
->m_nLastError
=0;
1655 nRet
= bind(pSocket
->m_Socket
, &(pAddr
->m_sockaddr
), sizeof(struct sockaddr
));
1657 if ( nRet
== OSL_SOCKET_ERROR
)
1659 pSocket
->m_nLastError
=errno
;
1667 /*****************************************************************************/
1668 /* osl_listenOnSocket */
1669 /*****************************************************************************/
1670 sal_Bool SAL_CALL
osl_listenOnSocket(oslSocket pSocket
,
1671 sal_Int32 MaxPendingConnections
)
1675 OSL_ASSERT(pSocket
);
1681 pSocket
->m_nLastError
=0;
1683 nRet
= listen(pSocket
->m_Socket
,
1684 MaxPendingConnections
== -1 ?
1686 MaxPendingConnections
);
1687 if ( nRet
== OSL_SOCKET_ERROR
)
1689 pSocket
->m_nLastError
=errno
;
1697 /*****************************************************************************/
1698 /* osl_connectSocketTo */
1699 /*****************************************************************************/
1700 oslSocketResult SAL_CALL
osl_connectSocketTo(oslSocket pSocket
,
1701 oslSocketAddr pAddr
,
1702 const TimeValue
* pTimeout
)
1708 oslSocketResult Result
= osl_Socket_Ok
;
1710 OSL_PRECOND(pSocket
, "osl_connectSocketTo(): need a valid socket!\n");
1714 return osl_Socket_Error
;
1717 pSocket
->m_nLastError
=0;
1719 if (osl_isNonBlockingMode(pSocket
))
1721 if (connect(pSocket
->m_Socket
,
1722 &(pAddr
->m_sockaddr
),
1723 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1724 return osl_Socket_Ok
;
1726 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
1728 pSocket
->m_nLastError
=EINPROGRESS
;
1729 return osl_Socket_InProgress
;
1733 pSocket
->m_nLastError
=errno
;
1734 OSL_TRACE("can't connect : '%s'",strerror(errno
));
1735 return osl_Socket_Error
;
1738 /* set socket temporarily to non-blocking */
1739 OSL_VERIFY(osl_enableNonBlockingMode(pSocket
, sal_True
));
1741 /* initiate connect */
1742 if(connect(pSocket
->m_Socket
,
1743 &(pAddr
->m_sockaddr
),
1744 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
1746 /* immediate connection */
1747 osl_enableNonBlockingMode(pSocket
, sal_False
);
1749 return osl_Socket_Ok
;
1753 /* really an error or just delayed? */
1754 if (errno
!= EINPROGRESS
)
1756 pSocket
->m_nLastError
=errno
;
1758 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
1759 errno
, strerror(errno
));
1761 osl_enableNonBlockingMode(pSocket
, sal_False
);
1762 return osl_Socket_Error
;
1767 /* prepare select set for socket */
1770 FD_SET(pSocket
->m_Socket
, &WriteSet
);
1771 FD_SET(pSocket
->m_Socket
, &ExcptSet
);
1773 /* prepare timeout */
1776 /* divide milliseconds into seconds and microseconds */
1777 tv
.tv_sec
= pTimeout
->Seconds
;
1778 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
1782 ReadyHandles
= select(pSocket
->m_Socket
+1,
1784 PTR_FD_SET(WriteSet
),
1785 PTR_FD_SET(ExcptSet
),
1786 (pTimeout
) ? &tv
: 0);
1788 if (ReadyHandles
> 0) /* connected */
1790 if ( FD_ISSET(pSocket
->m_Socket
, &WriteSet
) )
1793 socklen_t nErrorSize
= sizeof( nErrorCode
);
1797 nSockOpt
= getsockopt ( pSocket
->m_Socket
, SOL_SOCKET
, SO_ERROR
,
1798 &nErrorCode
, &nErrorSize
);
1799 if ( (nSockOpt
== 0) && (nErrorCode
== 0))
1800 Result
= osl_Socket_Ok
;
1802 Result
= osl_Socket_Error
;
1806 Result
= osl_Socket_Error
;
1809 else if (ReadyHandles
< 0) /* error */
1811 if (errno
== EBADF
) /* most probably interrupted by close() */
1813 /* do not access pSockImpl because it is about to be or */
1814 /* already destroyed */
1815 return osl_Socket_Interrupted
;
1819 pSocket
->m_nLastError
=errno
;
1820 Result
= osl_Socket_Error
;
1825 pSocket
->m_nLastError
=errno
;
1826 Result
= osl_Socket_TimedOut
;
1829 osl_enableNonBlockingMode(pSocket
, sal_False
);
1835 /*****************************************************************************/
1836 /* osl_acceptConnectionOnSocket */
1837 /*****************************************************************************/
1838 oslSocket SAL_CALL
osl_acceptConnectionOnSocket(oslSocket pSocket
,
1839 oslSocketAddr
* ppAddr
)
1841 struct sockaddr Addr
;
1842 int Connection
, Flags
;
1843 oslSocket pConnectionSockImpl
;
1845 socklen_t AddrLen
= sizeof(struct sockaddr
);
1846 OSL_ASSERT(pSocket
);
1852 pSocket
->m_nLastError
=0;
1854 pSocket
->m_bIsAccepting
= sal_True
;
1857 if( ppAddr
&& *ppAddr
)
1859 osl_destroySocketAddr( *ppAddr
);
1863 /* prevent Linux EINTR behaviour */
1866 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
1867 } while (Connection
== -1 && errno
== EINTR
);
1870 /* accept failed? */
1871 if( Connection
== OSL_SOCKET_ERROR
)
1873 pSocket
->m_nLastError
=errno
;
1874 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'",strerror(errno
));
1877 pSocket
->m_bIsAccepting
= sal_False
;
1882 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
1886 if ( pSocket
->m_bIsInShutdown
== sal_True
)
1889 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept");
1897 *ppAddr
= __osl_createSocketAddrFromSystem(&Addr
);
1901 pConnectionSockImpl
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1903 /* set close-on-exec flag */
1904 if ((Flags
= fcntl(Connection
, F_GETFD
, 0)) != -1)
1906 Flags
|= FD_CLOEXEC
;
1907 if (fcntl(Connection
, F_SETFD
, Flags
) == -1)
1909 pSocket
->m_nLastError
=errno
;
1910 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
1917 pConnectionSockImpl
->m_Socket
= Connection
;
1918 pConnectionSockImpl
->m_nLastError
= 0;
1919 pConnectionSockImpl
->m_CloseCallback
= NULL
;
1920 pConnectionSockImpl
->m_CallbackArg
= NULL
;
1922 pConnectionSockImpl
->m_bIsAccepting
= sal_False
;
1924 pSocket
->m_bIsAccepting
= sal_False
;
1926 return pConnectionSockImpl
;
1929 /*****************************************************************************/
1930 /* osl_receiveSocket */
1931 /*****************************************************************************/
1932 sal_Int32 SAL_CALL
osl_receiveSocket(oslSocket pSocket
,
1934 sal_uInt32 BytesToRead
,
1935 oslSocketMsgFlag Flag
)
1939 OSL_ASSERT(pSocket
);
1942 OSL_TRACE("osl_receiveSocket : Invalid socket");
1946 pSocket
->m_nLastError
=0;
1950 nRead
= recv(pSocket
->m_Socket
,
1953 MSG_FLAG_TO_NATIVE(Flag
));
1954 } while ( nRead
< 0 && errno
== EINTR
);
1958 pSocket
->m_nLastError
=errno
;
1959 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,strerror(errno
));
1961 else if ( nRead
== 0 )
1963 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
1970 /*****************************************************************************/
1971 /* osl_receiveFromSocket */
1972 /*****************************************************************************/
1973 sal_Int32 SAL_CALL
osl_receiveFromSocket(oslSocket pSocket
,
1974 oslSocketAddr pSenderAddr
,
1976 sal_uInt32 BufferSize
,
1977 oslSocketMsgFlag Flag
)
1980 struct sockaddr
*pSystemSockAddr
= 0;
1981 socklen_t AddrLen
= 0;
1984 AddrLen
= sizeof( struct sockaddr
);
1985 pSystemSockAddr
= &(pSenderAddr
->m_sockaddr
);
1988 OSL_ASSERT(pSocket
);
1991 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
1995 pSocket
->m_nLastError
=0;
1997 nRead
= recvfrom(pSocket
->m_Socket
,
2000 MSG_FLAG_TO_NATIVE(Flag
),
2006 pSocket
->m_nLastError
=errno
;
2007 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead
,strerror(errno
));
2009 else if ( nRead
== 0 )
2011 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
2018 /*****************************************************************************/
2019 /* osl_sendSocket */
2020 /*****************************************************************************/
2021 sal_Int32 SAL_CALL
osl_sendSocket(oslSocket pSocket
,
2022 const void* pBuffer
,
2023 sal_uInt32 BytesToSend
,
2024 oslSocketMsgFlag Flag
)
2028 OSL_ASSERT(pSocket
);
2031 OSL_TRACE("osl_sendSocket : Invalid socket");
2035 pSocket
->m_nLastError
=0;
2039 nWritten
= send(pSocket
->m_Socket
,
2042 MSG_FLAG_TO_NATIVE(Flag
));
2043 } while ( nWritten
< 0 && errno
== EINTR
);
2048 pSocket
->m_nLastError
=errno
;
2049 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,strerror(errno
));
2051 else if ( nWritten
== 0 )
2053 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,"EOL");
2059 /*****************************************************************************/
2060 /* osl_sendToSocket */
2061 /*****************************************************************************/
2062 sal_Int32 SAL_CALL
osl_sendToSocket(oslSocket pSocket
,
2063 oslSocketAddr ReceiverAddr
,
2064 const void* pBuffer
,
2065 sal_uInt32 BytesToSend
,
2066 oslSocketMsgFlag Flag
)
2070 struct sockaddr
*pSystemSockAddr
= 0;
2074 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
2075 AddrLen
= sizeof( struct sockaddr
);
2078 OSL_ASSERT(pSocket
);
2081 OSL_TRACE("osl_sendToSocket : Invalid socket");
2085 pSocket
->m_nLastError
=0;
2087 /* ReceiverAddr might be 0 when used on a connected socket. */
2088 /* Then sendto should behave like send. */
2090 nWritten
= sendto(pSocket
->m_Socket
,
2093 MSG_FLAG_TO_NATIVE(Flag
),
2099 pSocket
->m_nLastError
=errno
;
2100 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,strerror(errno
));
2102 else if ( nWritten
== 0 )
2104 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,"EOL");
2110 /*****************************************************************************/
2111 /* osl_readSocket */
2112 /*****************************************************************************/
2113 sal_Int32 SAL_CALL
osl_readSocket (
2114 oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
2116 sal_uInt8
* Ptr
= (sal_uInt8
*)pBuffer
;
2117 sal_uInt32 BytesRead
= 0;
2118 sal_uInt32 BytesToRead
= n
;
2120 OSL_ASSERT( pSocket
);
2122 /* loop until all desired bytes were read or an error occurred */
2123 while (BytesToRead
> 0)
2126 RetVal
= osl_receiveSocket(pSocket
,
2129 osl_Socket_MsgNormal
);
2131 /* error occurred? */
2137 BytesToRead
-= RetVal
;
2138 BytesRead
+= RetVal
;
2145 /*****************************************************************************/
2146 /* osl_writeSocket */
2147 /*****************************************************************************/
2148 sal_Int32 SAL_CALL
osl_writeSocket(
2149 oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
2151 /* loop until all desired bytes were send or an error occurred */
2152 sal_uInt32 BytesSend
= 0;
2153 sal_uInt32 BytesToSend
= n
;
2154 sal_uInt8
*Ptr
= ( sal_uInt8
* )pBuffer
;
2156 OSL_ASSERT( pSocket
);
2158 while (BytesToSend
> 0)
2162 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
2164 /* error occurred? */
2170 BytesToSend
-= RetVal
;
2171 BytesSend
+= RetVal
;
2178 /*****************************************************************************/
2179 /* __osl_socket_poll */
2180 /*****************************************************************************/
2182 #ifdef HAVE_POLL_H /* poll() */
2184 sal_Bool
__osl_socket_poll (
2186 const TimeValue
* pTimeout
,
2193 OSL_ASSERT(0 != pSocket
);
2195 return sal_False
; /* EINVAL */
2197 pSocket
->m_nLastError
= 0;
2199 fds
.fd
= pSocket
->m_Socket
;
2200 fds
.events
= nEvent
;
2206 /* Convert to [ms] */
2207 timeout
= pTimeout
->Seconds
* 1000;
2208 timeout
+= pTimeout
->Nanosec
/ (1000 * 1000);
2211 result
= poll (&fds
, 1, timeout
);
2214 pSocket
->m_nLastError
= errno
;
2215 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2216 errno
, strerror(errno
));
2225 return ((fds
.revents
& nEvent
) == nEvent
);
2228 #else /* select() */
2230 sal_Bool
__osl_socket_poll (
2232 const TimeValue
* pTimeout
,
2239 OSL_ASSERT(0 != pSocket
);
2241 return sal_False
; /* EINVAL */
2243 pSocket
->m_nLastError
= 0;
2246 FD_SET(pSocket
->m_Socket
, &fds
);
2250 /* Convert to 'timeval' */
2251 tv
.tv_sec
= pTimeout
->Seconds
;
2252 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000;
2256 pSocket
->m_Socket
+ 1,
2257 (nEvent
== POLLIN
) ? PTR_FD_SET(fds
) : NULL
,
2258 (nEvent
== POLLOUT
) ? PTR_FD_SET(fds
) : NULL
,
2259 (nEvent
== POLLPRI
) ? PTR_FD_SET(fds
) : NULL
,
2260 (pTimeout
) ? &tv
: NULL
);
2264 pSocket
->m_nLastError
= errno
;
2265 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2266 errno
, strerror(errno
));
2275 return (FD_ISSET(pSocket
->m_Socket
, &fds
) ? sal_True
: sal_False
);
2278 #endif /* HAVE_POLL_H */
2280 /*****************************************************************************/
2281 /* osl_isReceiveReady */
2282 /*****************************************************************************/
2283 sal_Bool SAL_CALL
osl_isReceiveReady (
2284 oslSocket pSocket
, const TimeValue
* pTimeout
)
2286 OSL_ASSERT(pSocket
);
2287 if (pSocket
== NULL
)
2293 return __osl_socket_poll (pSocket
, pTimeout
, POLLIN
);
2296 /*****************************************************************************/
2297 /* osl_isSendReady */
2298 /*****************************************************************************/
2299 sal_Bool SAL_CALL
osl_isSendReady (
2300 oslSocket pSocket
, const TimeValue
* pTimeout
)
2302 OSL_ASSERT(pSocket
);
2303 if (pSocket
== NULL
)
2309 return __osl_socket_poll (pSocket
, pTimeout
, POLLOUT
);
2312 /*****************************************************************************/
2313 /* osl_isExceptionPending */
2314 /*****************************************************************************/
2315 sal_Bool SAL_CALL
osl_isExceptionPending (
2316 oslSocket pSocket
, const TimeValue
* pTimeout
)
2318 OSL_ASSERT(pSocket
);
2319 if (pSocket
== NULL
)
2325 return __osl_socket_poll (pSocket
, pTimeout
, POLLPRI
);
2328 /*****************************************************************************/
2329 /* osl_shutdownSocket */
2330 /*****************************************************************************/
2331 sal_Bool SAL_CALL
osl_shutdownSocket(oslSocket pSocket
,
2332 oslSocketDirection Direction
)
2336 OSL_ASSERT(pSocket
);
2342 pSocket
->m_nLastError
=0;
2344 nRet
=shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
));
2347 pSocket
->m_nLastError
=errno
;
2348 OSL_TRACE("shutdown error '%s'",strerror(errno
));
2354 /*****************************************************************************/
2355 /* osl_getSocketOption */
2356 /*****************************************************************************/
2357 sal_Int32 SAL_CALL
osl_getSocketOption(oslSocket pSocket
,
2358 oslSocketOptionLevel Level
,
2359 oslSocketOption Option
,
2361 sal_uInt32 BufferLen
)
2363 socklen_t nOptLen
= (socklen_t
) BufferLen
;
2365 OSL_ASSERT(pSocket
);
2371 pSocket
->m_nLastError
=0;
2373 if(getsockopt(pSocket
->m_Socket
,
2374 OPTION_LEVEL_TO_NATIVE(Level
),
2375 OPTION_TO_NATIVE(Option
),
2379 pSocket
->m_nLastError
=errno
;
2386 /*****************************************************************************/
2387 /* osl_setSocketOption */
2388 /*****************************************************************************/
2389 sal_Bool SAL_CALL
osl_setSocketOption(oslSocket pSocket
,
2390 oslSocketOptionLevel Level
,
2391 oslSocketOption Option
,
2393 sal_uInt32 BufferLen
)
2397 OSL_ASSERT(pSocket
);
2403 pSocket
->m_nLastError
=0;
2405 nRet
= setsockopt(pSocket
->m_Socket
,
2406 OPTION_LEVEL_TO_NATIVE(Level
),
2407 OPTION_TO_NATIVE(Option
),
2413 pSocket
->m_nLastError
=errno
;
2420 /*****************************************************************************/
2421 /* osl_enableNonBlockingMode */
2422 /*****************************************************************************/
2423 sal_Bool SAL_CALL
osl_enableNonBlockingMode(oslSocket pSocket
,
2429 OSL_ASSERT(pSocket
);
2435 pSocket
->m_nLastError
=0;
2437 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2440 flags
|= O_NONBLOCK
;
2442 flags
&= ~(O_NONBLOCK
);
2444 nRet
= fcntl(pSocket
->m_Socket
, F_SETFL
, flags
);
2448 pSocket
->m_nLastError
=errno
;
2455 /*****************************************************************************/
2456 /* osl_isNonBlockingMode */
2457 /*****************************************************************************/
2458 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
2462 OSL_ASSERT(pSocket
);
2468 pSocket
->m_nLastError
=0;
2470 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2472 if (flags
== -1 || !(flags
& O_NONBLOCK
))
2478 /*****************************************************************************/
2479 /* osl_getSocketType */
2480 /*****************************************************************************/
2481 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
2484 socklen_t TypeSize
= sizeof(Type
);
2486 OSL_ASSERT(pSocket
);
2489 return osl_Socket_TypeInvalid
;
2492 pSocket
->m_nLastError
=0;
2494 if(getsockopt(pSocket
->m_Socket
,
2495 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
2496 OPTION_TO_NATIVE(osl_Socket_OptionType
),
2501 pSocket
->m_nLastError
=errno
;
2502 return osl_Socket_TypeInvalid
;
2505 return TYPE_FROM_NATIVE(Type
);
2509 /*****************************************************************************/
2510 /* osl_getLastSocketErrorDescription */
2511 /*****************************************************************************/
2512 void SAL_CALL
osl_getLastSocketErrorDescription(oslSocket Socket
, rtl_uString
**ustrError
)
2514 sal_Char pszError
[1024];
2518 osl_psz_getLastSocketErrorDescription(Socket
,pszError
,sizeof(pszError
));
2520 rtl_uString_newFromAscii(ustrError
,pszError
);
2526 void SAL_CALL
osl_psz_getLastSocketErrorDescription(oslSocket pSocket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
)
2528 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2529 pBuffer
[BufferSize
-1]= '\0';
2533 strncpy(pBuffer
, strerror(EINVAL
), BufferSize
-1);
2537 strncpy(pBuffer
, strerror(pSocket
->m_nLastError
), BufferSize
-1);
2541 /*****************************************************************************/
2542 /* osl_getLastSocketError */
2543 /*****************************************************************************/
2544 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket pSocket
)
2548 return ERROR_FROM_NATIVE(EINVAL
);
2551 return ERROR_FROM_NATIVE(pSocket
->m_nLastError
);
2554 /*****************************************************************************/
2556 /*****************************************************************************/
2557 typedef struct _TSocketSetImpl
2559 int m_MaxHandle
; /* for select(), the largest descriptor in the set */
2560 fd_set m_Set
; /* the set of descriptors */
2564 /*****************************************************************************/
2565 /* osl_createSocketSet */
2566 /*****************************************************************************/
2567 oslSocketSet SAL_CALL
osl_createSocketSet()
2569 TSocketSetImpl
* pSet
;
2571 pSet
= (TSocketSetImpl
*)malloc(sizeof(TSocketSetImpl
));
2577 pSet
->m_MaxHandle
= 0;
2578 FD_ZERO(&pSet
->m_Set
);
2581 return (oslSocketSet
)pSet
;
2584 /*****************************************************************************/
2585 /* osl_destroySocketSet */
2586 /*****************************************************************************/
2587 void SAL_CALL
osl_destroySocketSet(oslSocketSet Set
)
2593 /*****************************************************************************/
2594 /* osl_clearSocketSet */
2595 /*****************************************************************************/
2596 void SAL_CALL
osl_clearSocketSet(oslSocketSet Set
)
2598 TSocketSetImpl
* pSet
;
2605 pSet
= (TSocketSetImpl
*)Set
;
2606 pSet
->m_MaxHandle
= 0;
2608 FD_ZERO(&pSet
->m_Set
);
2611 /*****************************************************************************/
2612 /* osl_addToSocketSet */
2613 /*****************************************************************************/
2614 void SAL_CALL
osl_addToSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2616 TSocketSetImpl
* pSet
;
2619 OSL_ASSERT(pSocket
);
2621 if ( Set
== 0 || pSocket
== 0)
2626 pSet
= (TSocketSetImpl
*)Set
;
2628 /* correct max handle */
2629 if(pSocket
->m_Socket
> pSet
->m_MaxHandle
)
2630 pSet
->m_MaxHandle
= pSocket
->m_Socket
;
2631 FD_SET(pSocket
->m_Socket
, &pSet
->m_Set
);
2635 /*****************************************************************************/
2636 /* osl_removeFromSocketSet */
2637 /*****************************************************************************/
2638 void SAL_CALL
osl_removeFromSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2640 TSocketSetImpl
* pSet
;
2643 OSL_ASSERT(pSocket
);
2645 if ( Set
== 0 || pSocket
== 0)
2650 pSet
= (TSocketSetImpl
*)Set
;
2652 /* correct max handle */
2653 if(pSocket
->m_Socket
== pSet
->m_MaxHandle
)
2655 /* not optimal, since the next used descriptor might be */
2656 /* much smaller than m_Socket-1, but it will do */
2657 pSet
->m_MaxHandle
--;
2658 if(pSet
->m_MaxHandle
< 0)
2660 pSet
->m_MaxHandle
= 0; /* avoid underflow */
2664 FD_CLR(pSocket
->m_Socket
, &pSet
->m_Set
);
2667 /*****************************************************************************/
2668 /* osl_isInSocketSet */
2669 /*****************************************************************************/
2670 sal_Bool SAL_CALL
osl_isInSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2672 TSocketSetImpl
* pSet
;
2675 OSL_ASSERT(pSocket
);
2676 if ( Set
== 0 || pSocket
== 0 )
2681 pSet
= (TSocketSetImpl
*)Set
;
2683 return (FD_ISSET(pSocket
->m_Socket
, &pSet
->m_Set
) != 0);
2686 /*****************************************************************************/
2687 /* osl_demultiplexSocketEvents */
2688 /*****************************************************************************/
2689 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents(oslSocketSet IncomingSet
,
2690 oslSocketSet OutgoingSet
,
2691 oslSocketSet OutOfBandSet
,
2692 const TimeValue
* pTimeout
)
2696 TSocketSetImpl
* pInSet
;
2697 TSocketSetImpl
* pOutSet
;
2698 TSocketSetImpl
* pOOBSet
;
2702 /* non-blocking call */
2703 tv
.tv_sec
= pTimeout
->Seconds
;
2704 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
2707 /* map opaque data to impl-types */
2708 pInSet
= (TSocketSetImpl
*)IncomingSet
;
2709 pOutSet
= (TSocketSetImpl
*)OutgoingSet
;
2710 pOOBSet
= (TSocketSetImpl
*)OutOfBandSet
;
2712 /* get max handle from all sets */
2714 MaxHandle
= pInSet
->m_MaxHandle
;
2716 if (pOutSet
&& (pOutSet
->m_MaxHandle
> MaxHandle
))
2717 MaxHandle
= pOutSet
->m_MaxHandle
;
2719 if (pOOBSet
&& (pOOBSet
->m_MaxHandle
> MaxHandle
))
2720 MaxHandle
= pOOBSet
->m_MaxHandle
;
2722 return select(MaxHandle
+1,
2723 pInSet
? PTR_FD_SET(pInSet
->m_Set
) : 0,
2724 pOutSet
? PTR_FD_SET(pOutSet
->m_Set
) : 0,
2725 pOOBSet
? PTR_FD_SET(pOOBSet
->m_Set
) : 0,
2726 pTimeout
? &tv
: 0);
2729 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */