1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: socket.c,v $
10 * $Revision: 1.29.60.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
33 #include <osl/socket.h>
34 #include <osl/diagnose.h>
35 #include <osl/mutex.h>
36 #include <osl/signal.h>
38 #include <rtl/alloc.h>
41 #include <sal/types.h>
46 /* defines for poll */
51 #if defined(LINUX) || defined (IRIX) || defined(NETBSD) || defined ( FREEBSD ) || defined (MACOSX)
54 #endif /* HAVE_POLL_H */
63 #define POLLOUT 0x0002
64 #define POLLPRI 0x0004
65 #endif /* HAVE_POLL_H */
68 /* defines for shutdown */
75 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
76 I refrained from using sockaddr_in because of possible further
77 extensions of this socket-interface (IP-NG?).
78 The intention was to hide all Berkeley data-structures from
79 direct access past the osl-interface.
81 The current implementation is internet (IP) centered. All
82 the constructor-functions (osl_create...) take parameters
83 that will probably make sense only in the IP-environment
84 (e.g. because of using the dotted-address-format).
86 If the interface will be extended to host other protocol-
87 families, I expect no externally visible changes in the
88 existing functions. You'll probably need only new
89 constructor-functions who take the different address
90 formats into consideration (maybe a long dotted address
94 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
95 /* are the same! I don't like it very much but see no other easy way to */
96 /* conceal the struct sockaddr from the eyes of the user. */
99 #define OSL_INVALID_SOCKET -1
100 #define OSL_SOCKET_ERROR -1
103 /* Buffer size for gethostbyname */
104 #define MAX_HOSTBUFFER_SIZE 2048
106 /*****************************************************************************/
107 /* enum oslAddrFamily */
108 /*****************************************************************************/
111 static unsigned long FamilyMap
[]= {
112 AF_INET
, /* osl_Socket_FamilyInet */
113 AF_IPX
, /* osl_Socket_FamilyIpx */
114 0 /* osl_Socket_FamilyInvalid */
118 static oslAddrFamily
osl_AddrFamilyFromNative(sal_uInt32 nativeType
)
120 oslAddrFamily i
= (oslAddrFamily
)0;
122 while(i
!= osl_Socket_FamilyInvalid
)
124 if(FamilyMap
[i
] == nativeType
)
126 i
= (oslAddrFamily
) ( i
+ 1 );
133 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
134 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
136 /*****************************************************************************/
137 /* enum oslProtocol */
138 /*****************************************************************************/
141 static sal_uInt32 ProtocolMap
[]= {
142 0, /* osl_Socket_ProtocolIp */
143 NSPROTO_IPX
, /* osl_Socket_ProtocolIpx */
144 NSPROTO_SPX
, /* osl_Socket_ProtocolSpx */
145 NSPROTO_SPXII
, /* osl_Socket_ProtocolSpxII */
146 0 /* osl_Socket_ProtocolInvalid */
151 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
153 oslProtocol i= (oslProtocol)0;
155 while(i != osl_Socket_ProtocolInvalid)
157 if(ProtocolMap[i] == nativeType)
159 i = (oslProtocol) ( i + 1);
167 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
168 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
171 /*****************************************************************************/
172 /* enum oslSocketType */
173 /*****************************************************************************/
176 static sal_uInt32 TypeMap
[]= {
177 SOCK_STREAM
, /* osl_Socket_TypeStream */
178 SOCK_DGRAM
, /* osl_Socket_TypeDgram */
179 SOCK_RAW
, /* osl_Socket_TypeRaw */
180 SOCK_RDM
, /* osl_Socket_TypeRdm */
181 SOCK_SEQPACKET
, /* osl_Socket_TypeSeqPacket */
182 0 /* osl_Socket_TypeInvalid */
186 static oslSocketType
osl_SocketTypeFromNative(sal_uInt32 nativeType
)
188 oslSocketType i
= (oslSocketType
)0;
190 while(i
!= osl_Socket_TypeInvalid
)
192 if(TypeMap
[i
] == nativeType
)
194 i
= (oslSocketType
)(i
+ 1);
201 #define TYPE_TO_NATIVE(x) TypeMap[x]
202 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
205 /*****************************************************************************/
206 /* enum oslSocketOption */
207 /*****************************************************************************/
210 static sal_uInt32 OptionMap
[]= {
211 SO_DEBUG
, /* osl_Socket_OptionDebug */
212 SO_ACCEPTCONN
, /* osl_Socket_OptionAcceptConn */
213 SO_REUSEADDR
, /* osl_Socket_OptionReuseAddr */
214 SO_KEEPALIVE
, /* osl_Socket_OptionKeepAlive */
215 SO_DONTROUTE
, /* osl_Socket_OptionDontRoute */
216 SO_BROADCAST
, /* osl_Socket_OptionBroadcast */
217 SO_USELOOPBACK
, /* osl_Socket_OptionUseLoopback */
218 SO_LINGER
, /* osl_Socket_OptionLinger */
219 SO_OOBINLINE
, /* osl_Socket_OptionOOBinLine */
220 SO_SNDBUF
, /* osl_Socket_OptionSndBuf */
221 SO_RCVBUF
, /* osl_Socket_OptionRcvBuf */
222 SO_SNDLOWAT
, /* osl_Socket_OptionSndLowat */
223 SO_RCVLOWAT
, /* osl_Socket_OptionRcvLowat */
224 SO_SNDTIMEO
, /* osl_Socket_OptionSndTimeo */
225 SO_RCVTIMEO
, /* osl_Socket_OptionRcvTimeo */
226 SO_ERROR
, /* osl_Socket_OptionError */
227 SO_TYPE
, /* osl_Socket_OptionType */
228 TCP_NODELAY
, /* osl_Socket_OptionTcpNoDelay */
229 0 /* osl_Socket_OptionInvalid */
234 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
236 oslSocketOption i= (oslSocketOption)0;
238 while(i != osl_Socket_OptionInvalid)
240 if(OptionMap[i] == nativeType)
242 i = (oslSocketOption) ( i + 1 );
249 #define OPTION_TO_NATIVE(x) OptionMap[x]
250 #define OPTION_FROM_NATIVE(y) osl_SocketOptionFromNative(y)
253 /*****************************************************************************/
254 /* enum oslSocketOptionLevel */
255 /*****************************************************************************/
257 static sal_uInt32 OptionLevelMap
[]= {
258 SOL_SOCKET
, /* osl_Socket_LevelSocket */
259 IPPROTO_TCP
, /* osl_Socket_LevelTcp */
260 0 /* osl_Socket_LevelInvalid */
265 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
267 oslSocketOptionLevel i= (oslSocketOptionLevel)0;
269 while(i != osl_Socket_LevelInvalid)
271 if(OptionLevelMap[i] == nativeType)
273 i = (oslSocketOptionLevel) ( i + 1 );
280 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
281 #define OPTION_LEVEL_FROM_NATIVE(y) osl_SocketOptionLevelFromNative(y)
283 /*****************************************************************************/
284 /* enum oslSocketMsgFlag */
285 /*****************************************************************************/
287 static sal_uInt32 SocketMsgFlagMap
[]= {
288 0, /* osl_Socket_MsgNormal */
289 MSG_OOB
, /* osl_Socket_MsgOOB */
290 MSG_PEEK
, /* osl_Socket_MsgPeek */
291 MSG_DONTROUTE
, /* osl_Socket_MsgDontRoute */
292 MSG_MAXIOVLEN
, /* osl_Socket_MsgMaxIOVLen */
293 0 /* osl_Socket_MsgInvalid */
298 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
300 oslSocketMsgFlag i= (oslSocketMsgFlag)0;
302 while(i != osl_Socket_MsgInvalid)
304 if(SocketMsgFlagMap[i] == nativeType)
306 i = (oslSocketMsgFlag) ( i + 1 );
314 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
315 #define MSG_FLAG_FROM_NATIVE(y) osl_SocketMsgFlagFromNative(y)
318 /*****************************************************************************/
319 /* enum oslSocketDirection */
320 /*****************************************************************************/
322 static sal_uInt32 SocketDirection
[]= {
323 SD_RECEIVE
, /* osl_Socket_DirRead */
324 SD_SEND
, /* osl_Socket_DirWrite */
325 SD_BOTH
, /* osl_Socket_DirReadWrite */
326 0 /* osl_Socket_DirInvalid */
331 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
333 oslSocketDirection i= (oslSocketDirection)0;
335 while(i != osl_Socket_DirInvalid)
337 if(SocketDirection[i] == nativeType)
339 i = (oslSocketDirection) ( i + 1 );
347 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
348 #define DIRECTION_FROM_NATIVE(y) osl_SocketDirectionFromNative(y)
350 /*****************************************************************************/
351 /* enum oslSocketError */
352 /*****************************************************************************/
357 oslSocketError error
;
359 { 0, osl_Socket_E_None
}, /* no error */
360 { ENOTSOCK
, osl_Socket_E_NotSocket
}, /* Socket operation on non-socket */
361 { EDESTADDRREQ
, osl_Socket_E_DestAddrReq
}, /* Destination address required */
362 { EMSGSIZE
, osl_Socket_E_MsgSize
}, /* Message too long */
363 { EPROTOTYPE
, osl_Socket_E_Prototype
}, /* Protocol wrong type for socket */
364 { ENOPROTOOPT
, osl_Socket_E_NoProtocol
}, /* Protocol not available */
365 { EPROTONOSUPPORT
, osl_Socket_E_ProtocolNoSupport
}, /* Protocol not supported */
366 { ESOCKTNOSUPPORT
, osl_Socket_E_TypeNoSupport
}, /* Socket type not supported */
367 { EOPNOTSUPP
, osl_Socket_E_OpNotSupport
}, /* Operation not supported on socket */
368 { EPFNOSUPPORT
, osl_Socket_E_PfNoSupport
}, /* Protocol family not supported */
369 { EAFNOSUPPORT
, osl_Socket_E_AfNoSupport
}, /* Address family not supported by */
370 /* protocol family */
371 { EADDRINUSE
, osl_Socket_E_AddrInUse
}, /* Address already in use */
372 { EADDRNOTAVAIL
, osl_Socket_E_AddrNotAvail
}, /* Can't assign requested address */
373 { ENETDOWN
, osl_Socket_E_NetDown
}, /* Network is down */
374 { ENETUNREACH
, osl_Socket_E_NetUnreachable
}, /* Network is unreachable */
375 { ENETRESET
, osl_Socket_E_NetReset
}, /* Network dropped connection because */
377 { ECONNABORTED
, osl_Socket_E_ConnAborted
}, /* Software caused connection abort */
378 { ECONNRESET
, osl_Socket_E_ConnReset
}, /* Connection reset by peer */
379 { ENOBUFS
, osl_Socket_E_NoBufferSpace
}, /* No buffer space available */
380 { EISCONN
, osl_Socket_E_IsConnected
}, /* Socket is already connected */
381 { ENOTCONN
, osl_Socket_E_NotConnected
}, /* Socket is not connected */
382 { ESHUTDOWN
, osl_Socket_E_Shutdown
}, /* Can't send after socket shutdown */
383 { ETOOMANYREFS
, osl_Socket_E_TooManyRefs
}, /* Too many references: can't splice */
384 { ETIMEDOUT
, osl_Socket_E_TimedOut
}, /* Connection timed out */
385 { ECONNREFUSED
, osl_Socket_E_ConnRefused
}, /* Connection refused */
386 { EHOSTDOWN
, osl_Socket_E_HostDown
}, /* Host is down */
387 { EHOSTUNREACH
, osl_Socket_E_HostUnreachable
}, /* No route to host */
388 { EWOULDBLOCK
, osl_Socket_E_WouldBlock
}, /* call would block on non-blocking socket */
389 { EALREADY
, osl_Socket_E_Already
}, /* operation already in progress */
390 { EINPROGRESS
, osl_Socket_E_InProgress
}, /* operation now in progress */
391 { EAGAIN
, osl_Socket_E_WouldBlock
}, /* same as EWOULDBLOCK */
392 { -1, osl_Socket_E_InvalidError
}
397 static int osl_NativeFromSocketError(oslSocketError errorCode)
401 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
402 (SocketError[i].error != errorCode)) i++;
404 return SocketError[i].errcode;
409 static oslSocketError
osl_SocketErrorFromNative(int nativeType
)
413 while ((SocketError
[i
].error
!= osl_Socket_E_InvalidError
) &&
414 (SocketError
[i
].errcode
!= nativeType
)) i
++;
416 return SocketError
[i
].error
;
420 #define ERROR_TO_NATIVE(x) osl_NativeFromSocketError(x)
421 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
423 /*****************************************************************************/
424 /* local function prototypes */
425 /*****************************************************************************/
427 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
428 const sal_Char
* pszDottedAddr
, sal_Int32 Port
);
430 oslSocketAddr SAL_CALL
osl_psz_createIpxSocketAddr (
431 const sal_Char NetNumber
[4],
432 const sal_Char NodeNumber
[6],
433 sal_uInt32 SocketNumber
);
435 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
436 const sal_Char
*pszHostname
, const oslSocketAddr Addr
);
438 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (
439 const sal_Char
*pszHostname
);
441 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (
442 const oslHostAddr Addr
);
444 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
445 sal_Char
*pBuffer
, sal_uInt32 nBufLen
);
447 oslSocketAddr SAL_CALL
osl_psz_resolveHostname (
448 const sal_Char
* pszHostname
);
450 sal_Int32 SAL_CALL
osl_psz_getServicePort (
451 const sal_Char
* pszServicename
, const sal_Char
* pszProtocol
);
453 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr (
454 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
456 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr (
457 oslSocketAddr Addr
, sal_Char
*pBuffer
, sal_uInt32 BufferSize
);
459 void SAL_CALL
osl_psz_getLastSocketErrorDescription (
460 oslSocket Socket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
);
462 /*****************************************************************************/
463 /* osl_create/destroy-SocketImpl */
464 /*****************************************************************************/
466 #if OSL_DEBUG_LEVEL > 1
467 static sal_uInt32 g_nSocketImpl
= 0;
468 static sal_uInt32 g_nSocketAddr
= 0;
470 /* sorry, must be implemented otherwise */
477 OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl
);
479 OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr
);
482 LeakWarning socketWarning
;
485 #endif /* OSL_DEBUG_LEVEL */
488 oslSocket
__osl_createSocketImpl(int Socket
)
492 pSocket
= (oslSocket
)calloc(1, sizeof(struct oslSocketImpl
));
494 pSocket
->m_Socket
= Socket
;
495 pSocket
->m_nLastError
= 0;
496 pSocket
->m_CloseCallback
= 0;
497 pSocket
->m_CallbackArg
= 0;
498 pSocket
->m_nRefCount
= 1;
501 pSocket
->m_bIsAccepting
= sal_False
;
504 #if OSL_DEBUG_LEVEL > 1
510 void __osl_destroySocketImpl(oslSocket Socket
)
513 free((struct oslSocketImpl
*) Socket
);
514 #if OSL_DEBUG_LEVEL > 1
519 static oslSocketAddr
__osl_createSocketAddr( )
521 oslSocketAddr pAddr
= (oslSocketAddr
) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl
));
522 #if OSL_DEBUG_LEVEL > 1
528 static oslSocketAddr
__osl_createSocketAddrWithFamily(
529 oslAddrFamily family
, sal_Int32 port
, sal_uInt32 nAddr
)
533 OSL_ASSERT( family
== osl_Socket_FamilyInet
);
535 pAddr
= __osl_createSocketAddr();
538 case osl_Socket_FamilyInet
:
540 struct sockaddr_in
* pInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
542 pInetAddr
->sin_family
= FAMILY_TO_NATIVE(osl_Socket_FamilyInet
);
543 pInetAddr
->sin_addr
.s_addr
= nAddr
;
544 pInetAddr
->sin_port
= (sal_uInt16
)(port
&0xffff);
548 pAddr
->m_sockaddr
.sa_family
= FAMILY_TO_NATIVE(family
);
553 static oslSocketAddr
__osl_createSocketAddrFromSystem( struct sockaddr
*pSystemSockAddr
)
555 oslSocketAddr pAddr
= __osl_createSocketAddr();
556 memcpy( &(pAddr
->m_sockaddr
), pSystemSockAddr
, sizeof( struct sockaddr
) );
560 static void __osl_destroySocketAddr( oslSocketAddr addr
)
562 #if OSL_DEBUG_LEVEL > 1
565 rtl_freeMemory( addr
);
568 /*****************************************************************************/
569 /* osl_createEmptySocketAddr */
570 /*****************************************************************************/
571 oslSocketAddr SAL_CALL
osl_createEmptySocketAddr(oslAddrFamily Family
)
573 oslSocketAddr pAddr
= 0;
575 /* is it an internet-Addr? */
576 if (Family
== osl_Socket_FamilyInet
)
578 pAddr
= __osl_createSocketAddrWithFamily(Family
, 0 , htonl(INADDR_ANY
) );
582 pAddr
= __osl_createSocketAddrWithFamily( Family
, 0 , 0 );
588 /*****************************************************************************/
589 /* osl_copySocketAddr */
590 /*****************************************************************************/
591 oslSocketAddr SAL_CALL
osl_copySocketAddr(oslSocketAddr Addr
)
593 oslSocketAddr pCopy
= 0;
596 pCopy
= __osl_createSocketAddr();
599 memcpy(&(pCopy
->m_sockaddr
),&(Addr
->m_sockaddr
), sizeof(struct sockaddr
));
604 /*****************************************************************************/
605 /* osl_isEqualSocketAddr */
606 /*****************************************************************************/
607 sal_Bool SAL_CALL
osl_isEqualSocketAddr (
611 struct sockaddr
* pAddr1
= &(Addr1
->m_sockaddr
);
612 struct sockaddr
* pAddr2
= &(Addr2
->m_sockaddr
);
617 if (pAddr1
->sa_family
== pAddr2
->sa_family
)
619 switch (pAddr1
->sa_family
)
623 struct sockaddr_in
* pInetAddr1
= (struct sockaddr_in
*)pAddr1
;
624 struct sockaddr_in
* pInetAddr2
= (struct sockaddr_in
*)pAddr2
;
626 if ((pInetAddr1
->sin_family
== pInetAddr2
->sin_family
) &&
627 (pInetAddr1
->sin_addr
.s_addr
== pInetAddr2
->sin_addr
.s_addr
) &&
628 (pInetAddr1
->sin_port
== pInetAddr2
->sin_port
))
634 return (memcmp(pAddr1
, Addr2
, sizeof(struct sockaddr
)) == 0);
642 /*****************************************************************************/
643 /* osl_createInetBroadcastAddr */
644 /*****************************************************************************/
645 oslSocketAddr SAL_CALL
osl_createInetBroadcastAddr (
646 rtl_uString
*strDottedAddr
,
649 sal_uInt32 nAddr
= OSL_INADDR_NONE
;
652 if (strDottedAddr
&& strDottedAddr
->length
)
654 /* Dotted host address for limited broadcast */
655 rtl_String
*pDottedAddr
= NULL
;
658 &pDottedAddr
, strDottedAddr
->buffer
, strDottedAddr
->length
,
659 RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
661 nAddr
= inet_addr (pDottedAddr
->buffer
);
662 rtl_string_release (pDottedAddr
);
665 if (nAddr
!= OSL_INADDR_NONE
)
667 /* Limited broadcast */
668 nAddr
= ntohl(nAddr
);
669 if (IN_CLASSA(nAddr
))
671 nAddr
&= IN_CLASSA_NET
;
672 nAddr
|= IN_CLASSA_HOST
;
674 else if (IN_CLASSB(nAddr
))
676 nAddr
&= IN_CLASSB_NET
;
677 nAddr
|= IN_CLASSB_HOST
;
679 else if (IN_CLASSC(nAddr
))
681 nAddr
&= IN_CLASSC_NET
;
682 nAddr
|= IN_CLASSC_HOST
;
686 /* No broadcast in class D */
687 return ((oslSocketAddr
)NULL
);
689 nAddr
= htonl(nAddr
);
692 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
), nAddr
);
696 /*****************************************************************************/
697 /* osl_createInetSocketAddr */
698 /*****************************************************************************/
699 oslSocketAddr SAL_CALL
osl_createInetSocketAddr (
700 rtl_uString
*ustrDottedAddr
,
703 rtl_String
* strDottedAddr
=0;
705 sal_Char
* pszDottedAddr
=0;
707 if ( ustrDottedAddr
!= 0 )
709 rtl_uString2String( &strDottedAddr
,
710 rtl_uString_getStr(ustrDottedAddr
),
711 rtl_uString_getLength(ustrDottedAddr
),
712 RTL_TEXTENCODING_UTF8
,
713 OUSTRING_TO_OSTRING_CVTFLAGS
);
714 pszDottedAddr
= rtl_string_getStr(strDottedAddr
);
718 Addr
= osl_psz_createInetSocketAddr(pszDottedAddr
, Port
);
720 if ( strDottedAddr
!= 0 )
722 rtl_string_release(strDottedAddr
);
728 oslSocketAddr SAL_CALL
osl_psz_createInetSocketAddr (
729 const sal_Char
* pszDottedAddr
,
732 oslSocketAddr pAddr
= 0;
733 sal_Int32 Addr
= inet_addr(pszDottedAddr
);
736 /* valid dotted addr */
737 pAddr
= __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet
, htons(Port
) , Addr
);
742 /*****************************************************************************/
743 /* osl_setAddrOfSocketAddr */
744 /*****************************************************************************/
745 oslSocketResult SAL_CALL
osl_setAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
*pByteSeq
)
747 oslSocketResult res
= osl_Socket_Error
;
750 OSL_ASSERT( pByteSeq
);
752 if( pAddr
&& pByteSeq
)
754 struct sockaddr_in
* pSystemInetAddr
;
756 OSL_ASSERT( pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE( osl_Socket_FamilyInet
) );
757 OSL_ASSERT( pByteSeq
->nElements
== 4 );
759 pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
760 memcpy( &(pSystemInetAddr
->sin_addr
) , pByteSeq
->elements
, 4 );
766 /*****************************************************************************/
767 /* osl_getAddrOfSocketAddr */
768 /*****************************************************************************/
769 oslSocketResult SAL_CALL
osl_getAddrOfSocketAddr( oslSocketAddr pAddr
, sal_Sequence
**ppByteSeq
)
771 oslSocketResult res
= osl_Socket_Error
;
774 OSL_ASSERT( ppByteSeq
);
776 if( pAddr
&& ppByteSeq
)
778 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
779 rtl_byte_sequence_constructFromArray( ppByteSeq
, (sal_Int8
*) &(pSystemInetAddr
->sin_addr
),4);
786 /*****************************************************************************/
787 /* _osl_getFullQualifiedDomainName */
788 /*****************************************************************************/
790 /** try to figure out a full-qualified hostname, by adding the current domain
791 as given by the domainname program to the given hostname.
792 This function MUST NOT call gethostbyname since pHostName allready points
793 to data returned by gethostname and would be garbled: use gethostname_r
797 /* wrap around different interfaces to reentrant gethostbyname */
798 static struct hostent
* _osl_gethostbyname_r (
799 const char *name
, struct hostent
*result
,
800 char *buffer
, int buflen
, int *h_errnop
)
802 #if defined(LINUX) || (defined(FREEBSD) && (__FreeBSD_version >= 601103))
803 struct hostent
*__result
; /* will be the same as result */
805 __error
= gethostbyname_r (name
, result
, buffer
, buflen
,
806 &__result
, h_errnop
);
807 return __error
? NULL
: __result
;
809 return gethostbyname_r( name
, result
, buffer
, buflen
, h_errnop
);
813 static sal_Bool
_osl_getDomainName (sal_Char
*buffer
, sal_Int32 bufsiz
)
837 execv ("/bin/domainname", argv
);
838 // arriving here means exec failed
843 sal_Int32 k
= 0, n
= bufsiz
;
846 if ((k
= read (p
[0], buffer
, n
- 1)) > 0)
849 if (buffer
[k
- 1] == '\n')
854 waitpid (pid
, &nStatus
, 0);
865 static sal_Char
* _osl_getFullQualifiedDomainName (const sal_Char
*pHostName
)
867 # define DOMAINNAME_LENGTH 512
868 sal_uInt32 nLengthOfHostName
;
869 static sal_uInt32 nLengthOfDomainName
= 0;
870 static sal_Char
*pDomainName
= NULL
;
872 sal_Char
*pFullQualifiedName
;
874 FILE *pPipeToDomainnameExe
;
875 #endif /* OBSOLETE */
877 /* get a '\0' terminated domainname */
879 /* read default domainname default from environment */
880 if (nLengthOfDomainName
== 0)
882 sal_Char
*pEnvDomain
;
884 pEnvDomain
= getenv ("STAR_OVERRIDE_DOMAINNAME");
887 pDomainName
= strdup (pEnvDomain
);
888 nLengthOfDomainName
= strlen (pDomainName
);
893 if (nLengthOfDomainName
== 0)
895 sal_Char pDomainNameBuffer
[ DOMAINNAME_LENGTH
];
897 pDomainNameBuffer
[0] = '\0';
899 if (_osl_getDomainName (pDomainNameBuffer
, DOMAINNAME_LENGTH
))
901 pDomainName
= strdup (pDomainNameBuffer
);
902 nLengthOfDomainName
= strlen (pDomainName
);
910 /* call 'domainname > /usr/tmp/some-tmp-file', since
911 popen read pclose do block or core-dump,
912 (even the pipe-stuff that comes with pthreads) */
913 if (nLengthOfDomainName
== 0)
915 sal_Char tmp_name
[ L_tmpnam
];
917 sal_Char domain_call
[ L_tmpnam
+ 16 ] = "domainname > ";
922 strcat ( domain_call
, tmp_name
);
923 if ( (system ( domain_call
) == 0)
924 && ((tmp_file
= fopen( tmp_name
, "r" )) != NULL
) )
926 sal_Char pDomainNameBuffer
[ DOMAINNAME_LENGTH
];
928 pDomainNameBuffer
[0] = '\0';
930 if ( fgets ( pDomainNameBuffer
, DOMAINNAME_LENGTH
, tmp_file
) )
932 pDomainName
= strdup( pDomainNameBuffer
);
933 nLengthOfDomainName
= strlen( pDomainName
);
934 if ( ( nLengthOfDomainName
> 0 )
935 && ( pDomainName
[ nLengthOfDomainName
- 1] == '\n' ) )
936 pDomainName
[ --nLengthOfDomainName
] = '\0';
945 /* read the domainname from pipe to the program domainname */
946 if ( (nLengthOfDomainName
== 0)
947 && (pPipeToDomainnameExe
= popen( "domainname", "r")) )
950 sal_Char pDomainNameBuffer
[ DOMAINNAME_LENGTH
];
951 sal_Char
*pDomainNamePointer
;
953 pDomainNameBuffer
[0] = '\0';
955 pDomainNamePointer
= pDomainNameBuffer
;
956 while ( ((c
= getc( pPipeToDomainnameExe
)) != EOF
)
957 && (nLengthOfDomainName
< (DOMAINNAME_LENGTH
- 1)) )
961 nLengthOfDomainName
++ ;
962 *pDomainNamePointer
++ = (sal_Char
)c
;
965 *pDomainNamePointer
= '\0';
966 pDomainName
= strdup( pDomainNameBuffer
);
968 pclose( pPipeToDomainnameExe
);
972 #endif /* OBSOLETE */
974 /* compose hostname and domainname */
975 nLengthOfHostName
= strlen( pHostName
);
976 pFullQualifiedName
= (sal_Char
*) malloc( (nLengthOfHostName
+ 1
977 + nLengthOfDomainName
+ 1) * sizeof(sal_Char
) );
978 memcpy( pFullQualifiedName
, pHostName
,
979 (nLengthOfHostName
+ 1) * sizeof(sal_Char
) );
981 if ( nLengthOfDomainName
> 0 )
983 /* fqdn = hostname + '.' + domainname + '\0' */
984 pFullQualifiedName
[ nLengthOfHostName
] = '.';
985 memcpy( pFullQualifiedName
+ nLengthOfHostName
+ 1, pDomainName
,
986 nLengthOfDomainName
+ 1 );
989 /* check whether full-qualified name and hostname point to the same host
990 * should almost always be true */
991 if ( nLengthOfDomainName
> 0 )
993 struct hostent
*pQualifiedHostByName
;
994 struct hostent
*pHostByName
;
995 sal_Bool bHostsAreEqual
;
997 /* buffer for calls to reentrant version of gethostbyname */
998 struct hostent aHostByName
, aQualifiedHostByName
;
999 sal_Char pHostBuffer
[ MAX_HOSTBUFFER_SIZE
];
1000 sal_Char pQualifiedHostBuffer
[ MAX_HOSTBUFFER_SIZE
];
1003 pHostBuffer
[0] = '\0';
1004 pQualifiedHostBuffer
[0] = '\0';
1006 /* get list of addresses */
1007 pQualifiedHostByName
= _osl_gethostbyname_r (
1009 &aQualifiedHostByName
, pQualifiedHostBuffer
,
1010 sizeof(pQualifiedHostBuffer
), &nErrorNo
);
1011 pHostByName
= _osl_gethostbyname_r (
1013 &aHostByName
, pHostBuffer
,
1014 sizeof(pHostBuffer
), &nErrorNo
);
1016 /* compare addresses */
1017 bHostsAreEqual
= sal_False
;
1018 if ( pQualifiedHostByName
&& pHostByName
)
1023 /* lists are expected to be (very) short */
1024 for ( p
= pQualifiedHostByName
->h_addr_list
; *p
!= NULL
; p
++ )
1026 for ( q
= pHostByName
->h_addr_list
; *q
!= NULL
; q
++ )
1028 /* in.s_addr may be in_addr_t or uint32_t or heaven knows */
1029 if ( memcmp( *p
, *q
, sizeof(in
.s_addr
) ) == 0 )
1031 bHostsAreEqual
= sal_True
;
1035 if ( bHostsAreEqual
)
1040 /* very strange case, but have to believe it: reduce the
1041 * full qualified name to the unqualified host name */
1042 if ( !bHostsAreEqual
)
1044 OSL_TRACE("_osl_getFullQualifiedDomainName: "
1045 "suspect FQDN: %s\n", pFullQualifiedName
);
1047 pFullQualifiedName
[ nLengthOfHostName
] = '\0';
1048 pFullQualifiedName
= (sal_Char
*)realloc ( pFullQualifiedName
,
1049 (nLengthOfHostName
+ 1) * sizeof( sal_Char
));
1053 /* always return a hostname looked up as carefully as possible
1054 * this string must be freed by the caller */
1055 return pFullQualifiedName
;
1058 /*****************************************************************************/
1059 /* _osl_isFullQualifiedDomainName */
1060 /*****************************************************************************/
1061 static sal_Bool
_osl_isFullQualifiedDomainName (const sal_Char
*pHostName
)
1063 /* a FQDN (aka 'hostname.domain.top_level_domain' )
1064 * is a name which contains a dot '.' in it ( would
1065 * match as well for 'hostname.' but is good enough
1067 return (sal_Bool
)( strchr( pHostName
, (int)'.' ) != NULL
);
1070 /*****************************************************************************/
1072 /*****************************************************************************/
1073 struct oslHostAddrImpl
1075 sal_Char
*pHostName
;
1076 oslSocketAddr pSockAddr
;
1079 static oslHostAddr
_osl_hostentToHostAddr (const struct hostent
*he
)
1081 oslHostAddr pAddr
= NULL
;
1082 oslSocketAddr pSockAddr
= 0;
1086 if ((he
== NULL
) || (he
->h_name
== NULL
) || (he
->h_addr_list
[0] == NULL
))
1087 return ((oslHostAddr
)NULL
);
1089 if (_osl_isFullQualifiedDomainName(he
->h_name
))
1091 cn
= (sal_Char
*)malloc(strlen (he
->h_name
) + 1);
1094 return ((oslHostAddr
)NULL
);
1096 strcpy(cn
, he
->h_name
);
1100 cn
=_osl_getFullQualifiedDomainName (he
->h_name
);
1103 return ((oslHostAddr
)NULL
);
1106 pSockAddr
= __osl_createSocketAddr();
1107 OSL_ASSERT(pSockAddr
);
1108 if (pSockAddr
== NULL
)
1111 return ((oslHostAddr
)NULL
);
1114 pSockAddr
->m_sockaddr
.sa_family
= he
->h_addrtype
;
1115 if (pSockAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1117 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&(pSockAddr
->m_sockaddr
);
1119 &(sin
->sin_addr
.s_addr
),
1125 /* unknown address family */
1126 /* future extensions for new families might be implemented here */
1128 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.\n");
1129 OSL_ASSERT(sal_False
);
1131 __osl_destroySocketAddr( pSockAddr
);
1133 return ((oslHostAddr
)NULL
);
1136 pAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
1140 __osl_destroySocketAddr( pSockAddr
);
1142 return ((oslHostAddr
)NULL
);
1145 pAddr
->pHostName
= cn
;
1146 pAddr
->pSockAddr
= pSockAddr
;
1151 /*****************************************************************************/
1152 /* osl_createHostAddr */
1153 /*****************************************************************************/
1154 oslHostAddr SAL_CALL
osl_createHostAddr (
1155 rtl_uString
*ustrHostname
,
1156 const oslSocketAddr Addr
)
1158 oslHostAddr HostAddr
;
1159 rtl_String
* strHostname
=0;
1160 sal_Char
* pszHostName
=0;
1162 if ( ustrHostname
!= 0 )
1164 rtl_uString2String( &strHostname
,
1165 rtl_uString_getStr(ustrHostname
),
1166 rtl_uString_getLength(ustrHostname
),
1167 RTL_TEXTENCODING_UTF8
,
1168 OUSTRING_TO_OSTRING_CVTFLAGS
);
1169 pszHostName
= rtl_string_getStr(strHostname
);
1172 HostAddr
= osl_psz_createHostAddr(pszHostName
,Addr
);
1174 if ( strHostname
!= 0 )
1176 rtl_string_release(strHostname
);
1183 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
1184 const sal_Char
*pszHostname
,
1185 const oslSocketAddr pAddr
)
1187 oslHostAddr pHostAddr
;
1190 OSL_ASSERT(pszHostname
&& pAddr
);
1191 if ((pszHostname
== NULL
) || (pAddr
== NULL
))
1192 return ((oslHostAddr
)NULL
);
1194 cn
= (sal_Char
*)malloc(strlen (pszHostname
) + 1);
1197 return ((oslHostAddr
)NULL
);
1199 strcpy (cn
, pszHostname
);
1201 pHostAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
1202 OSL_ASSERT(pHostAddr
);
1206 return ((oslHostAddr
)NULL
);
1209 pHostAddr
->pHostName
= cn
;
1210 pHostAddr
->pSockAddr
= osl_copySocketAddr( pAddr
);
1215 /*****************************************************************************/
1216 /* osl_createHostAddrByName */
1217 /*****************************************************************************/
1218 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*ustrHostname
)
1220 oslHostAddr HostAddr
;
1221 rtl_String
* strHostname
=0;
1222 sal_Char
* pszHostName
=0;
1224 if ( ustrHostname
!= 0 )
1226 rtl_uString2String( &strHostname
,
1227 rtl_uString_getStr(ustrHostname
),
1228 rtl_uString_getLength(ustrHostname
),
1229 RTL_TEXTENCODING_UTF8
,
1230 OUSTRING_TO_OSTRING_CVTFLAGS
);
1231 pszHostName
=rtl_string_getStr(strHostname
);
1234 HostAddr
= osl_psz_createHostAddrByName(pszHostName
);
1236 if ( strHostname
!= 0 )
1238 rtl_string_release(strHostname
);
1244 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (const sal_Char
*pszHostname
)
1249 static oslMutex mutex
= NULL
;
1252 mutex
= osl_createMutex();
1254 osl_acquireMutex(mutex
);
1256 he
= gethostbyname((sal_Char
*)pszHostname
);
1257 addr
= _osl_hostentToHostAddr (he
);
1259 osl_releaseMutex(mutex
);
1264 /*****************************************************************************/
1265 /* osl_createHostAddrByAddr */
1266 /*****************************************************************************/
1267 oslHostAddr SAL_CALL
osl_createHostAddrByAddr (const oslSocketAddr pAddr
)
1272 return ((oslHostAddr
)NULL
);
1274 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1276 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1279 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
1280 return ((oslHostAddr
)NULL
);
1282 he
= gethostbyaddr((sal_Char
*)&(sin
->sin_addr
),
1283 sizeof (sin
->sin_addr
),
1285 return _osl_hostentToHostAddr (he
);
1288 return ((oslHostAddr
)NULL
);
1291 /*****************************************************************************/
1292 /* osl_copyHostAddr */
1293 /*****************************************************************************/
1294 oslHostAddr SAL_CALL
osl_copyHostAddr (const oslHostAddr pAddr
)
1299 return osl_psz_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
1301 return ((oslHostAddr
)NULL
);
1304 /*****************************************************************************/
1305 /* osl_getHostnameOfHostAddr */
1306 /*****************************************************************************/
1307 void SAL_CALL
osl_getHostnameOfHostAddr (
1308 const oslHostAddr Addr
,
1309 rtl_uString
**ustrHostname
)
1311 const sal_Char
* pHostname
=0;
1313 pHostname
= osl_psz_getHostnameOfHostAddr(Addr
);
1315 rtl_uString_newFromAscii (ustrHostname
, pHostname
);
1320 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr
)
1325 return pAddr
->pHostName
;
1330 /*****************************************************************************/
1331 /* osl_getSocketAddrOfHostAddr */
1332 /*****************************************************************************/
1333 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr
)
1338 return ((oslSocketAddr
)(pAddr
->pSockAddr
));
1343 /*****************************************************************************/
1344 /* osl_destroyHostAddr */
1345 /*****************************************************************************/
1346 void SAL_CALL
osl_destroyHostAddr (oslHostAddr pAddr
)
1350 if (pAddr
->pHostName
)
1351 free (pAddr
->pHostName
);
1352 if (pAddr
->pSockAddr
)
1353 osl_destroySocketAddr (pAddr
->pSockAddr
);
1358 /*****************************************************************************/
1359 /* osl_getLocalHostname */
1360 /*****************************************************************************/
1361 oslSocketResult SAL_CALL
osl_getLocalHostname(rtl_uString
**ustrLocalHostname
)
1363 oslSocketResult Result
;
1364 sal_Char pszHostname
[1024];
1366 pszHostname
[0] = '\0';
1368 Result
= osl_psz_getLocalHostname(pszHostname
,sizeof(pszHostname
));
1370 rtl_uString_newFromAscii(ustrLocalHostname
,pszHostname
);
1375 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
1376 sal_Char
*pBuffer
, sal_uInt32 nBufLen
)
1378 static sal_Char LocalHostname
[256] = "";
1380 if (strlen(LocalHostname
) == 0)
1382 const sal_Char
*pStr
;
1387 if (uname(&uts
) < 0)
1388 return osl_Socket_Error
;
1390 if ((strlen(uts
.nodename
) + 1) > nBufLen
)
1391 return osl_Socket_Error
;
1393 strncpy(LocalHostname
, uts
.nodename
, sizeof( LocalHostname
));
1394 #else /* BSD compatible */
1396 if (gethostname(LocalHostname
, sizeof(LocalHostname
)-1) != 0)
1397 return osl_Socket_Error
;
1398 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
1401 /* check if we have an FQDN */
1402 if (strchr(LocalHostname
, '.') == NULL
)
1406 /* no, determine it via dns */
1407 Addr
= osl_psz_createHostAddrByName(LocalHostname
);
1409 if ((pStr
= osl_psz_getHostnameOfHostAddr(Addr
)) != NULL
)
1411 #if 0 /* OBSOLETE */
1413 #endif /* OBSOLETE */
1414 strcpy(LocalHostname
, pStr
);
1416 #if 0 /* OBSOLETE */
1417 /* already done by _osl_getFullQualifiedDomainName() with
1418 much better heuristics, so this may be contraproductive */
1420 /* no FQDN, last try append domain name */
1421 if ((pChr
= strchr(LocalHostname
, '.')) == NULL
)
1425 pChr
= &LocalHostname
[strlen(LocalHostname
)];
1427 if ( (fp
= popen("domainname", "r")) != 0 )
1433 while ((c
= getc(fp
)) != EOF
)
1436 *pChr
++ = (sal_Char
)c
;
1444 LocalHostname
[0] = '\0';
1446 #endif /* OBSOLETE */
1449 osl_destroyHostAddr(Addr
);
1453 if (strlen(LocalHostname
) > 0)
1455 strncpy(pBuffer
, LocalHostname
, nBufLen
);
1456 pBuffer
[nBufLen
- 1] = '\0';
1458 return osl_Socket_Ok
;
1461 return osl_Socket_Error
;
1464 /*****************************************************************************/
1465 /* osl_resolveHostname */
1466 /*****************************************************************************/
1467 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
*ustrHostname
)
1470 rtl_String
* strHostname
=0;
1471 sal_Char
* pszHostName
=0;
1473 if ( ustrHostname
!= 0 )
1475 rtl_uString2String( &strHostname
,
1476 rtl_uString_getStr(ustrHostname
),
1477 rtl_uString_getLength(ustrHostname
),
1478 RTL_TEXTENCODING_UTF8
,
1479 OUSTRING_TO_OSTRING_CVTFLAGS
);
1480 pszHostName
= rtl_string_getStr(strHostname
);
1484 Addr
= osl_psz_resolveHostname(pszHostName
);
1486 if ( strHostname
!= 0 )
1488 rtl_string_release(strHostname
);
1496 oslSocketAddr SAL_CALL
osl_psz_resolveHostname(const sal_Char
* pszHostname
)
1498 struct oslHostAddrImpl
*pAddr
= (oslHostAddr
)osl_psz_createHostAddrByName(pszHostname
);
1502 oslSocketAddr SockAddr
= osl_copySocketAddr(pAddr
->pSockAddr
);
1504 osl_destroyHostAddr(pAddr
);
1509 return ((oslSocketAddr
)NULL
);
1512 /*****************************************************************************/
1513 /* osl_getServicePort */
1514 /*****************************************************************************/
1515 sal_Int32 SAL_CALL
osl_getServicePort(rtl_uString
*ustrServicename
, rtl_uString
*ustrProtocol
)
1518 rtl_String
* strServicename
=0;
1519 rtl_String
* strProtocol
=0;
1520 sal_Char
* pszServiceName
=0;
1521 sal_Char
* pszProtocol
=0;
1523 if ( ustrServicename
!= 0 )
1525 rtl_uString2String( &strServicename
,
1526 rtl_uString_getStr(ustrServicename
),
1527 rtl_uString_getLength(ustrServicename
),
1528 RTL_TEXTENCODING_UTF8
,
1529 OUSTRING_TO_OSTRING_CVTFLAGS
);
1530 pszServiceName
= rtl_string_getStr(strServicename
);
1533 if ( ustrProtocol
!= 0 )
1535 rtl_uString2String( &strProtocol
,
1536 rtl_uString_getStr(ustrProtocol
),
1537 rtl_uString_getLength(ustrProtocol
),
1538 RTL_TEXTENCODING_UTF8
,
1539 OUSTRING_TO_OSTRING_CVTFLAGS
);
1540 pszProtocol
= rtl_string_getStr(strProtocol
);
1543 nPort
= osl_psz_getServicePort(pszServiceName
,pszProtocol
);
1545 if ( strServicename
!= 0 )
1547 rtl_string_release(strServicename
);
1550 if ( strProtocol
!= 0 )
1552 rtl_string_release(strProtocol
);
1560 sal_Int32 SAL_CALL
osl_psz_getServicePort(const sal_Char
* pszServicename
,
1561 const sal_Char
* pszProtocol
)
1565 ps
= getservbyname(pszServicename
, pszProtocol
);
1568 return ntohs(ps
->s_port
);
1570 return OSL_INVALID_PORT
;
1573 /*****************************************************************************/
1574 /* osl_destroySocketAddr */
1575 /*****************************************************************************/
1576 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
1578 __osl_destroySocketAddr( pAddr
);
1581 /*****************************************************************************/
1582 /* osl_getFamilyOfSocketAddr */
1583 /*****************************************************************************/
1584 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
1589 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1591 return osl_Socket_FamilyInvalid
;
1594 /*****************************************************************************/
1595 /* osl_getInetPortOfSocketAddr */
1596 /*****************************************************************************/
1597 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
1602 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1604 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1605 return ntohs(pSystemInetAddr
->sin_port
);
1607 return OSL_INVALID_PORT
;
1610 /*****************************************************************************/
1611 /* osl_setInetPortOfSocketAddr */
1612 /*****************************************************************************/
1613 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr
, sal_Int32 Port
)
1618 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1619 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1621 pSystemInetAddr
->sin_port
= htons((short)Port
);
1626 /* this is not a inet-addr => can't set port */
1630 /*****************************************************************************/
1631 /* osl_getHostnameOfSocketAddr */
1632 /*****************************************************************************/
1633 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrHostname
)
1635 oslSocketResult Result
;
1636 sal_Char pszHostname
[1024];
1638 pszHostname
[0] = '\0';
1640 Result
= osl_psz_getHostnameOfSocketAddr(Addr
,pszHostname
,sizeof(pszHostname
));
1642 rtl_uString_newFromAscii(ustrHostname
,pszHostname
);
1648 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr
,
1649 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1651 oslHostAddr pHostAddr
= (oslHostAddr
)osl_createHostAddrByAddr(pAddr
);
1655 strncpy(pBuffer
, pHostAddr
->pHostName
, BufferSize
);
1657 pBuffer
[BufferSize
- 1] = '\0';
1659 osl_destroyHostAddr(pHostAddr
);
1661 return osl_Socket_Ok
;
1664 return osl_Socket_Error
;
1667 /*****************************************************************************/
1668 /* osl_getDottedInetAddrOfSocketAddr */
1669 /*****************************************************************************/
1670 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrDottedInetAddr
)
1672 oslSocketResult Result
;
1673 sal_Char pszDottedInetAddr
[1024];
1675 pszDottedInetAddr
[0] = '\0';
1677 Result
= osl_psz_getDottedInetAddrOfSocketAddr(Addr
,pszDottedInetAddr
,sizeof(pszDottedInetAddr
));
1679 rtl_uString_newFromAscii(ustrDottedInetAddr
,pszDottedInetAddr
);
1685 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr
,
1686 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1692 struct sockaddr_in
* pSystemInetAddr
= ( struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
1694 if (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1696 strncpy(pBuffer
, inet_ntoa(pSystemInetAddr
->sin_addr
), BufferSize
);
1697 pBuffer
[BufferSize
- 1] = '\0';
1699 return osl_Socket_Ok
;
1703 return osl_Socket_Error
;
1706 #if 0 /* OBSOLETE */
1707 /*****************************************************************************/
1708 /* osl_getIpxNetNumber */
1709 /*****************************************************************************/
1710 oslSocketResult SAL_CALL
osl_getIpxNetNumber(oslSocketAddr Addr
,
1711 oslSocketIpxNetNumber NetNumber
)
1714 struct sockaddr_ipx
* pAddr
;
1716 pAddr
= (struct sockaddr_ipx
*)Addr
;
1720 if (pAddr
&& (pAddr
->sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyIpx
)))
1722 memcpy(NetNumber
, pAddr
->sa_netnum
, sizeof(NetNumber
));
1724 return osl_Socket_Ok
;
1727 return osl_Socket_Error
;
1731 /*****************************************************************************/
1732 /* osl_getIpxNodeNumber */
1733 /*****************************************************************************/
1734 oslSocketResult SAL_CALL
osl_getIpxNodeNumber(oslSocketAddr Addr
,
1735 oslSocketIpxNodeNumber NodeNumber
)
1738 struct sockaddr_ipx
* pAddr
;
1740 pAddr
= (struct sockaddr_ipx
*)Addr
;
1744 if (pAddr
&& (pAddr
->sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyIpx
)))
1746 memcpy(NodeNumber
, pAddr
->sa_nodenum
, sizeof(NodeNumber
));
1748 return osl_Socket_Ok
;
1751 return osl_Socket_Error
;
1755 /*****************************************************************************/
1756 /* osl_getIpxSocketNumber */
1757 /*****************************************************************************/
1758 sal_Int32 SAL_CALL
osl_getIpxSocketNumber(oslSocketAddr Addr
)
1760 struct sockaddr_ipx
* pAddr
= (struct sockaddr_ipx
*)Addr
;
1763 if (pAddr
&& (pAddr
->sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyIpx
)))
1764 return pAddr
->sa_socket
;
1766 return OSL_INVALID_IPX_SOCKET_NO
;
1769 #endif /* OBSOLETE */
1771 /*****************************************************************************/
1772 /* osl_createSocket */
1773 /*****************************************************************************/
1774 oslSocket SAL_CALL
osl_createSocket(oslAddrFamily Family
,
1776 oslProtocol Protocol
)
1782 pSocket
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1785 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
1786 TYPE_TO_NATIVE(Type
),
1787 PROTOCOL_TO_NATIVE(Protocol
));
1789 /* creation failed => free memory */
1790 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
1792 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1796 __osl_destroySocketImpl((pSocket
));
1801 /* set close-on-exec flag */
1802 if ((Flags
= fcntl(pSocket
->m_Socket
, F_GETFD
, 0)) != -1)
1804 Flags
|= FD_CLOEXEC
;
1805 if (fcntl(pSocket
->m_Socket
, F_SETFD
, Flags
) == -1)
1807 pSocket
->m_nLastError
=errno
;
1808 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1815 pSocket
->m_nLastError
=errno
;
1819 pSocket
->m_CloseCallback
= NULL
;
1820 pSocket
->m_CallbackArg
= NULL
;
1826 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
1828 osl_incrementInterlockedCount( &(pSocket
->m_nRefCount
) );
1831 void SAL_CALL
osl_releaseSocket( oslSocket pSocket
)
1833 if( pSocket
&& 0 == osl_decrementInterlockedCount( &(pSocket
->m_nRefCount
) ) )
1836 if ( pSocket
->m_bIsAccepting
== sal_True
)
1838 OSL_ENSURE(0, "osl_destroySocket : attempt to destroy socket while accepting\n");
1842 osl_closeSocket( pSocket
);
1843 __osl_destroySocketImpl( pSocket
);
1849 /*****************************************************************************/
1850 /* osl_closeSocket */
1851 /*****************************************************************************/
1852 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
1857 /* socket already invalid */
1861 pSocket
->m_nLastError
=0;
1862 nFD
= pSocket
->m_Socket
;
1864 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1867 pSocket
->m_bIsInShutdown
= sal_True
;
1869 if ( pSocket
->m_bIsAccepting
== sal_True
)
1872 struct sockaddr aSockAddr
;
1873 socklen_t nSockLen
= sizeof(aSockAddr
);
1875 nRet
= getsockname(nFD
, &aSockAddr
, &nSockLen
);
1876 #if OSL_DEBUG_LEVEL > 1
1879 perror("getsockname");
1881 #endif /* OSL_DEBUG_LEVEL */
1883 if ( aSockAddr
.sa_family
== AF_INET
)
1885 struct sockaddr_in
* pSockAddrIn
= (struct sockaddr_in
*) &aSockAddr
;
1887 if ( pSockAddrIn
->sin_addr
.s_addr
== htonl(INADDR_ANY
) )
1889 pSockAddrIn
->sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1892 nConnFD
= socket(AF_INET
, SOCK_STREAM
, 0);
1893 #if OSL_DEBUG_LEVEL > 1
1898 #endif /* OSL_DEBUG_LEVEL */
1900 nRet
= connect(nConnFD
, &aSockAddr
, sizeof(aSockAddr
));
1901 #if OSL_DEBUG_LEVEL > 1
1906 #endif /* OSL_DEBUG_LEVEL */
1912 /* registrierten Callback ausfuehren */
1913 if (pSocket
->m_CloseCallback
!= NULL
)
1915 pSocket
->m_CloseCallback(pSocket
->m_CallbackArg
);
1921 pSocket
->m_nLastError
=errno
;
1922 OSL_TRACE("closeSocket close error '%s'\n",strerror(errno
));
1925 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1928 /*****************************************************************************/
1929 /* osl_getLocalAddrOfSocket */
1930 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1931 /* are the same! I don't like it very much but see no other easy way to conceal */
1932 /* the struct sockaddr from the eyes of the user. */
1933 /*****************************************************************************/
1934 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
1937 struct sockaddr Addr
;
1938 oslSocketAddr pAddr
;
1940 if (pSocket
== NULL
) /* ENOTSOCK */
1941 return ((oslSocketAddr
)NULL
);
1943 AddrLen
= sizeof(struct sockaddr
);
1945 if (getsockname(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1946 return ((oslSocketAddr
)NULL
);
1948 pAddr
= __osl_createSocketAddrFromSystem( &Addr
);
1952 /*****************************************************************************/
1953 /* osl_getPeerAddrOfSocket */
1954 /*****************************************************************************/
1955 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1958 struct sockaddr Addr
;
1960 OSL_ASSERT(pSocket
);
1966 pSocket
->m_nLastError
=0;
1967 AddrLen
= sizeof(struct sockaddr
);
1969 if(getpeername(pSocket
->m_Socket
, &Addr
, &AddrLen
) == OSL_SOCKET_ERROR
)
1971 pSocket
->m_nLastError
=errno
;
1974 return __osl_createSocketAddrFromSystem( &Addr
);
1977 /*****************************************************************************/
1978 /* osl_bindAddrToSocket */
1979 /*****************************************************************************/
1980 sal_Bool SAL_CALL
osl_bindAddrToSocket(oslSocket pSocket
,
1981 oslSocketAddr pAddr
)
1985 OSL_ASSERT(pSocket
&& pAddr
);
1986 if ( pSocket
== 0 || pAddr
== 0 )
1991 pSocket
->m_nLastError
=0;
1993 nRet
= bind(pSocket
->m_Socket
, &(pAddr
->m_sockaddr
), sizeof(struct sockaddr
));
1995 if ( nRet
== OSL_SOCKET_ERROR
)
1997 pSocket
->m_nLastError
=errno
;
2005 /*****************************************************************************/
2006 /* osl_listenOnSocket */
2007 /*****************************************************************************/
2008 sal_Bool SAL_CALL
osl_listenOnSocket(oslSocket pSocket
,
2009 sal_Int32 MaxPendingConnections
)
2013 OSL_ASSERT(pSocket
);
2019 pSocket
->m_nLastError
=0;
2021 nRet
= listen(pSocket
->m_Socket
,
2022 MaxPendingConnections
== -1 ?
2024 MaxPendingConnections
);
2025 if ( nRet
== OSL_SOCKET_ERROR
)
2027 pSocket
->m_nLastError
=errno
;
2035 /*****************************************************************************/
2036 /* osl_connectSocketTo */
2037 /*****************************************************************************/
2038 oslSocketResult SAL_CALL
osl_connectSocketTo(oslSocket pSocket
,
2039 oslSocketAddr pAddr
,
2040 const TimeValue
* pTimeout
)
2046 oslSocketResult Result
= osl_Socket_Ok
;
2048 OSL_PRECOND(pSocket
, "osl_connectSocketTo(): need a valid socket!\n");
2052 return osl_Socket_Error
;
2055 pSocket
->m_nLastError
=0;
2057 if (osl_isNonBlockingMode(pSocket
))
2059 if (connect(pSocket
->m_Socket
,
2060 &(pAddr
->m_sockaddr
),
2061 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
2062 return osl_Socket_Ok
;
2064 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
2066 pSocket
->m_nLastError
=EINPROGRESS
;
2067 return osl_Socket_InProgress
;
2071 pSocket
->m_nLastError
=errno
;
2072 OSL_TRACE("can't connect : '%s'",strerror(errno
));
2073 return osl_Socket_Error
;
2076 /* set socket temporarily to non-blocking */
2077 OSL_VERIFY(osl_enableNonBlockingMode(pSocket
, sal_True
));
2079 /* initiate connect */
2080 if(connect(pSocket
->m_Socket
,
2081 &(pAddr
->m_sockaddr
),
2082 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
2084 /* immediate connection */
2085 osl_enableNonBlockingMode(pSocket
, sal_False
);
2087 return osl_Socket_Ok
;
2091 /* really an error or just delayed? */
2092 if (errno
!= EINPROGRESS
)
2094 pSocket
->m_nLastError
=errno
;
2096 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
2097 errno
, strerror(errno
));
2099 osl_enableNonBlockingMode(pSocket
, sal_False
);
2100 return osl_Socket_Error
;
2105 /* prepare select set for socket */
2108 FD_SET(pSocket
->m_Socket
, &WriteSet
);
2109 FD_SET(pSocket
->m_Socket
, &ExcptSet
);
2111 /* prepare timeout */
2114 /* divide milliseconds into seconds and microseconds */
2115 tv
.tv_sec
= pTimeout
->Seconds
;
2116 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
2120 ReadyHandles
= select(pSocket
->m_Socket
+1,
2122 PTR_FD_SET(WriteSet
),
2123 PTR_FD_SET(ExcptSet
),
2124 (pTimeout
) ? &tv
: 0);
2126 if (ReadyHandles
> 0) /* connected */
2128 if ( FD_ISSET(pSocket
->m_Socket
, &WriteSet
) )
2131 socklen_t nErrorSize
= sizeof( nErrorCode
);
2135 nSockOpt
= getsockopt ( pSocket
->m_Socket
, SOL_SOCKET
, SO_ERROR
,
2136 &nErrorCode
, &nErrorSize
);
2137 if ( (nSockOpt
== 0) && (nErrorCode
== 0))
2138 Result
= osl_Socket_Ok
;
2140 Result
= osl_Socket_Error
;
2144 Result
= osl_Socket_Error
;
2147 else if (ReadyHandles
< 0) /* error */
2149 if (errno
== EBADF
) /* most probably interrupted by close() */
2151 /* do not access pSockImpl because it is about to be or */
2152 /* already destroyed */
2153 return osl_Socket_Interrupted
;
2157 pSocket
->m_nLastError
=errno
;
2158 Result
= osl_Socket_Error
;
2163 pSocket
->m_nLastError
=errno
;
2164 Result
= osl_Socket_TimedOut
;
2167 osl_enableNonBlockingMode(pSocket
, sal_False
);
2173 /*****************************************************************************/
2174 /* osl_acceptConnectionOnSocket */
2175 /*****************************************************************************/
2176 oslSocket SAL_CALL
osl_acceptConnectionOnSocket(oslSocket pSocket
,
2177 oslSocketAddr
* ppAddr
)
2179 struct sockaddr Addr
;
2180 int Connection
, Flags
;
2181 oslSocket pConnectionSockImpl
;
2183 socklen_t AddrLen
= sizeof(struct sockaddr
);
2184 OSL_ASSERT(pSocket
);
2190 pSocket
->m_nLastError
=0;
2192 pSocket
->m_bIsAccepting
= sal_True
;
2195 if( ppAddr
&& *ppAddr
)
2197 osl_destroySocketAddr( *ppAddr
);
2201 /* prevent Linux EINTR behaviour */
2204 Connection
= accept(pSocket
->m_Socket
, &Addr
, &AddrLen
);
2205 } while (Connection
== -1 && errno
== EINTR
);
2208 /* accept failed? */
2209 if( Connection
== OSL_SOCKET_ERROR
)
2211 pSocket
->m_nLastError
=errno
;
2212 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'\n",strerror(errno
));
2215 pSocket
->m_bIsAccepting
= sal_False
;
2220 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
2224 if ( pSocket
->m_bIsInShutdown
== sal_True
)
2227 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept\n");
2235 *ppAddr
= __osl_createSocketAddrFromSystem(&Addr
);
2239 pConnectionSockImpl
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
2241 /* set close-on-exec flag */
2242 if ((Flags
= fcntl(Connection
, F_GETFD
, 0)) != -1)
2244 Flags
|= FD_CLOEXEC
;
2245 if (fcntl(Connection
, F_SETFD
, Flags
) == -1)
2247 pSocket
->m_nLastError
=errno
;
2248 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
2255 pConnectionSockImpl
->m_Socket
= Connection
;
2256 pConnectionSockImpl
->m_nLastError
= 0;
2257 pConnectionSockImpl
->m_CloseCallback
= NULL
;
2258 pConnectionSockImpl
->m_CallbackArg
= NULL
;
2260 pConnectionSockImpl
->m_bIsAccepting
= sal_False
;
2262 pSocket
->m_bIsAccepting
= sal_False
;
2264 return pConnectionSockImpl
;
2267 /*****************************************************************************/
2268 /* osl_receiveSocket */
2269 /*****************************************************************************/
2270 sal_Int32 SAL_CALL
osl_receiveSocket(oslSocket pSocket
,
2272 sal_uInt32 BytesToRead
,
2273 oslSocketMsgFlag Flag
)
2277 OSL_ASSERT(pSocket
);
2280 OSL_TRACE("osl_receiveSocket : Invalid socket");
2284 pSocket
->m_nLastError
=0;
2288 nRead
= recv(pSocket
->m_Socket
,
2291 MSG_FLAG_TO_NATIVE(Flag
));
2292 } while ( nRead
< 0 && errno
== EINTR
);
2296 pSocket
->m_nLastError
=errno
;
2297 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,strerror(errno
));
2299 else if ( nRead
== 0 )
2301 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
2308 /*****************************************************************************/
2309 /* osl_receiveFromSocket */
2310 /*****************************************************************************/
2311 sal_Int32 SAL_CALL
osl_receiveFromSocket(oslSocket pSocket
,
2312 oslSocketAddr pSenderAddr
,
2314 sal_uInt32 BufferSize
,
2315 oslSocketMsgFlag Flag
)
2318 struct sockaddr
*pSystemSockAddr
= 0;
2319 socklen_t AddrLen
= 0;
2322 AddrLen
= sizeof( struct sockaddr
);
2323 pSystemSockAddr
= &(pSenderAddr
->m_sockaddr
);
2326 OSL_ASSERT(pSocket
);
2329 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
2333 pSocket
->m_nLastError
=0;
2335 nRead
= recvfrom(pSocket
->m_Socket
,
2338 MSG_FLAG_TO_NATIVE(Flag
),
2344 pSocket
->m_nLastError
=errno
;
2345 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead
,strerror(errno
));
2347 else if ( nRead
== 0 )
2349 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
2356 /*****************************************************************************/
2357 /* osl_sendSocket */
2358 /*****************************************************************************/
2359 sal_Int32 SAL_CALL
osl_sendSocket(oslSocket pSocket
,
2360 const void* pBuffer
,
2361 sal_uInt32 BytesToSend
,
2362 oslSocketMsgFlag Flag
)
2366 OSL_ASSERT(pSocket
);
2369 OSL_TRACE("osl_sendSocket : Invalid socket");
2373 pSocket
->m_nLastError
=0;
2377 nWritten
= send(pSocket
->m_Socket
,
2380 MSG_FLAG_TO_NATIVE(Flag
));
2381 } while ( nWritten
< 0 && errno
== EINTR
);
2386 pSocket
->m_nLastError
=errno
;
2387 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,strerror(errno
));
2389 else if ( nWritten
== 0 )
2391 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,"EOL");
2397 /*****************************************************************************/
2398 /* osl_sendToSocket */
2399 /*****************************************************************************/
2400 sal_Int32 SAL_CALL
osl_sendToSocket(oslSocket pSocket
,
2401 oslSocketAddr ReceiverAddr
,
2402 const void* pBuffer
,
2403 sal_uInt32 BytesToSend
,
2404 oslSocketMsgFlag Flag
)
2408 struct sockaddr
*pSystemSockAddr
= 0;
2412 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
2413 AddrLen
= sizeof( struct sockaddr
);
2416 OSL_ASSERT(pSocket
);
2419 OSL_TRACE("osl_sendToSocket : Invalid socket");
2423 pSocket
->m_nLastError
=0;
2425 /* ReceiverAddr might be 0 when used on a connected socket. */
2426 /* Then sendto should behave like send. */
2428 nWritten
= sendto(pSocket
->m_Socket
,
2431 MSG_FLAG_TO_NATIVE(Flag
),
2437 pSocket
->m_nLastError
=errno
;
2438 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,strerror(errno
));
2440 else if ( nWritten
== 0 )
2442 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,"EOL");
2448 /*****************************************************************************/
2449 /* osl_readSocket */
2450 /*****************************************************************************/
2451 sal_Int32 SAL_CALL
osl_readSocket (
2452 oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
2454 sal_uInt8
* Ptr
= (sal_uInt8
*)pBuffer
;
2455 sal_uInt32 BytesRead
= 0;
2456 sal_uInt32 BytesToRead
= n
;
2458 OSL_ASSERT( pSocket
);
2460 /* loop until all desired bytes were read or an error occured */
2461 while (BytesToRead
> 0)
2464 RetVal
= osl_receiveSocket(pSocket
,
2467 osl_Socket_MsgNormal
);
2469 /* error occured? */
2475 BytesToRead
-= RetVal
;
2476 BytesRead
+= RetVal
;
2483 /*****************************************************************************/
2484 /* osl_writeSocket */
2485 /*****************************************************************************/
2486 sal_Int32 SAL_CALL
osl_writeSocket(
2487 oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
2489 /* loop until all desired bytes were send or an error occured */
2490 sal_uInt32 BytesSend
= 0;
2491 sal_uInt32 BytesToSend
= n
;
2492 sal_uInt8
*Ptr
= ( sal_uInt8
* )pBuffer
;
2494 OSL_ASSERT( pSocket
);
2496 while (BytesToSend
> 0)
2500 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
2502 /* error occured? */
2508 BytesToSend
-= RetVal
;
2509 BytesSend
+= RetVal
;
2516 /*****************************************************************************/
2517 /* __osl_socket_poll */
2518 /*****************************************************************************/
2520 #ifdef HAVE_POLL_H /* poll() */
2522 sal_Bool
__osl_socket_poll (
2524 const TimeValue
* pTimeout
,
2531 OSL_ASSERT(pSocket
);
2532 pSocket
->m_nLastError
= 0;
2534 fds
.fd
= pSocket
->m_Socket
;
2535 fds
.events
= nEvent
;
2541 /* Convert to [ms] */
2542 timeout
= pTimeout
->Seconds
* 1000;
2543 timeout
+= pTimeout
->Nanosec
/ (1000 * 1000);
2546 result
= poll (&fds
, 1, timeout
);
2549 pSocket
->m_nLastError
= errno
;
2550 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2551 errno
, strerror(errno
));
2560 return ((fds
.revents
& nEvent
) == nEvent
);
2563 #else /* select() */
2565 sal_Bool
__osl_socket_poll (
2567 const TimeValue
* pTimeout
,
2574 OSL_ASSERT(pSocket
);
2575 pSocket
->m_nLastError
= 0;
2578 FD_SET(pSocket
->m_Socket
, &fds
);
2582 /* Convert to 'timeval' */
2583 tv
.tv_sec
= pTimeout
->Seconds
;
2584 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000;
2588 pSocket
->m_Socket
+ 1,
2589 (nEvent
== POLLIN
) ? PTR_FD_SET(fds
) : NULL
,
2590 (nEvent
== POLLOUT
) ? PTR_FD_SET(fds
) : NULL
,
2591 (nEvent
== POLLPRI
) ? PTR_FD_SET(fds
) : NULL
,
2592 (pTimeout
) ? &tv
: NULL
);
2596 pSocket
->m_nLastError
= errno
;
2597 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2598 errno
, strerror(errno
));
2607 return (FD_ISSET(pSocket
->m_Socket
, &fds
) ? sal_True
: sal_False
);
2610 #endif /* HAVE_POLL_H */
2612 /*****************************************************************************/
2613 /* osl_isReceiveReady */
2614 /*****************************************************************************/
2615 sal_Bool SAL_CALL
osl_isReceiveReady (
2616 oslSocket pSocket
, const TimeValue
* pTimeout
)
2618 OSL_ASSERT(pSocket
);
2619 if (pSocket
== NULL
)
2625 return __osl_socket_poll (pSocket
, pTimeout
, POLLIN
);
2628 /*****************************************************************************/
2629 /* osl_isSendReady */
2630 /*****************************************************************************/
2631 sal_Bool SAL_CALL
osl_isSendReady (
2632 oslSocket pSocket
, const TimeValue
* pTimeout
)
2634 OSL_ASSERT(pSocket
);
2635 if (pSocket
== NULL
)
2641 return __osl_socket_poll (pSocket
, pTimeout
, POLLOUT
);
2644 /*****************************************************************************/
2645 /* osl_isExceptionPending */
2646 /*****************************************************************************/
2647 sal_Bool SAL_CALL
osl_isExceptionPending (
2648 oslSocket pSocket
, const TimeValue
* pTimeout
)
2650 OSL_ASSERT(pSocket
);
2651 if (pSocket
== NULL
)
2657 return __osl_socket_poll (pSocket
, pTimeout
, POLLPRI
);
2660 /*****************************************************************************/
2661 /* osl_shutdownSocket */
2662 /*****************************************************************************/
2663 sal_Bool SAL_CALL
osl_shutdownSocket(oslSocket pSocket
,
2664 oslSocketDirection Direction
)
2668 OSL_ASSERT(pSocket
);
2674 pSocket
->m_nLastError
=0;
2676 nRet
=shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
));
2679 pSocket
->m_nLastError
=errno
;
2680 OSL_TRACE("shutdown error '%s'\n",strerror(errno
));
2686 /*****************************************************************************/
2687 /* osl_getSocketOption */
2688 /*****************************************************************************/
2689 sal_Int32 SAL_CALL
osl_getSocketOption(oslSocket pSocket
,
2690 oslSocketOptionLevel Level
,
2691 oslSocketOption Option
,
2693 sal_uInt32 BufferLen
)
2695 socklen_t nOptLen
= (socklen_t
) BufferLen
;
2697 OSL_ASSERT(pSocket
);
2703 pSocket
->m_nLastError
=0;
2705 if(getsockopt(pSocket
->m_Socket
,
2706 OPTION_LEVEL_TO_NATIVE(Level
),
2707 OPTION_TO_NATIVE(Option
),
2711 pSocket
->m_nLastError
=errno
;
2718 /*****************************************************************************/
2719 /* osl_setSocketOption */
2720 /*****************************************************************************/
2721 sal_Bool SAL_CALL
osl_setSocketOption(oslSocket pSocket
,
2722 oslSocketOptionLevel Level
,
2723 oslSocketOption Option
,
2725 sal_uInt32 BufferLen
)
2729 OSL_ASSERT(pSocket
);
2735 pSocket
->m_nLastError
=0;
2737 nRet
= setsockopt(pSocket
->m_Socket
,
2738 OPTION_LEVEL_TO_NATIVE(Level
),
2739 OPTION_TO_NATIVE(Option
),
2745 pSocket
->m_nLastError
=errno
;
2752 /*****************************************************************************/
2753 /* osl_enableNonBlockingMode */
2754 /*****************************************************************************/
2755 sal_Bool SAL_CALL
osl_enableNonBlockingMode(oslSocket pSocket
,
2761 OSL_ASSERT(pSocket
);
2767 pSocket
->m_nLastError
=0;
2769 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2772 flags
|= O_NONBLOCK
;
2774 flags
&= ~(O_NONBLOCK
);
2776 nRet
= fcntl(pSocket
->m_Socket
, F_SETFL
, flags
);
2780 pSocket
->m_nLastError
=errno
;
2787 /*****************************************************************************/
2788 /* osl_isNonBlockingMode */
2789 /*****************************************************************************/
2790 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
2794 OSL_ASSERT(pSocket
);
2800 pSocket
->m_nLastError
=0;
2802 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2804 if (flags
== -1 || !(flags
& O_NONBLOCK
))
2810 /*****************************************************************************/
2811 /* osl_getSocketType */
2812 /*****************************************************************************/
2813 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
2816 socklen_t TypeSize
= sizeof(Type
);
2818 OSL_ASSERT(pSocket
);
2821 return osl_Socket_TypeInvalid
;
2824 pSocket
->m_nLastError
=0;
2826 if(getsockopt(pSocket
->m_Socket
,
2827 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
2828 OPTION_TO_NATIVE(osl_Socket_OptionType
),
2833 pSocket
->m_nLastError
=errno
;
2834 return osl_Socket_TypeInvalid
;
2837 return TYPE_FROM_NATIVE(Type
);
2841 /*****************************************************************************/
2842 /* osl_getLastSocketErrorDescription */
2843 /*****************************************************************************/
2844 void SAL_CALL
osl_getLastSocketErrorDescription(oslSocket Socket
, rtl_uString
**ustrError
)
2846 sal_Char pszError
[1024];
2850 osl_psz_getLastSocketErrorDescription(Socket
,pszError
,sizeof(pszError
));
2852 rtl_uString_newFromAscii(ustrError
,pszError
);
2858 void SAL_CALL
osl_psz_getLastSocketErrorDescription(oslSocket pSocket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
)
2860 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2861 pBuffer
[BufferSize
-1]= '\0';
2865 strncpy(pBuffer
, strerror(EINVAL
), BufferSize
-1);
2869 strncpy(pBuffer
, strerror(pSocket
->m_nLastError
), BufferSize
-1);
2873 /*****************************************************************************/
2874 /* osl_getLastSocketError */
2875 /*****************************************************************************/
2876 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket pSocket
)
2880 return ERROR_FROM_NATIVE(EINVAL
);
2883 return ERROR_FROM_NATIVE(pSocket
->m_nLastError
);
2886 /*****************************************************************************/
2888 /*****************************************************************************/
2889 typedef struct _TSocketSetImpl
2891 int m_MaxHandle
; /* for select(), the largest descriptor in the set */
2892 fd_set m_Set
; /* the set of descriptors */
2896 /*****************************************************************************/
2897 /* osl_createSocketSet */
2898 /*****************************************************************************/
2899 oslSocketSet SAL_CALL
osl_createSocketSet()
2901 TSocketSetImpl
* pSet
;
2903 pSet
= (TSocketSetImpl
*)malloc(sizeof(TSocketSetImpl
));
2909 pSet
->m_MaxHandle
= 0;
2910 FD_ZERO(&pSet
->m_Set
);
2913 return (oslSocketSet
)pSet
;
2916 /*****************************************************************************/
2917 /* osl_destroySocketSet */
2918 /*****************************************************************************/
2919 void SAL_CALL
osl_destroySocketSet(oslSocketSet Set
)
2925 /*****************************************************************************/
2926 /* osl_clearSocketSet */
2927 /*****************************************************************************/
2928 void SAL_CALL
osl_clearSocketSet(oslSocketSet Set
)
2930 TSocketSetImpl
* pSet
;
2937 pSet
= (TSocketSetImpl
*)Set
;
2938 pSet
->m_MaxHandle
= 0;
2940 FD_ZERO(&pSet
->m_Set
);
2943 /*****************************************************************************/
2944 /* osl_addToSocketSet */
2945 /*****************************************************************************/
2946 void SAL_CALL
osl_addToSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2948 TSocketSetImpl
* pSet
;
2951 OSL_ASSERT(pSocket
);
2953 if ( Set
== 0 || pSocket
== 0)
2958 pSet
= (TSocketSetImpl
*)Set
;
2960 /* correct max handle */
2961 if(pSocket
->m_Socket
> pSet
->m_MaxHandle
)
2962 pSet
->m_MaxHandle
= pSocket
->m_Socket
;
2963 FD_SET(pSocket
->m_Socket
, &pSet
->m_Set
);
2967 /*****************************************************************************/
2968 /* osl_removeFromSocketSet */
2969 /*****************************************************************************/
2970 void SAL_CALL
osl_removeFromSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2972 TSocketSetImpl
* pSet
;
2975 OSL_ASSERT(pSocket
);
2977 if ( Set
== 0 || pSocket
== 0)
2982 pSet
= (TSocketSetImpl
*)Set
;
2984 /* correct max handle */
2985 if(pSocket
->m_Socket
== pSet
->m_MaxHandle
)
2987 /* not optimal, since the next used descriptor might be */
2988 /* much smaller than m_Socket-1, but it will do */
2989 pSet
->m_MaxHandle
--;
2990 if(pSet
->m_MaxHandle
< 0)
2992 pSet
->m_MaxHandle
= 0; /* avoid underflow */
2996 FD_CLR(pSocket
->m_Socket
, &pSet
->m_Set
);
2999 /*****************************************************************************/
3000 /* osl_isInSocketSet */
3001 /*****************************************************************************/
3002 sal_Bool SAL_CALL
osl_isInSocketSet(oslSocketSet Set
, oslSocket pSocket
)
3004 TSocketSetImpl
* pSet
;
3007 OSL_ASSERT(pSocket
);
3008 if ( Set
== 0 || pSocket
== 0 )
3013 pSet
= (TSocketSetImpl
*)Set
;
3015 return (FD_ISSET(pSocket
->m_Socket
, &pSet
->m_Set
) != 0);
3018 /*****************************************************************************/
3019 /* osl_demultiplexSocketEvents */
3020 /*****************************************************************************/
3021 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents(oslSocketSet IncomingSet
,
3022 oslSocketSet OutgoingSet
,
3023 oslSocketSet OutOfBandSet
,
3024 const TimeValue
* pTimeout
)
3028 TSocketSetImpl
* pInSet
;
3029 TSocketSetImpl
* pOutSet
;
3030 TSocketSetImpl
* pOOBSet
;
3034 /* non-blocking call */
3035 tv
.tv_sec
= pTimeout
->Seconds
;
3036 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
3039 /* map opaque data to impl-types */
3040 pInSet
= (TSocketSetImpl
*)IncomingSet
;
3041 pOutSet
= (TSocketSetImpl
*)OutgoingSet
;
3042 pOOBSet
= (TSocketSetImpl
*)OutOfBandSet
;
3044 /* get max handle from all sets */
3046 MaxHandle
= pInSet
->m_MaxHandle
;
3048 if (pOutSet
&& (pOutSet
->m_MaxHandle
> MaxHandle
))
3049 MaxHandle
= pOutSet
->m_MaxHandle
;
3051 if (pOOBSet
&& (pOOBSet
->m_MaxHandle
> MaxHandle
))
3052 MaxHandle
= pOOBSet
->m_MaxHandle
;
3054 return select(MaxHandle
+1,
3055 pInSet
? PTR_FD_SET(pInSet
->m_Set
) : 0,
3056 pOutSet
? PTR_FD_SET(pOutSet
->m_Set
) : 0,
3057 pOOBSet
? PTR_FD_SET(pOOBSet
->m_Set
) : 0,
3058 pTimeout
? &tv
: 0);