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