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.5.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
)
804 struct hostent
*__result
; /* will be the same as result */
806 __error
= gethostbyname_r (name
, result
, buffer
, buflen
,
807 &__result
, h_errnop
);
808 return __error
? NULL
: __result
;
813 return gethostbyname_r( name
, result
, buffer
, buflen
, h_errnop
);
817 static sal_Bool
_osl_getDomainName (sal_Char
*buffer
, sal_Int32 bufsiz
)
824 #if 0 // YD 17/04/06 libc panic for fork() from thread!=1
844 execv ("/bin/domainname", argv
);
845 // arriving here means exec failed
850 sal_Int32 k
= 0, n
= bufsiz
;
853 if ((k
= read (p
[0], buffer
, n
- 1)) > 0)
856 if (buffer
[k
- 1] == '\n')
861 waitpid (pid
, &nStatus
, 0);
874 static sal_Char
* _osl_getFullQualifiedDomainName (const sal_Char
*pHostName
)
876 # define DOMAINNAME_LENGTH 512
877 sal_uInt32 nLengthOfHostName
;
878 static sal_uInt32 nLengthOfDomainName
= 0;
879 static sal_Char
*pDomainName
= NULL
;
881 sal_Char
*pFullQualifiedName
;
883 FILE *pPipeToDomainnameExe
;
884 #endif /* OBSOLETE */
886 /* get a '\0' terminated domainname */
888 /* read default domainname default from environment */
889 if (nLengthOfDomainName
== 0)
891 sal_Char
*pEnvDomain
;
893 pEnvDomain
= getenv ("STAR_OVERRIDE_DOMAINNAME");
896 pDomainName
= strdup (pEnvDomain
);
897 nLengthOfDomainName
= strlen (pDomainName
);
902 if (nLengthOfDomainName
== 0)
904 sal_Char pDomainNameBuffer
[ DOMAINNAME_LENGTH
];
906 pDomainNameBuffer
[0] = '\0';
908 if (_osl_getDomainName (pDomainNameBuffer
, DOMAINNAME_LENGTH
))
910 pDomainName
= strdup (pDomainNameBuffer
);
911 nLengthOfDomainName
= strlen (pDomainName
);
919 /* call 'domainname > /usr/tmp/some-tmp-file', since
920 popen read pclose do block or core-dump,
921 (even the pipe-stuff that comes with pthreads) */
922 if (nLengthOfDomainName
== 0)
924 sal_Char tmp_name
[ L_tmpnam
];
926 sal_Char domain_call
[ L_tmpnam
+ 16 ] = "domainname > ";
931 strcat ( domain_call
, tmp_name
);
932 if ( (system ( domain_call
) == 0)
933 && ((tmp_file
= fopen( tmp_name
, "r" )) != NULL
) )
935 sal_Char pDomainNameBuffer
[ DOMAINNAME_LENGTH
];
937 pDomainNameBuffer
[0] = '\0';
939 if ( fgets ( pDomainNameBuffer
, DOMAINNAME_LENGTH
, tmp_file
) )
941 pDomainName
= strdup( pDomainNameBuffer
);
942 nLengthOfDomainName
= strlen( pDomainName
);
943 if ( ( nLengthOfDomainName
> 0 )
944 && ( pDomainName
[ nLengthOfDomainName
- 1] == '\n' ) )
945 pDomainName
[ --nLengthOfDomainName
] = '\0';
954 /* read the domainname from pipe to the program domainname */
955 if ( (nLengthOfDomainName
== 0)
956 && (pPipeToDomainnameExe
= popen( "domainname", "r")) )
959 sal_Char pDomainNameBuffer
[ DOMAINNAME_LENGTH
];
960 sal_Char
*pDomainNamePointer
;
962 pDomainNameBuffer
[0] = '\0';
964 pDomainNamePointer
= pDomainNameBuffer
;
965 while ( ((c
= getc( pPipeToDomainnameExe
)) != EOF
)
966 && (nLengthOfDomainName
< (DOMAINNAME_LENGTH
- 1)) )
970 nLengthOfDomainName
++ ;
971 *pDomainNamePointer
++ = (sal_Char
)c
;
974 *pDomainNamePointer
= '\0';
975 pDomainName
= strdup( pDomainNameBuffer
);
977 pclose( pPipeToDomainnameExe
);
981 #endif /* OBSOLETE */
983 /* compose hostname and domainname */
984 nLengthOfHostName
= strlen( pHostName
);
985 pFullQualifiedName
= (sal_Char
*) malloc( (nLengthOfHostName
+ 1
986 + nLengthOfDomainName
+ 1) * sizeof(sal_Char
) );
987 memcpy( pFullQualifiedName
, pHostName
,
988 (nLengthOfHostName
+ 1) * sizeof(sal_Char
) );
990 if ( nLengthOfDomainName
> 0 )
992 /* fqdn = hostname + '.' + domainname + '\0' */
993 pFullQualifiedName
[ nLengthOfHostName
] = '.';
994 memcpy( pFullQualifiedName
+ nLengthOfHostName
+ 1, pDomainName
,
995 nLengthOfDomainName
+ 1 );
998 /* check whether full-qualified name and hostname point to the same host
999 * should almost always be true */
1000 if ( nLengthOfDomainName
> 0 )
1002 struct hostent
*pQualifiedHostByName
;
1003 struct hostent
*pHostByName
;
1004 sal_Bool bHostsAreEqual
;
1006 /* buffer for calls to reentrant version of gethostbyname */
1007 struct hostent aHostByName
, aQualifiedHostByName
;
1008 sal_Char pHostBuffer
[ MAX_HOSTBUFFER_SIZE
];
1009 sal_Char pQualifiedHostBuffer
[ MAX_HOSTBUFFER_SIZE
];
1012 pHostBuffer
[0] = '\0';
1013 pQualifiedHostBuffer
[0] = '\0';
1015 /* get list of addresses */
1016 pQualifiedHostByName
= _osl_gethostbyname_r (
1018 &aQualifiedHostByName
, pQualifiedHostBuffer
,
1019 sizeof(pQualifiedHostBuffer
), &nErrorNo
);
1020 pHostByName
= _osl_gethostbyname_r (
1022 &aHostByName
, pHostBuffer
,
1023 sizeof(pHostBuffer
), &nErrorNo
);
1025 /* compare addresses */
1026 bHostsAreEqual
= sal_False
;
1027 if ( pQualifiedHostByName
&& pHostByName
)
1032 /* lists are expected to be (very) short */
1033 for ( p
= pQualifiedHostByName
->h_addr_list
; *p
!= NULL
; p
++ )
1035 for ( q
= pHostByName
->h_addr_list
; *q
!= NULL
; q
++ )
1037 /* in.s_addr may be in_addr_t or uint32_t or heaven knows */
1038 if ( memcmp( *p
, *q
, sizeof(in
.s_addr
) ) == 0 )
1040 bHostsAreEqual
= sal_True
;
1044 if ( bHostsAreEqual
)
1049 /* very strange case, but have to believe it: reduce the
1050 * full qualified name to the unqualified host name */
1051 if ( !bHostsAreEqual
)
1053 OSL_TRACE("_osl_getFullQualifiedDomainName: "
1054 "suspect FQDN: %s\n", pFullQualifiedName
);
1056 pFullQualifiedName
[ nLengthOfHostName
] = '\0';
1057 pFullQualifiedName
= (sal_Char
*)realloc ( pFullQualifiedName
,
1058 (nLengthOfHostName
+ 1) * sizeof( sal_Char
));
1062 /* always return a hostname looked up as carefully as possible
1063 * this string must be freed by the caller */
1064 return pFullQualifiedName
;
1067 /*****************************************************************************/
1068 /* _osl_isFullQualifiedDomainName */
1069 /*****************************************************************************/
1070 static sal_Bool
_osl_isFullQualifiedDomainName (const sal_Char
*pHostName
)
1072 /* a FQDN (aka 'hostname.domain.top_level_domain' )
1073 * is a name which contains a dot '.' in it ( would
1074 * match as well for 'hostname.' but is good enough
1076 return (sal_Bool
)( strchr( pHostName
, (int)'.' ) != NULL
);
1079 /*****************************************************************************/
1081 /*****************************************************************************/
1082 struct oslHostAddrImpl
1084 sal_Char
*pHostName
;
1085 oslSocketAddr pSockAddr
;
1088 static oslHostAddr
_osl_hostentToHostAddr (const struct hostent
*he
)
1090 oslHostAddr pAddr
= NULL
;
1091 oslSocketAddr pSockAddr
= 0;
1094 if ((he
== NULL
) || (he
->h_name
== NULL
) || (he
->h_addr_list
[0] == NULL
))
1095 return ((oslHostAddr
)NULL
);
1097 //YD 18/06/2006 win32 does this with unicode, see socket.cxx
1099 cn
= (sal_Char
*)malloc(strlen (he
->h_name
) + 1);
1102 return ((oslHostAddr
)NULL
);
1104 strcpy(cn
, he
->h_name
);
1106 #if 0 // YD 17/04/06 win32 doesn't it.
1107 if (_osl_isFullQualifiedDomainName(he
->h_name
))
1109 cn
= (sal_Char
*)malloc(strlen (he
->h_name
) + 1);
1112 return ((oslHostAddr
)NULL
);
1114 strcpy(cn
, he
->h_name
);
1118 cn
=_osl_getFullQualifiedDomainName (he
->h_name
);
1121 return ((oslHostAddr
)NULL
);
1125 pSockAddr
= __osl_createSocketAddr();
1126 OSL_ASSERT(pSockAddr
);
1127 if (pSockAddr
== NULL
)
1130 return ((oslHostAddr
)NULL
);
1133 pSockAddr
->m_sockaddr
.sa_family
= he
->h_addrtype
;
1134 if (pSockAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1136 struct sockaddr_in
*sin
= (struct sockaddr_in
*)&(pSockAddr
->m_sockaddr
);
1138 &(sin
->sin_addr
.s_addr
),
1144 /* unknown address family */
1145 /* future extensions for new families might be implemented here */
1147 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.\n");
1148 OSL_ASSERT(sal_False
);
1150 __osl_destroySocketAddr( pSockAddr
);
1152 return ((oslHostAddr
)NULL
);
1155 pAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
1159 __osl_destroySocketAddr( pSockAddr
);
1161 return ((oslHostAddr
)NULL
);
1164 pAddr
->pHostName
= cn
;
1165 pAddr
->pSockAddr
= pSockAddr
;
1170 /*****************************************************************************/
1171 /* osl_createHostAddr */
1172 /*****************************************************************************/
1173 oslHostAddr SAL_CALL
osl_createHostAddr (
1174 rtl_uString
*ustrHostname
,
1175 const oslSocketAddr Addr
)
1177 oslHostAddr HostAddr
;
1178 rtl_String
* strHostname
=0;
1179 sal_Char
* pszHostName
=0;
1181 if ( ustrHostname
!= 0 )
1183 rtl_uString2String( &strHostname
,
1184 rtl_uString_getStr(ustrHostname
),
1185 rtl_uString_getLength(ustrHostname
),
1186 RTL_TEXTENCODING_UTF8
,
1187 OUSTRING_TO_OSTRING_CVTFLAGS
);
1188 pszHostName
= rtl_string_getStr(strHostname
);
1191 HostAddr
= osl_psz_createHostAddr(pszHostName
,Addr
);
1193 if ( strHostname
!= 0 )
1195 rtl_string_release(strHostname
);
1202 oslHostAddr SAL_CALL
osl_psz_createHostAddr (
1203 const sal_Char
*pszHostname
,
1204 const oslSocketAddr pAddr
)
1206 oslHostAddr pHostAddr
;
1209 OSL_ASSERT(pszHostname
&& pAddr
);
1210 if ((pszHostname
== NULL
) || (pAddr
== NULL
))
1211 return ((oslHostAddr
)NULL
);
1213 cn
= (sal_Char
*)malloc(strlen (pszHostname
) + 1);
1216 return ((oslHostAddr
)NULL
);
1218 strcpy (cn
, pszHostname
);
1220 pHostAddr
= (oslHostAddr
) malloc(sizeof(struct oslHostAddrImpl
));
1221 OSL_ASSERT(pHostAddr
);
1225 return ((oslHostAddr
)NULL
);
1228 pHostAddr
->pHostName
= cn
;
1229 pHostAddr
->pSockAddr
= osl_copySocketAddr( pAddr
);
1234 /*****************************************************************************/
1235 /* osl_createHostAddrByName */
1236 /*****************************************************************************/
1237 oslHostAddr SAL_CALL
osl_createHostAddrByName(rtl_uString
*ustrHostname
)
1239 oslHostAddr HostAddr
;
1240 rtl_String
* strHostname
=0;
1241 sal_Char
* pszHostName
=0;
1243 if ( ustrHostname
!= 0 )
1245 rtl_uString2String( &strHostname
,
1246 rtl_uString_getStr(ustrHostname
),
1247 rtl_uString_getLength(ustrHostname
),
1248 RTL_TEXTENCODING_UTF8
,
1249 OUSTRING_TO_OSTRING_CVTFLAGS
);
1250 pszHostName
=rtl_string_getStr(strHostname
);
1253 HostAddr
= osl_psz_createHostAddrByName(pszHostName
);
1255 if ( strHostname
!= 0 )
1257 rtl_string_release(strHostname
);
1263 oslHostAddr SAL_CALL
osl_psz_createHostAddrByName (const sal_Char
*pszHostname
)
1268 static oslMutex mutex
= NULL
;
1271 mutex
= osl_createMutex();
1273 osl_acquireMutex(mutex
);
1275 he
= gethostbyname((sal_Char
*)pszHostname
);
1276 addr
= _osl_hostentToHostAddr (he
);
1278 osl_releaseMutex(mutex
);
1283 /*****************************************************************************/
1284 /* osl_createHostAddrByAddr */
1285 /*****************************************************************************/
1286 oslHostAddr SAL_CALL
osl_createHostAddrByAddr (const oslSocketAddr pAddr
)
1291 return ((oslHostAddr
)NULL
);
1293 if (pAddr
->m_sockaddr
.sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1295 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1298 if (sin
->sin_addr
.s_addr
== htonl(INADDR_ANY
))
1299 return ((oslHostAddr
)NULL
);
1301 he
= gethostbyaddr((sal_Char
*)&(sin
->sin_addr
),
1302 sizeof (sin
->sin_addr
),
1304 return _osl_hostentToHostAddr (he
);
1307 return ((oslHostAddr
)NULL
);
1310 /*****************************************************************************/
1311 /* osl_copyHostAddr */
1312 /*****************************************************************************/
1313 oslHostAddr SAL_CALL
osl_copyHostAddr (const oslHostAddr pAddr
)
1318 return osl_psz_createHostAddr (pAddr
->pHostName
, pAddr
->pSockAddr
);
1320 return ((oslHostAddr
)NULL
);
1323 /*****************************************************************************/
1324 /* osl_getHostnameOfHostAddr */
1325 /*****************************************************************************/
1326 void SAL_CALL
osl_getHostnameOfHostAddr (
1327 const oslHostAddr Addr
,
1328 rtl_uString
**ustrHostname
)
1330 const sal_Char
* pHostname
=0;
1332 pHostname
= osl_psz_getHostnameOfHostAddr(Addr
);
1334 rtl_uString_newFromAscii (ustrHostname
, pHostname
);
1339 const sal_Char
* SAL_CALL
osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr
)
1344 return pAddr
->pHostName
;
1349 /*****************************************************************************/
1350 /* osl_getSocketAddrOfHostAddr */
1351 /*****************************************************************************/
1352 oslSocketAddr SAL_CALL
osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr
)
1357 return ((oslSocketAddr
)(pAddr
->pSockAddr
));
1362 /*****************************************************************************/
1363 /* osl_destroyHostAddr */
1364 /*****************************************************************************/
1365 void SAL_CALL
osl_destroyHostAddr (oslHostAddr pAddr
)
1369 if (pAddr
->pHostName
)
1370 free (pAddr
->pHostName
);
1371 if (pAddr
->pSockAddr
)
1372 osl_destroySocketAddr (pAddr
->pSockAddr
);
1377 /*****************************************************************************/
1378 /* osl_getLocalHostname */
1379 /*****************************************************************************/
1380 oslSocketResult SAL_CALL
osl_getLocalHostname(rtl_uString
**ustrLocalHostname
)
1382 oslSocketResult Result
;
1383 sal_Char pszHostname
[1024];
1385 pszHostname
[0] = '\0';
1387 Result
= osl_psz_getLocalHostname(pszHostname
,sizeof(pszHostname
));
1389 rtl_uString_newFromAscii(ustrLocalHostname
,pszHostname
);
1394 oslSocketResult SAL_CALL
osl_psz_getLocalHostname (
1395 sal_Char
*pBuffer
, sal_uInt32 nBufLen
)
1397 static sal_Char LocalHostname
[256] = "";
1399 if (strlen(LocalHostname
) == 0)
1401 const sal_Char
*pStr
;
1406 if (uname(&uts
) < 0)
1407 return osl_Socket_Error
;
1409 if ((strlen(uts
.nodename
) + 1) > nBufLen
)
1410 return osl_Socket_Error
;
1412 strncpy(LocalHostname
, uts
.nodename
, sizeof( LocalHostname
));
1413 #else /* BSD compatible */
1415 if (gethostname(LocalHostname
, sizeof(LocalHostname
)-1) != 0)
1416 return osl_Socket_Error
;
1417 LocalHostname
[sizeof(LocalHostname
)-1] = 0;
1420 /* check if we have an FQDN */
1421 if (strchr(LocalHostname
, '.') == NULL
)
1425 /* no, determine it via dns */
1426 Addr
= osl_psz_createHostAddrByName(LocalHostname
);
1428 if (Addr
&& (pStr
= osl_psz_getHostnameOfHostAddr(Addr
)) != NULL
)
1430 #if 0 /* OBSOLETE */
1432 #endif /* OBSOLETE */
1433 strcpy(LocalHostname
, pStr
);
1435 #if 0 /* OBSOLETE */
1436 /* already done by _osl_getFullQualifiedDomainName() with
1437 much better heuristics, so this may be contraproductive */
1439 /* no FQDN, last try append domain name */
1440 if ((pChr
= strchr(LocalHostname
, '.')) == NULL
)
1444 pChr
= &LocalHostname
[strlen(LocalHostname
)];
1446 if ( (fp
= popen("domainname", "r")) != 0 )
1452 while ((c
= getc(fp
)) != EOF
)
1455 *pChr
++ = (sal_Char
)c
;
1463 LocalHostname
[0] = '\0';
1465 #endif /* OBSOLETE */
1469 osl_destroyHostAddr(Addr
);
1473 if (strlen(LocalHostname
) > 0)
1475 strncpy(pBuffer
, LocalHostname
, nBufLen
);
1476 pBuffer
[nBufLen
- 1] = '\0';
1478 return osl_Socket_Ok
;
1481 return osl_Socket_Error
;
1484 /*****************************************************************************/
1485 /* osl_resolveHostname */
1486 /*****************************************************************************/
1487 oslSocketAddr SAL_CALL
osl_resolveHostname(rtl_uString
*ustrHostname
)
1490 rtl_String
* strHostname
=0;
1491 sal_Char
* pszHostName
=0;
1493 if ( ustrHostname
!= 0 )
1495 rtl_uString2String( &strHostname
,
1496 rtl_uString_getStr(ustrHostname
),
1497 rtl_uString_getLength(ustrHostname
),
1498 RTL_TEXTENCODING_UTF8
,
1499 OUSTRING_TO_OSTRING_CVTFLAGS
);
1500 pszHostName
= rtl_string_getStr(strHostname
);
1504 Addr
= osl_psz_resolveHostname(pszHostName
);
1506 if ( strHostname
!= 0 )
1508 rtl_string_release(strHostname
);
1516 oslSocketAddr SAL_CALL
osl_psz_resolveHostname(const sal_Char
* pszHostname
)
1518 struct oslHostAddrImpl
*pAddr
= (oslHostAddr
)osl_psz_createHostAddrByName(pszHostname
);
1522 oslSocketAddr SockAddr
= osl_copySocketAddr(pAddr
->pSockAddr
);
1524 osl_destroyHostAddr(pAddr
);
1529 return ((oslSocketAddr
)NULL
);
1532 /*****************************************************************************/
1533 /* osl_getServicePort */
1534 /*****************************************************************************/
1535 sal_Int32 SAL_CALL
osl_getServicePort(rtl_uString
*ustrServicename
, rtl_uString
*ustrProtocol
)
1538 rtl_String
* strServicename
=0;
1539 rtl_String
* strProtocol
=0;
1540 sal_Char
* pszServiceName
=0;
1541 sal_Char
* pszProtocol
=0;
1543 if ( ustrServicename
!= 0 )
1545 rtl_uString2String( &strServicename
,
1546 rtl_uString_getStr(ustrServicename
),
1547 rtl_uString_getLength(ustrServicename
),
1548 RTL_TEXTENCODING_UTF8
,
1549 OUSTRING_TO_OSTRING_CVTFLAGS
);
1550 pszServiceName
= rtl_string_getStr(strServicename
);
1553 if ( ustrProtocol
!= 0 )
1555 rtl_uString2String( &strProtocol
,
1556 rtl_uString_getStr(ustrProtocol
),
1557 rtl_uString_getLength(ustrProtocol
),
1558 RTL_TEXTENCODING_UTF8
,
1559 OUSTRING_TO_OSTRING_CVTFLAGS
);
1560 pszProtocol
= rtl_string_getStr(strProtocol
);
1563 nPort
= osl_psz_getServicePort(pszServiceName
,pszProtocol
);
1565 if ( strServicename
!= 0 )
1567 rtl_string_release(strServicename
);
1570 if ( strProtocol
!= 0 )
1572 rtl_string_release(strProtocol
);
1580 sal_Int32 SAL_CALL
osl_psz_getServicePort(const sal_Char
* pszServicename
,
1581 const sal_Char
* pszProtocol
)
1585 ps
= getservbyname(pszServicename
, pszProtocol
);
1588 return ntohs(ps
->s_port
);
1590 return OSL_INVALID_PORT
;
1593 /*****************************************************************************/
1594 /* osl_destroySocketAddr */
1595 /*****************************************************************************/
1596 void SAL_CALL
osl_destroySocketAddr(oslSocketAddr pAddr
)
1598 __osl_destroySocketAddr( pAddr
);
1601 /*****************************************************************************/
1602 /* osl_getFamilyOfSocketAddr */
1603 /*****************************************************************************/
1604 oslAddrFamily SAL_CALL
osl_getFamilyOfSocketAddr(oslSocketAddr pAddr
)
1609 return FAMILY_FROM_NATIVE(pAddr
->m_sockaddr
.sa_family
);
1611 return osl_Socket_FamilyInvalid
;
1614 /*****************************************************************************/
1615 /* osl_getInetPortOfSocketAddr */
1616 /*****************************************************************************/
1617 sal_Int32 SAL_CALL
osl_getInetPortOfSocketAddr(oslSocketAddr pAddr
)
1622 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1624 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1625 return ntohs(pSystemInetAddr
->sin_port
);
1627 return OSL_INVALID_PORT
;
1630 /*****************************************************************************/
1631 /* osl_setInetPortOfSocketAddr */
1632 /*****************************************************************************/
1633 sal_Bool SAL_CALL
osl_setInetPortOfSocketAddr(oslSocketAddr pAddr
, sal_Int32 Port
)
1638 struct sockaddr_in
* pSystemInetAddr
= (struct sockaddr_in
*)&(pAddr
->m_sockaddr
);
1639 if ( pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1641 pSystemInetAddr
->sin_port
= htons((short)Port
);
1646 /* this is not a inet-addr => can't set port */
1650 /*****************************************************************************/
1651 /* osl_getHostnameOfSocketAddr */
1652 /*****************************************************************************/
1653 oslSocketResult SAL_CALL
osl_getHostnameOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrHostname
)
1655 oslSocketResult Result
;
1656 sal_Char pszHostname
[1024];
1658 pszHostname
[0] = '\0';
1660 Result
= osl_psz_getHostnameOfSocketAddr(Addr
,pszHostname
,sizeof(pszHostname
));
1662 rtl_uString_newFromAscii(ustrHostname
,pszHostname
);
1668 oslSocketResult SAL_CALL
osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr
,
1669 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1671 oslHostAddr pHostAddr
= (oslHostAddr
)osl_createHostAddrByAddr(pAddr
);
1675 strncpy(pBuffer
, pHostAddr
->pHostName
, BufferSize
);
1677 pBuffer
[BufferSize
- 1] = '\0';
1679 osl_destroyHostAddr(pHostAddr
);
1681 return osl_Socket_Ok
;
1684 return osl_Socket_Error
;
1687 /*****************************************************************************/
1688 /* osl_getDottedInetAddrOfSocketAddr */
1689 /*****************************************************************************/
1690 oslSocketResult SAL_CALL
osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr
, rtl_uString
**ustrDottedInetAddr
)
1692 oslSocketResult Result
;
1693 sal_Char pszDottedInetAddr
[1024];
1695 pszDottedInetAddr
[0] = '\0';
1697 Result
= osl_psz_getDottedInetAddrOfSocketAddr(Addr
,pszDottedInetAddr
,sizeof(pszDottedInetAddr
));
1699 rtl_uString_newFromAscii(ustrDottedInetAddr
,pszDottedInetAddr
);
1705 oslSocketResult SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr
,
1706 sal_Char
*pBuffer
, sal_uInt32 BufferSize
)
1712 struct sockaddr_in
* pSystemInetAddr
= ( struct sockaddr_in
* ) &(pAddr
->m_sockaddr
);
1714 if (pSystemInetAddr
->sin_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyInet
))
1716 strncpy(pBuffer
, inet_ntoa(pSystemInetAddr
->sin_addr
), BufferSize
);
1717 pBuffer
[BufferSize
- 1] = '\0';
1719 return osl_Socket_Ok
;
1723 return osl_Socket_Error
;
1726 #if 0 /* OBSOLETE */
1727 /*****************************************************************************/
1728 /* osl_getIpxNetNumber */
1729 /*****************************************************************************/
1730 oslSocketResult SAL_CALL
osl_getIpxNetNumber(oslSocketAddr Addr
,
1731 oslSocketIpxNetNumber NetNumber
)
1734 struct sockaddr_ipx
* pAddr
;
1736 pAddr
= (struct sockaddr_ipx
*)Addr
;
1740 if (pAddr
&& (pAddr
->sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyIpx
)))
1742 memcpy(NetNumber
, pAddr
->sa_netnum
, sizeof(NetNumber
));
1744 return osl_Socket_Ok
;
1747 return osl_Socket_Error
;
1751 /*****************************************************************************/
1752 /* osl_getIpxNodeNumber */
1753 /*****************************************************************************/
1754 oslSocketResult SAL_CALL
osl_getIpxNodeNumber(oslSocketAddr Addr
,
1755 oslSocketIpxNodeNumber NodeNumber
)
1758 struct sockaddr_ipx
* pAddr
;
1760 pAddr
= (struct sockaddr_ipx
*)Addr
;
1764 if (pAddr
&& (pAddr
->sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyIpx
)))
1766 memcpy(NodeNumber
, pAddr
->sa_nodenum
, sizeof(NodeNumber
));
1768 return osl_Socket_Ok
;
1771 return osl_Socket_Error
;
1775 /*****************************************************************************/
1776 /* osl_getIpxSocketNumber */
1777 /*****************************************************************************/
1778 sal_Int32 SAL_CALL
osl_getIpxSocketNumber(oslSocketAddr Addr
)
1780 struct sockaddr_ipx
* pAddr
= (struct sockaddr_ipx
*)Addr
;
1783 if (pAddr
&& (pAddr
->sa_family
== FAMILY_TO_NATIVE(osl_Socket_FamilyIpx
)))
1784 return pAddr
->sa_socket
;
1786 return OSL_INVALID_IPX_SOCKET_NO
;
1789 #endif /* OBSOLETE */
1791 /*****************************************************************************/
1792 /* osl_createSocket */
1793 /*****************************************************************************/
1794 oslSocket SAL_CALL
osl_createSocket(oslAddrFamily Family
,
1796 oslProtocol Protocol
)
1802 pSocket
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
1805 pSocket
->m_Socket
= socket(FAMILY_TO_NATIVE(Family
),
1806 TYPE_TO_NATIVE(Type
),
1807 PROTOCOL_TO_NATIVE(Protocol
));
1809 /* creation failed => free memory */
1810 if(pSocket
->m_Socket
== OSL_INVALID_SOCKET
)
1812 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1816 __osl_destroySocketImpl((pSocket
));
1821 /* set close-on-exec flag */
1822 if ((Flags
= fcntl(pSocket
->m_Socket
, F_GETFD
, 0)) != -1)
1824 Flags
|= FD_CLOEXEC
;
1825 if (fcntl(pSocket
->m_Socket
, F_SETFD
, Flags
) == -1)
1827 pSocket
->m_nLastError
=errno
;
1828 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1835 pSocket
->m_nLastError
=errno
;
1839 pSocket
->m_CloseCallback
= NULL
;
1840 pSocket
->m_CallbackArg
= NULL
;
1846 void SAL_CALL
osl_acquireSocket(oslSocket pSocket
)
1848 osl_incrementInterlockedCount( &(pSocket
->m_nRefCount
) );
1851 void SAL_CALL
osl_releaseSocket( oslSocket pSocket
)
1853 if( pSocket
&& 0 == osl_decrementInterlockedCount( &(pSocket
->m_nRefCount
) ) )
1856 if ( pSocket
->m_bIsAccepting
== sal_True
)
1858 OSL_ENSURE(0, "osl_destroySocket : attempt to destroy socket while accepting\n");
1862 osl_closeSocket( pSocket
);
1863 __osl_destroySocketImpl( pSocket
);
1869 /*****************************************************************************/
1870 /* osl_closeSocket */
1871 /*****************************************************************************/
1872 void SAL_CALL
osl_closeSocket(oslSocket pSocket
)
1877 /* socket already invalid */
1881 pSocket
->m_nLastError
=0;
1882 nFD
= pSocket
->m_Socket
;
1884 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1887 pSocket
->m_bIsInShutdown
= sal_True
;
1889 if ( pSocket
->m_bIsAccepting
== sal_True
)
1892 struct sockaddr aSockAddr
;
1893 socklen_t nSockLen
= sizeof(aSockAddr
);
1895 nRet
= getsockname(nFD
, &aSockAddr
, &nSockLen
);
1896 #if OSL_DEBUG_LEVEL > 1
1899 perror("getsockname");
1901 #endif /* OSL_DEBUG_LEVEL */
1903 if ( aSockAddr
.sa_family
== AF_INET
)
1905 struct sockaddr_in
* pSockAddrIn
= (struct sockaddr_in
*) &aSockAddr
;
1907 if ( pSockAddrIn
->sin_addr
.s_addr
== htonl(INADDR_ANY
) )
1909 pSockAddrIn
->sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1912 nConnFD
= socket(AF_INET
, SOCK_STREAM
, 0);
1913 #if OSL_DEBUG_LEVEL > 1
1918 #endif /* OSL_DEBUG_LEVEL */
1920 nRet
= connect(nConnFD
, &aSockAddr
, sizeof(aSockAddr
));
1921 #if OSL_DEBUG_LEVEL > 1
1926 #endif /* OSL_DEBUG_LEVEL */
1932 /* registrierten Callback ausfuehren */
1933 if (pSocket
->m_CloseCallback
!= NULL
)
1935 pSocket
->m_CloseCallback(pSocket
->m_CallbackArg
);
1941 pSocket
->m_nLastError
=errno
;
1942 OSL_TRACE("closeSocket close error '%s'\n",strerror(errno
));
1945 pSocket
->m_Socket
= OSL_INVALID_SOCKET
;
1948 /*****************************************************************************/
1949 /* osl_getLocalAddrOfSocket */
1950 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1951 /* are the same! I don't like it very much but see no other easy way to conceal */
1952 /* the struct sockaddr from the eyes of the user. */
1953 /*****************************************************************************/
1954 oslSocketAddr SAL_CALL
osl_getLocalAddrOfSocket(oslSocket pSocket
)
1956 #if defined(LINUX) || defined(FREEBSD)
1959 /* mfe: Solaris 'cc +w' means Addrlen should be signed! */
1960 /* it's really defined as 'int*' in /usr/include/sys/socket.h! */
1961 /* the man page says it expects a 'size_t' */
1964 struct sockaddr Addr
;
1965 oslSocketAddr pAddr
;
1967 if (pSocket
== NULL
) /* ENOTSOCK */
1968 return ((oslSocketAddr
)NULL
);
1970 AddrLen
= sizeof(struct sockaddr
);
1972 if (getsockname(pSocket
->m_Socket
, &Addr
, PTR_SIZE_T(AddrLen
)) == OSL_SOCKET_ERROR
)
1973 return ((oslSocketAddr
)NULL
);
1975 pAddr
= __osl_createSocketAddrFromSystem( &Addr
);
1979 /*****************************************************************************/
1980 /* osl_getPeerAddrOfSocket */
1981 /*****************************************************************************/
1982 oslSocketAddr SAL_CALL
osl_getPeerAddrOfSocket(oslSocket pSocket
)
1985 struct sockaddr Addr
;
1987 OSL_ASSERT(pSocket
);
1993 pSocket
->m_nLastError
=0;
1994 AddrLen
= sizeof(struct sockaddr
);
1996 if(getpeername(pSocket
->m_Socket
, &Addr
, (int*)PTR_SIZE_T(AddrLen
)) == OSL_SOCKET_ERROR
)
1998 pSocket
->m_nLastError
=errno
;
2001 return __osl_createSocketAddrFromSystem( &Addr
);
2004 /*****************************************************************************/
2005 /* osl_bindAddrToSocket */
2006 /*****************************************************************************/
2007 sal_Bool SAL_CALL
osl_bindAddrToSocket(oslSocket pSocket
,
2008 oslSocketAddr pAddr
)
2012 OSL_ASSERT(pSocket
&& pAddr
);
2013 if ( pSocket
== 0 || pAddr
== 0 )
2018 pSocket
->m_nLastError
=0;
2020 nRet
= bind(pSocket
->m_Socket
, &(pAddr
->m_sockaddr
), sizeof(struct sockaddr
));
2022 if ( nRet
== OSL_SOCKET_ERROR
)
2024 pSocket
->m_nLastError
=errno
;
2032 /*****************************************************************************/
2033 /* osl_listenOnSocket */
2034 /*****************************************************************************/
2035 sal_Bool SAL_CALL
osl_listenOnSocket(oslSocket pSocket
,
2036 sal_Int32 MaxPendingConnections
)
2040 OSL_ASSERT(pSocket
);
2046 pSocket
->m_nLastError
=0;
2048 nRet
= listen(pSocket
->m_Socket
,
2049 MaxPendingConnections
== -1 ?
2051 MaxPendingConnections
);
2052 if ( nRet
== OSL_SOCKET_ERROR
)
2054 pSocket
->m_nLastError
=errno
;
2062 /*****************************************************************************/
2063 /* osl_connectSocketTo */
2064 /*****************************************************************************/
2065 oslSocketResult SAL_CALL
osl_connectSocketTo(oslSocket pSocket
,
2066 oslSocketAddr pAddr
,
2067 const TimeValue
* pTimeout
)
2073 oslSocketResult Result
= osl_Socket_Ok
;
2075 OSL_PRECOND(pSocket
, "osl_connectSocketTo(): need a valid socket!\n");
2079 return osl_Socket_Error
;
2082 pSocket
->m_nLastError
=0;
2084 if (osl_isNonBlockingMode(pSocket
))
2086 if (connect(pSocket
->m_Socket
,
2087 &(pAddr
->m_sockaddr
),
2088 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
2089 return osl_Socket_Ok
;
2091 if (errno
== EWOULDBLOCK
|| errno
== EINPROGRESS
)
2093 pSocket
->m_nLastError
=EINPROGRESS
;
2094 return osl_Socket_InProgress
;
2098 pSocket
->m_nLastError
=errno
;
2099 OSL_TRACE("can't connect : '%s'",strerror(errno
));
2100 return osl_Socket_Error
;
2103 /* set socket temporarily to non-blocking */
2104 OSL_VERIFY(osl_enableNonBlockingMode(pSocket
, sal_True
));
2106 /* initiate connect */
2107 if(connect(pSocket
->m_Socket
,
2108 &(pAddr
->m_sockaddr
),
2109 sizeof(struct sockaddr
)) != OSL_SOCKET_ERROR
)
2111 /* immediate connection */
2112 osl_enableNonBlockingMode(pSocket
, sal_False
);
2114 return osl_Socket_Ok
;
2118 /* really an error or just delayed? */
2119 if (errno
!= EINPROGRESS
)
2121 pSocket
->m_nLastError
=errno
;
2123 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
2124 errno
, strerror(errno
));
2126 osl_enableNonBlockingMode(pSocket
, sal_False
);
2127 return osl_Socket_Error
;
2132 /* prepare select set for socket */
2135 FD_SET(pSocket
->m_Socket
, &WriteSet
);
2136 FD_SET(pSocket
->m_Socket
, &ExcptSet
);
2138 /* prepare timeout */
2141 /* divide milliseconds into seconds and microseconds */
2142 tv
.tv_sec
= pTimeout
->Seconds
;
2143 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
2147 ReadyHandles
= select(pSocket
->m_Socket
+1,
2149 PTR_FD_SET(WriteSet
),
2150 PTR_FD_SET(ExcptSet
),
2151 (pTimeout
) ? &tv
: 0);
2153 if (ReadyHandles
> 0) /* connected */
2155 if ( FD_ISSET(pSocket
->m_Socket
, &WriteSet
) )
2159 /* mfe: Solaris 'cc +w' means 5th argument should be a 'int*'!
2160 it's really defined as 'int*' in /usr/include/sys/socket.h!
2161 the man page says it expects a 'size_t*'
2163 int nErrorSize
= sizeof( nErrorCode
);
2165 size_t nErrorSize
= sizeof( nErrorCode
);
2170 nSockOpt
= getsockopt ( pSocket
->m_Socket
, SOL_SOCKET
, SO_ERROR
,
2172 /* mfe: Solaris 'cc +w' means 4th argument should be a 'char*'!
2173 it's really defined as 'char*' in /usr/include/sys/socket.h!
2174 the man page says it expects a 'void*'
2178 &nErrorCode
, (int*)&nErrorSize
);
2179 if ( (nSockOpt
== 0) && (nErrorCode
== 0))
2180 Result
= osl_Socket_Ok
;
2182 Result
= osl_Socket_Error
;
2186 Result
= osl_Socket_Error
;
2189 else if (ReadyHandles
< 0) /* error */
2191 if (errno
== EBADF
) /* most probably interrupted by close() */
2193 /* do not access pSockImpl because it is about to be or */
2194 /* already destroyed */
2195 return osl_Socket_Interrupted
;
2199 pSocket
->m_nLastError
=errno
;
2200 Result
= osl_Socket_Error
;
2205 pSocket
->m_nLastError
=errno
;
2206 Result
= osl_Socket_TimedOut
;
2209 osl_enableNonBlockingMode(pSocket
, sal_False
);
2215 /*****************************************************************************/
2216 /* osl_acceptConnectionOnSocket */
2217 /*****************************************************************************/
2218 oslSocket SAL_CALL
osl_acceptConnectionOnSocket(oslSocket pSocket
,
2219 oslSocketAddr
* ppAddr
)
2221 struct sockaddr Addr
;
2222 int Connection
, Flags
;
2223 sal_uInt32 AddrLen
= sizeof(struct sockaddr
);
2224 oslSocket pConnectionSockImpl
;
2226 OSL_ASSERT(pSocket
);
2232 pSocket
->m_nLastError
=0;
2234 pSocket
->m_bIsAccepting
= sal_True
;
2237 if( ppAddr
&& *ppAddr
)
2239 osl_destroySocketAddr( *ppAddr
);
2243 /* prevent Linux EINTR behaviour */
2246 Connection
= accept(pSocket
->m_Socket
, &Addr
, (int*)PTR_SIZE_T(AddrLen
));
2247 } while (Connection
== -1 && errno
== EINTR
);
2250 /* accept failed? */
2251 if( Connection
== OSL_SOCKET_ERROR
)
2253 pSocket
->m_nLastError
=errno
;
2254 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'\n",strerror(errno
));
2257 pSocket
->m_bIsAccepting
= sal_False
;
2262 OSL_ASSERT(AddrLen
== sizeof(struct sockaddr
));
2266 if ( pSocket
->m_bIsInShutdown
== sal_True
)
2269 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept\n");
2277 *ppAddr
= __osl_createSocketAddrFromSystem(&Addr
);
2281 pConnectionSockImpl
= __osl_createSocketImpl(OSL_INVALID_SOCKET
);
2283 /* set close-on-exec flag */
2284 if ((Flags
= fcntl(Connection
, F_GETFD
, 0)) != -1)
2286 Flags
|= FD_CLOEXEC
;
2287 if (fcntl(Connection
, F_SETFD
, Flags
) == -1)
2289 pSocket
->m_nLastError
=errno
;
2290 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
2297 pConnectionSockImpl
->m_Socket
= Connection
;
2298 pConnectionSockImpl
->m_nLastError
= 0;
2299 pConnectionSockImpl
->m_CloseCallback
= NULL
;
2300 pConnectionSockImpl
->m_CallbackArg
= NULL
;
2302 pConnectionSockImpl
->m_bIsAccepting
= sal_False
;
2304 pSocket
->m_bIsAccepting
= sal_False
;
2306 return pConnectionSockImpl
;
2309 /*****************************************************************************/
2310 /* osl_receiveSocket */
2311 /*****************************************************************************/
2312 sal_Int32 SAL_CALL
osl_receiveSocket(oslSocket pSocket
,
2314 sal_uInt32 BytesToRead
,
2315 oslSocketMsgFlag Flag
)
2319 OSL_ASSERT(pSocket
);
2322 OSL_TRACE("osl_receiveSocket : Invalid socket");
2326 pSocket
->m_nLastError
=0;
2330 nRead
= recv(pSocket
->m_Socket
,
2333 MSG_FLAG_TO_NATIVE(Flag
));
2334 } while ( nRead
< 0 && errno
== EINTR
);
2338 pSocket
->m_nLastError
=errno
;
2339 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,strerror(errno
));
2341 else if ( nRead
== 0 )
2343 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
2350 /*****************************************************************************/
2351 /* osl_receiveFromSocket */
2352 /*****************************************************************************/
2353 sal_Int32 SAL_CALL
osl_receiveFromSocket(oslSocket pSocket
,
2354 oslSocketAddr pSenderAddr
,
2356 sal_uInt32 BufferSize
,
2357 oslSocketMsgFlag Flag
)
2360 struct sockaddr
*pSystemSockAddr
= 0;
2364 AddrLen
= sizeof( struct sockaddr
);
2365 pSystemSockAddr
= &(pSenderAddr
->m_sockaddr
);
2368 OSL_ASSERT(pSocket
);
2371 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
2375 pSocket
->m_nLastError
=0;
2377 nRead
= recvfrom(pSocket
->m_Socket
,
2380 MSG_FLAG_TO_NATIVE(Flag
),
2382 PTR_SIZE_T(AddrLen
));
2386 pSocket
->m_nLastError
=errno
;
2387 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead
,strerror(errno
));
2389 else if ( nRead
== 0 )
2391 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead
,"EOL");
2398 /*****************************************************************************/
2399 /* osl_sendSocket */
2400 /*****************************************************************************/
2401 sal_Int32 SAL_CALL
osl_sendSocket(oslSocket pSocket
,
2402 const void* pBuffer
,
2403 sal_uInt32 BytesToSend
,
2404 oslSocketMsgFlag Flag
)
2408 OSL_ASSERT(pSocket
);
2411 OSL_TRACE("osl_sendSocket : Invalid socket");
2415 pSocket
->m_nLastError
=0;
2419 nWritten
= send(pSocket
->m_Socket
,
2422 MSG_FLAG_TO_NATIVE(Flag
));
2423 } while ( nWritten
< 0 && errno
== EINTR
);
2428 pSocket
->m_nLastError
=errno
;
2429 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,strerror(errno
));
2431 else if ( nWritten
== 0 )
2433 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten
,"EOL");
2439 /*****************************************************************************/
2440 /* osl_sendToSocket */
2441 /*****************************************************************************/
2442 sal_Int32 SAL_CALL
osl_sendToSocket(oslSocket pSocket
,
2443 oslSocketAddr ReceiverAddr
,
2444 const void* pBuffer
,
2445 sal_uInt32 BytesToSend
,
2446 oslSocketMsgFlag Flag
)
2450 struct sockaddr
*pSystemSockAddr
= 0;
2454 pSystemSockAddr
= &(ReceiverAddr
->m_sockaddr
);
2455 AddrLen
= sizeof( struct sockaddr
);
2458 OSL_ASSERT(pSocket
);
2461 OSL_TRACE("osl_sendToSocket : Invalid socket");
2465 pSocket
->m_nLastError
=0;
2467 /* ReceiverAddr might be 0 when used on a connected socket. */
2468 /* Then sendto should behave like send. */
2470 nWritten
= sendto(pSocket
->m_Socket
,
2473 MSG_FLAG_TO_NATIVE(Flag
),
2479 pSocket
->m_nLastError
=errno
;
2480 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,strerror(errno
));
2482 else if ( nWritten
== 0 )
2484 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten
,"EOL");
2490 /*****************************************************************************/
2491 /* osl_readSocket */
2492 /*****************************************************************************/
2493 sal_Int32 SAL_CALL
osl_readSocket (
2494 oslSocket pSocket
, void *pBuffer
, sal_Int32 n
)
2496 sal_uInt8
* Ptr
= (sal_uInt8
*)pBuffer
;
2497 sal_uInt32 BytesRead
= 0;
2498 sal_uInt32 BytesToRead
= n
;
2500 OSL_ASSERT( pSocket
);
2502 /* loop until all desired bytes were read or an error occured */
2503 while (BytesToRead
> 0)
2506 RetVal
= osl_receiveSocket(pSocket
,
2509 osl_Socket_MsgNormal
);
2511 /* error occured? */
2517 BytesToRead
-= RetVal
;
2518 BytesRead
+= RetVal
;
2525 /*****************************************************************************/
2526 /* osl_writeSocket */
2527 /*****************************************************************************/
2528 sal_Int32 SAL_CALL
osl_writeSocket(
2529 oslSocket pSocket
, const void *pBuffer
, sal_Int32 n
)
2531 /* loop until all desired bytes were send or an error occured */
2532 sal_uInt32 BytesSend
= 0;
2533 sal_uInt32 BytesToSend
= n
;
2534 sal_uInt8
*Ptr
= ( sal_uInt8
* )pBuffer
;
2536 OSL_ASSERT( pSocket
);
2538 while (BytesToSend
> 0)
2542 RetVal
= osl_sendSocket( pSocket
,Ptr
,BytesToSend
,osl_Socket_MsgNormal
);
2544 /* error occured? */
2550 BytesToSend
-= RetVal
;
2551 BytesSend
+= RetVal
;
2558 /*****************************************************************************/
2559 /* __osl_socket_poll */
2560 /*****************************************************************************/
2562 #ifdef HAVE_POLL_H /* poll() */
2564 sal_Bool
__osl_socket_poll (
2566 const TimeValue
* pTimeout
,
2573 OSL_ASSERT(pSocket
);
2574 pSocket
->m_nLastError
= 0;
2576 fds
.fd
= pSocket
->m_Socket
;
2577 fds
.events
= nEvent
;
2583 /* Convert to [ms] */
2584 timeout
= pTimeout
->Seconds
* 1000;
2585 timeout
+= pTimeout
->Nanosec
/ (1000 * 1000);
2588 result
= poll (&fds
, 1, timeout
);
2591 pSocket
->m_nLastError
= errno
;
2592 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2593 errno
, strerror(errno
));
2602 return ((fds
.revents
& nEvent
) == nEvent
);
2605 #else /* select() */
2607 sal_Bool
__osl_socket_poll (
2609 const TimeValue
* pTimeout
,
2616 OSL_ASSERT(pSocket
);
2617 pSocket
->m_nLastError
= 0;
2620 FD_SET(pSocket
->m_Socket
, &fds
);
2624 /* Convert to 'timeval' */
2625 tv
.tv_sec
= pTimeout
->Seconds
;
2626 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000;
2630 pSocket
->m_Socket
+ 1,
2631 (nEvent
== POLLIN
) ? PTR_FD_SET(fds
) : NULL
,
2632 (nEvent
== POLLOUT
) ? PTR_FD_SET(fds
) : NULL
,
2633 (nEvent
== POLLPRI
) ? PTR_FD_SET(fds
) : NULL
,
2634 (pTimeout
) ? &tv
: NULL
);
2638 pSocket
->m_nLastError
= errno
;
2639 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2640 errno
, strerror(errno
));
2649 return (FD_ISSET(pSocket
->m_Socket
, &fds
) ? sal_True
: sal_False
);
2652 #endif /* HAVE_POLL_H */
2654 /*****************************************************************************/
2655 /* osl_isReceiveReady */
2656 /*****************************************************************************/
2657 sal_Bool SAL_CALL
osl_isReceiveReady (
2658 oslSocket pSocket
, const TimeValue
* pTimeout
)
2660 OSL_ASSERT(pSocket
);
2661 if (pSocket
== NULL
)
2667 return __osl_socket_poll (pSocket
, pTimeout
, POLLIN
);
2670 /*****************************************************************************/
2671 /* osl_isSendReady */
2672 /*****************************************************************************/
2673 sal_Bool SAL_CALL
osl_isSendReady (
2674 oslSocket pSocket
, const TimeValue
* pTimeout
)
2676 OSL_ASSERT(pSocket
);
2677 if (pSocket
== NULL
)
2683 return __osl_socket_poll (pSocket
, pTimeout
, POLLOUT
);
2686 /*****************************************************************************/
2687 /* osl_isExceptionPending */
2688 /*****************************************************************************/
2689 sal_Bool SAL_CALL
osl_isExceptionPending (
2690 oslSocket pSocket
, const TimeValue
* pTimeout
)
2692 OSL_ASSERT(pSocket
);
2693 if (pSocket
== NULL
)
2699 return __osl_socket_poll (pSocket
, pTimeout
, POLLPRI
);
2702 /*****************************************************************************/
2703 /* osl_shutdownSocket */
2704 /*****************************************************************************/
2705 sal_Bool SAL_CALL
osl_shutdownSocket(oslSocket pSocket
,
2706 oslSocketDirection Direction
)
2710 OSL_ASSERT(pSocket
);
2716 pSocket
->m_nLastError
=0;
2718 nRet
=shutdown(pSocket
->m_Socket
, DIRECTION_TO_NATIVE(Direction
));
2721 pSocket
->m_nLastError
=errno
;
2722 OSL_TRACE("shutdown error '%s'\n",strerror(errno
));
2728 /*****************************************************************************/
2729 /* osl_getSocketOption */
2730 /*****************************************************************************/
2731 sal_Int32 SAL_CALL
osl_getSocketOption(oslSocket pSocket
,
2732 oslSocketOptionLevel Level
,
2733 oslSocketOption Option
,
2735 sal_uInt32 BufferLen
)
2737 OSL_ASSERT(pSocket
);
2743 pSocket
->m_nLastError
=0;
2745 if(getsockopt(pSocket
->m_Socket
,
2746 OPTION_LEVEL_TO_NATIVE(Level
),
2747 OPTION_TO_NATIVE(Option
),
2749 (int*)PTR_SIZE_T(BufferLen
)) == -1)
2751 pSocket
->m_nLastError
=errno
;
2758 /*****************************************************************************/
2759 /* osl_setSocketOption */
2760 /*****************************************************************************/
2761 sal_Bool SAL_CALL
osl_setSocketOption(oslSocket pSocket
,
2762 oslSocketOptionLevel Level
,
2763 oslSocketOption Option
,
2765 sal_uInt32 BufferLen
)
2769 OSL_ASSERT(pSocket
);
2775 pSocket
->m_nLastError
=0;
2777 nRet
= setsockopt(pSocket
->m_Socket
,
2778 OPTION_LEVEL_TO_NATIVE(Level
),
2779 OPTION_TO_NATIVE(Option
),
2785 pSocket
->m_nLastError
=errno
;
2792 /*****************************************************************************/
2793 /* osl_enableNonBlockingMode */
2794 /*****************************************************************************/
2795 sal_Bool SAL_CALL
osl_enableNonBlockingMode(oslSocket pSocket
,
2801 OSL_ASSERT(pSocket
);
2807 pSocket
->m_nLastError
=0;
2809 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2812 flags
|= O_NONBLOCK
;
2814 flags
&= ~(O_NONBLOCK
);
2816 nRet
= fcntl(pSocket
->m_Socket
, F_SETFL
, flags
);
2820 pSocket
->m_nLastError
=errno
;
2827 /*****************************************************************************/
2828 /* osl_isNonBlockingMode */
2829 /*****************************************************************************/
2830 sal_Bool SAL_CALL
osl_isNonBlockingMode(oslSocket pSocket
)
2834 OSL_ASSERT(pSocket
);
2840 pSocket
->m_nLastError
=0;
2842 flags
= fcntl(pSocket
->m_Socket
, F_GETFL
, 0);
2844 if (flags
== -1 || !(flags
& O_NONBLOCK
))
2850 /*****************************************************************************/
2851 /* osl_getSocketType */
2852 /*****************************************************************************/
2853 oslSocketType SAL_CALL
osl_getSocketType(oslSocket pSocket
)
2856 sal_uInt32 TypeSize
= sizeof(Type
);
2858 OSL_ASSERT(pSocket
);
2861 return osl_Socket_TypeInvalid
;
2864 pSocket
->m_nLastError
=0;
2866 if(getsockopt(pSocket
->m_Socket
,
2867 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket
),
2868 OPTION_TO_NATIVE(osl_Socket_OptionType
),
2870 (int*)PTR_SIZE_T(TypeSize
)) == -1)
2873 pSocket
->m_nLastError
=errno
;
2874 return osl_Socket_TypeInvalid
;
2877 return TYPE_FROM_NATIVE(Type
);
2881 /*****************************************************************************/
2882 /* osl_getLastSocketErrorDescription */
2883 /*****************************************************************************/
2884 void SAL_CALL
osl_getLastSocketErrorDescription(oslSocket Socket
, rtl_uString
**ustrError
)
2886 sal_Char pszError
[1024];
2890 osl_psz_getLastSocketErrorDescription(Socket
,pszError
,sizeof(pszError
));
2892 rtl_uString_newFromAscii(ustrError
,pszError
);
2898 void SAL_CALL
osl_psz_getLastSocketErrorDescription(oslSocket pSocket
, sal_Char
* pBuffer
, sal_uInt32 BufferSize
)
2900 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2901 pBuffer
[BufferSize
-1]= '\0';
2905 strncpy(pBuffer
, strerror(EINVAL
), BufferSize
-1);
2909 strncpy(pBuffer
, strerror(pSocket
->m_nLastError
), BufferSize
-1);
2913 /*****************************************************************************/
2914 /* osl_getLastSocketError */
2915 /*****************************************************************************/
2916 oslSocketError SAL_CALL
osl_getLastSocketError(oslSocket pSocket
)
2920 return ERROR_FROM_NATIVE(EINVAL
);
2923 return ERROR_FROM_NATIVE(pSocket
->m_nLastError
);
2926 /*****************************************************************************/
2928 /*****************************************************************************/
2929 typedef struct _TSocketSetImpl
2931 int m_MaxHandle
; /* for select(), the largest descriptor in the set */
2932 fd_set m_Set
; /* the set of descriptors */
2936 /*****************************************************************************/
2937 /* osl_createSocketSet */
2938 /*****************************************************************************/
2939 oslSocketSet SAL_CALL
osl_createSocketSet()
2941 TSocketSetImpl
* pSet
;
2943 pSet
= (TSocketSetImpl
*)malloc(sizeof(TSocketSetImpl
));
2949 pSet
->m_MaxHandle
= 0;
2950 FD_ZERO(&pSet
->m_Set
);
2953 return (oslSocketSet
)pSet
;
2956 /*****************************************************************************/
2957 /* osl_destroySocketSet */
2958 /*****************************************************************************/
2959 void SAL_CALL
osl_destroySocketSet(oslSocketSet Set
)
2965 /*****************************************************************************/
2966 /* osl_clearSocketSet */
2967 /*****************************************************************************/
2968 void SAL_CALL
osl_clearSocketSet(oslSocketSet Set
)
2970 TSocketSetImpl
* pSet
;
2977 pSet
= (TSocketSetImpl
*)Set
;
2978 pSet
->m_MaxHandle
= 0;
2980 FD_ZERO(&pSet
->m_Set
);
2983 /*****************************************************************************/
2984 /* osl_addToSocketSet */
2985 /*****************************************************************************/
2986 void SAL_CALL
osl_addToSocketSet(oslSocketSet Set
, oslSocket pSocket
)
2988 TSocketSetImpl
* pSet
;
2991 OSL_ASSERT(pSocket
);
2993 if ( Set
== 0 || pSocket
== 0)
2998 pSet
= (TSocketSetImpl
*)Set
;
3000 /* correct max handle */
3001 if(pSocket
->m_Socket
> pSet
->m_MaxHandle
)
3002 pSet
->m_MaxHandle
= pSocket
->m_Socket
;
3003 FD_SET(pSocket
->m_Socket
, &pSet
->m_Set
);
3007 /*****************************************************************************/
3008 /* osl_removeFromSocketSet */
3009 /*****************************************************************************/
3010 void SAL_CALL
osl_removeFromSocketSet(oslSocketSet Set
, oslSocket pSocket
)
3012 TSocketSetImpl
* pSet
;
3015 OSL_ASSERT(pSocket
);
3017 if ( Set
== 0 || pSocket
== 0)
3022 pSet
= (TSocketSetImpl
*)Set
;
3024 /* correct max handle */
3025 if(pSocket
->m_Socket
== pSet
->m_MaxHandle
)
3027 /* not optimal, since the next used descriptor might be */
3028 /* much smaller than m_Socket-1, but it will do */
3029 pSet
->m_MaxHandle
--;
3030 if(pSet
->m_MaxHandle
< 0)
3032 pSet
->m_MaxHandle
= 0; /* avoid underflow */
3036 FD_CLR(pSocket
->m_Socket
, &pSet
->m_Set
);
3039 /*****************************************************************************/
3040 /* osl_isInSocketSet */
3041 /*****************************************************************************/
3042 sal_Bool SAL_CALL
osl_isInSocketSet(oslSocketSet Set
, oslSocket pSocket
)
3044 TSocketSetImpl
* pSet
;
3047 OSL_ASSERT(pSocket
);
3048 if ( Set
== 0 || pSocket
== 0 )
3053 pSet
= (TSocketSetImpl
*)Set
;
3055 return (FD_ISSET(pSocket
->m_Socket
, &pSet
->m_Set
) != 0);
3058 /*****************************************************************************/
3059 /* osl_demultiplexSocketEvents */
3060 /*****************************************************************************/
3061 sal_Int32 SAL_CALL
osl_demultiplexSocketEvents(oslSocketSet IncomingSet
,
3062 oslSocketSet OutgoingSet
,
3063 oslSocketSet OutOfBandSet
,
3064 const TimeValue
* pTimeout
)
3068 TSocketSetImpl
* pInSet
;
3069 TSocketSetImpl
* pOutSet
;
3070 TSocketSetImpl
* pOOBSet
;
3074 /* non-blocking call */
3075 tv
.tv_sec
= pTimeout
->Seconds
;
3076 tv
.tv_usec
= pTimeout
->Nanosec
/ 1000L;
3079 /* map opaque data to impl-types */
3080 pInSet
= (TSocketSetImpl
*)IncomingSet
;
3081 pOutSet
= (TSocketSetImpl
*)OutgoingSet
;
3082 pOOBSet
= (TSocketSetImpl
*)OutOfBandSet
;
3084 /* get max handle from all sets */
3086 MaxHandle
= pInSet
->m_MaxHandle
;
3088 if (pOutSet
&& (pOutSet
->m_MaxHandle
> MaxHandle
))
3089 MaxHandle
= pOutSet
->m_MaxHandle
;
3091 if (pOOBSet
&& (pOOBSet
->m_MaxHandle
> MaxHandle
))
3092 MaxHandle
= pOOBSet
->m_MaxHandle
;
3094 return select(MaxHandle
+1,
3095 pInSet
? PTR_FD_SET(pInSet
->m_Set
) : 0,
3096 pOutSet
? PTR_FD_SET(pOutSet
->m_Set
) : 0,
3097 pOOBSet
? PTR_FD_SET(pOOBSet
->m_Set
) : 0,
3098 pTimeout
? &tv
: 0);