bump product version to 4.1.6.2
[LibreOffice.git] / sal / osl / unx / socket.c
blobd2e928dec7af6703dad629c99f060a26e5f2ca3a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "system.h"
22 #include <osl/socket.h>
23 #include <osl/diagnose.h>
24 #include <osl/mutex.h>
25 #include <osl/signal.h>
27 #include <rtl/alloc.h>
29 #include <ctype.h>
30 #include <sal/types.h>
32 #include "sockimpl.h"
34 /* defines for poll */
35 #ifdef HAVE_POLL_H
36 #undef HAVE_POLL_H
37 #endif
39 #if defined(LINUX) || defined(NETBSD) || defined ( FREEBSD ) || \
40 defined (MACOSX) || defined (OPENBSD) || defined(DRAGONFLY)
41 #include <sys/poll.h>
42 #define HAVE_POLL_H
43 #endif /* HAVE_POLL_H */
45 #if defined(SOLARIS)
46 #include <poll.h>
47 #define HAVE_POLL_H
48 #endif /* SOLARIS */
50 #ifndef HAVE_POLL_H
51 #define POLLIN 0x0001
52 #define POLLOUT 0x0002
53 #define POLLPRI 0x0004
54 #endif /* HAVE_POLL_H */
57 /* defines for shutdown */
58 #define SD_RECEIVE 0
59 #define SD_SEND 1
60 #define SD_BOTH 2
64 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
65 I refrained from using sockaddr_in because of possible further
66 extensions of this socket-interface (IP-NG?).
67 The intention was to hide all Berkeley data-structures from
68 direct access past the osl-interface.
70 The current implementation is internet (IP) centered. All
71 the constructor-functions (osl_create...) take parameters
72 that will probably make sense only in the IP-environment
73 (e.g. because of using the dotted-address-format).
75 If the interface will be extended to host other protocol-
76 families, I expect no externally visible changes in the
77 existing functions. You'll probably need only new
78 constructor-functions who take the different address
79 formats into consideration (maybe a long dotted address
80 or whatever).
83 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
84 /* are the same! I don't like it very much but see no other easy way to */
85 /* conceal the struct sockaddr from the eyes of the user. */
88 #define OSL_INVALID_SOCKET -1
89 #define OSL_SOCKET_ERROR -1
92 /* Buffer size for gethostbyname */
93 #define MAX_HOSTBUFFER_SIZE 2048
95 /*****************************************************************************/
96 /* enum oslAddrFamily */
97 /*****************************************************************************/
99 /* map */
100 static unsigned long FamilyMap[]= {
101 AF_INET, /* osl_Socket_FamilyInet */
102 AF_IPX, /* osl_Socket_FamilyIpx */
103 0 /* osl_Socket_FamilyInvalid */
106 /* reverse map */
107 static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
109 oslAddrFamily i= (oslAddrFamily)0;
111 while(i != osl_Socket_FamilyInvalid)
113 if(FamilyMap[i] == nativeType)
114 return i;
115 i = (oslAddrFamily) ( i + 1 );
118 return i;
121 /* macros */
122 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
123 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
125 /*****************************************************************************/
126 /* enum oslProtocol */
127 /*****************************************************************************/
129 /* map */
130 static sal_uInt32 ProtocolMap[]= {
131 0, /* osl_Socket_ProtocolIp */
132 NSPROTO_IPX, /* osl_Socket_ProtocolIpx */
133 NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
134 NSPROTO_SPXII, /* osl_Socket_ProtocolSpxII */
135 0 /* osl_Socket_ProtocolInvalid */
138 /* reverse map */
139 /* mfe: NOT USED
140 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
142 oslProtocol i= (oslProtocol)0;
144 while(i != osl_Socket_ProtocolInvalid)
146 if(ProtocolMap[i] == nativeType)
147 return i;
148 i = (oslProtocol) ( i + 1);
151 return i;
155 /* macros */
156 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
159 /*****************************************************************************/
160 /* enum oslSocketType */
161 /*****************************************************************************/
163 /* map */
164 static sal_uInt32 TypeMap[]= {
165 SOCK_STREAM, /* osl_Socket_TypeStream */
166 SOCK_DGRAM, /* osl_Socket_TypeDgram */
167 SOCK_RAW, /* osl_Socket_TypeRaw */
168 SOCK_RDM, /* osl_Socket_TypeRdm */
169 SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
170 0 /* osl_Socket_TypeInvalid */
173 /* reverse map */
174 static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
176 oslSocketType i= (oslSocketType)0;
178 while(i != osl_Socket_TypeInvalid)
180 if(TypeMap[i] == nativeType)
181 return i;
182 i = (oslSocketType)(i + 1);
185 return i;
188 /* macros */
189 #define TYPE_TO_NATIVE(x) TypeMap[x]
190 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
193 /*****************************************************************************/
194 /* enum oslSocketOption */
195 /*****************************************************************************/
197 /* map */
198 static sal_uInt32 OptionMap[]= {
199 SO_DEBUG, /* osl_Socket_OptionDebug */
200 SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
201 SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
202 SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
203 SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
204 SO_BROADCAST, /* osl_Socket_OptionBroadcast */
205 SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
206 SO_LINGER, /* osl_Socket_OptionLinger */
207 SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
208 SO_SNDBUF, /* osl_Socket_OptionSndBuf */
209 SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
210 SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
211 SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
212 SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
213 SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
214 SO_ERROR, /* osl_Socket_OptionError */
215 SO_TYPE, /* osl_Socket_OptionType */
216 TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
217 0 /* osl_Socket_OptionInvalid */
220 /* reverse map */
221 /* mfe: NOT USED
222 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
224 oslSocketOption i= (oslSocketOption)0;
226 while(i != osl_Socket_OptionInvalid)
228 if(OptionMap[i] == nativeType)
229 return i;
230 i = (oslSocketOption) ( i + 1 );
233 return i;
236 /* macros */
237 #define OPTION_TO_NATIVE(x) OptionMap[x]
239 /*****************************************************************************/
240 /* enum oslSocketOptionLevel */
241 /*****************************************************************************/
243 static sal_uInt32 OptionLevelMap[]= {
244 SOL_SOCKET, /* osl_Socket_LevelSocket */
245 IPPROTO_TCP, /* osl_Socket_LevelTcp */
246 0 /* osl_Socket_LevelInvalid */
249 /* reverse map */
250 /* mfe: NOT USED
251 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
253 oslSocketOptionLevel i= (oslSocketOptionLevel)0;
255 while(i != osl_Socket_LevelInvalid)
257 if(OptionLevelMap[i] == nativeType)
258 return i;
259 i = (oslSocketOptionLevel) ( i + 1 );
262 return i;
265 /* macros */
266 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
268 /*****************************************************************************/
269 /* enum oslSocketMsgFlag */
270 /*****************************************************************************/
272 static sal_uInt32 SocketMsgFlagMap[]= {
273 0, /* osl_Socket_MsgNormal */
274 MSG_OOB, /* osl_Socket_MsgOOB */
275 MSG_PEEK, /* osl_Socket_MsgPeek */
276 MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
277 MSG_MAXIOVLEN, /* osl_Socket_MsgMaxIOVLen */
278 0 /* osl_Socket_MsgInvalid */
281 /* reverse map */
282 /* mfe: NOT USED
283 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
285 oslSocketMsgFlag i= (oslSocketMsgFlag)0;
287 while(i != osl_Socket_MsgInvalid)
289 if(SocketMsgFlagMap[i] == nativeType)
290 return i;
291 i = (oslSocketMsgFlag) ( i + 1 );
294 return i;
298 /* macros */
299 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
301 /*****************************************************************************/
302 /* enum oslSocketDirection */
303 /*****************************************************************************/
305 static sal_uInt32 SocketDirection[]= {
306 SD_RECEIVE, /* osl_Socket_DirRead */
307 SD_SEND, /* osl_Socket_DirWrite */
308 SD_BOTH, /* osl_Socket_DirReadWrite */
309 0 /* osl_Socket_DirInvalid */
312 /* reverse map */
313 /* mfe: NOT USED
314 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
316 oslSocketDirection i= (oslSocketDirection)0;
318 while(i != osl_Socket_DirInvalid)
320 if(SocketDirection[i] == nativeType)
321 return i;
322 i = (oslSocketDirection) ( i + 1 );
325 return i;
329 /* macros */
330 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
332 /*****************************************************************************/
333 /* enum oslSocketError */
334 /*****************************************************************************/
336 static struct
338 int errcode;
339 oslSocketError error;
340 } SocketError[]= {
341 { 0, osl_Socket_E_None }, /* no error */
342 { ENOTSOCK, osl_Socket_E_NotSocket }, /* Socket operation on non-socket */
343 { EDESTADDRREQ, osl_Socket_E_DestAddrReq }, /* Destination address required */
344 { EMSGSIZE, osl_Socket_E_MsgSize }, /* Message too long */
345 { EPROTOTYPE, osl_Socket_E_Prototype }, /* Protocol wrong type for socket */
346 { ENOPROTOOPT, osl_Socket_E_NoProtocol }, /* Protocol not available */
347 { EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
348 { ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport }, /* Socket type not supported */
349 { EOPNOTSUPP, osl_Socket_E_OpNotSupport }, /* Operation not supported on socket */
350 { EPFNOSUPPORT, osl_Socket_E_PfNoSupport }, /* Protocol family not supported */
351 { EAFNOSUPPORT, osl_Socket_E_AfNoSupport }, /* Address family not supported by */
352 /* protocol family */
353 { EADDRINUSE, osl_Socket_E_AddrInUse }, /* Address already in use */
354 { EADDRNOTAVAIL, osl_Socket_E_AddrNotAvail }, /* Can't assign requested address */
355 { ENETDOWN, osl_Socket_E_NetDown }, /* Network is down */
356 { ENETUNREACH, osl_Socket_E_NetUnreachable }, /* Network is unreachable */
357 { ENETRESET, osl_Socket_E_NetReset }, /* Network dropped connection because */
358 /* of reset */
359 { ECONNABORTED, osl_Socket_E_ConnAborted }, /* Software caused connection abort */
360 { ECONNRESET, osl_Socket_E_ConnReset }, /* Connection reset by peer */
361 { ENOBUFS, osl_Socket_E_NoBufferSpace }, /* No buffer space available */
362 { EISCONN, osl_Socket_E_IsConnected }, /* Socket is already connected */
363 { ENOTCONN, osl_Socket_E_NotConnected }, /* Socket is not connected */
364 { ESHUTDOWN, osl_Socket_E_Shutdown }, /* Can't send after socket shutdown */
365 { ETOOMANYREFS, osl_Socket_E_TooManyRefs }, /* Too many references: can't splice */
366 { ETIMEDOUT, osl_Socket_E_TimedOut }, /* Connection timed out */
367 { ECONNREFUSED, osl_Socket_E_ConnRefused }, /* Connection refused */
368 { EHOSTDOWN, osl_Socket_E_HostDown }, /* Host is down */
369 { EHOSTUNREACH, osl_Socket_E_HostUnreachable }, /* No route to host */
370 { EWOULDBLOCK, osl_Socket_E_WouldBlock }, /* call would block on non-blocking socket */
371 { EALREADY, osl_Socket_E_Already }, /* operation already in progress */
372 { EINPROGRESS, osl_Socket_E_InProgress }, /* operation now in progress */
373 { EAGAIN, osl_Socket_E_WouldBlock }, /* same as EWOULDBLOCK */
374 { -1, osl_Socket_E_InvalidError }
377 /* map */
378 /* mfe: NOT USED
379 static int osl_NativeFromSocketError(oslSocketError errorCode)
381 int i = 0;
383 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
384 (SocketError[i].error != errorCode)) i++;
386 return SocketError[i].errcode;
390 /* reverse map */
391 static oslSocketError osl_SocketErrorFromNative(int nativeType)
393 int i = 0;
395 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
396 (SocketError[i].errcode != nativeType)) i++;
398 return SocketError[i].error;
401 /* macros */
402 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
404 /*****************************************************************************/
405 /* local function prototypes */
406 /*****************************************************************************/
408 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
409 const sal_Char* pszDottedAddr, sal_Int32 Port);
411 oslSocketAddr SAL_CALL osl_psz_createIpxSocketAddr (
412 const sal_Char NetNumber[4],
413 const sal_Char NodeNumber[6],
414 sal_uInt32 SocketNumber);
416 oslHostAddr SAL_CALL osl_psz_createHostAddr (
417 const sal_Char *pszHostname, const oslSocketAddr Addr);
419 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (
420 const sal_Char *pszHostname);
422 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (
423 const oslHostAddr Addr);
425 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
426 sal_Char *pBuffer, sal_uInt32 nBufLen);
428 oslSocketAddr SAL_CALL osl_psz_resolveHostname (
429 const sal_Char* pszHostname);
431 sal_Int32 SAL_CALL osl_psz_getServicePort (
432 const sal_Char* pszServicename, const sal_Char* pszProtocol);
434 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr (
435 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
437 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr (
438 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
440 void SAL_CALL osl_psz_getLastSocketErrorDescription (
441 oslSocket Socket, sal_Char* pBuffer, sal_uInt32 BufferSize);
443 /*****************************************************************************/
444 /* osl_create/destroy-SocketImpl */
445 /*****************************************************************************/
447 #if OSL_DEBUG_LEVEL > 1
448 static sal_uInt32 g_nSocketImpl = 0;
449 static sal_uInt32 g_nSocketAddr = 0;
451 /* sorry, must be implemented otherwise */
453 #endif /* OSL_DEBUG_LEVEL */
456 oslSocket __osl_createSocketImpl(int Socket)
458 oslSocket pSocket;
460 pSocket = (oslSocket)calloc(1, sizeof(struct oslSocketImpl));
462 pSocket->m_Socket = Socket;
463 pSocket->m_nLastError = 0;
464 pSocket->m_nRefCount = 1;
466 #if defined(LINUX)
467 pSocket->m_bIsAccepting = sal_False;
468 #endif
470 #if OSL_DEBUG_LEVEL > 1
471 g_nSocketImpl ++;
472 #endif
473 return pSocket;
476 void __osl_destroySocketImpl(oslSocket Socket)
478 if ( Socket != NULL)
479 free((struct oslSocketImpl *) Socket);
480 #if OSL_DEBUG_LEVEL > 1
481 g_nSocketImpl --;
482 #endif
485 static oslSocketAddr __osl_createSocketAddr( )
487 oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
488 #if OSL_DEBUG_LEVEL > 1
489 g_nSocketAddr ++;
490 #endif
491 return pAddr;
494 static oslSocketAddr __osl_createSocketAddrWithFamily(
495 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
497 oslSocketAddr pAddr;
499 OSL_ASSERT( family == osl_Socket_FamilyInet );
501 pAddr = __osl_createSocketAddr();
502 switch( family )
504 case osl_Socket_FamilyInet:
506 struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
508 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
509 pInetAddr->sin_addr.s_addr = nAddr;
510 pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
511 break;
513 default:
514 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
516 return pAddr;
519 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
521 oslSocketAddr pAddr = __osl_createSocketAddr();
522 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
523 return pAddr;
526 static void __osl_destroySocketAddr( oslSocketAddr addr )
528 #if OSL_DEBUG_LEVEL > 1
529 g_nSocketAddr --;
530 #endif
531 rtl_freeMemory( addr );
534 /*****************************************************************************/
535 /* osl_createEmptySocketAddr */
536 /*****************************************************************************/
537 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
539 oslSocketAddr pAddr = 0;
541 /* is it an internet-Addr? */
542 if (Family == osl_Socket_FamilyInet)
544 pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
546 else
548 pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
551 return pAddr;
554 /*****************************************************************************/
555 /* osl_copySocketAddr */
556 /*****************************************************************************/
557 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
559 oslSocketAddr pCopy = 0;
560 if (Addr)
562 pCopy = __osl_createSocketAddr();
564 if (pCopy)
565 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
567 return pCopy;
570 /*****************************************************************************/
571 /* osl_isEqualSocketAddr */
572 /*****************************************************************************/
573 sal_Bool SAL_CALL osl_isEqualSocketAddr (
574 oslSocketAddr Addr1,
575 oslSocketAddr Addr2)
577 struct sockaddr* pAddr1 = NULL;
578 struct sockaddr* pAddr2 = NULL;
580 OSL_ASSERT(Addr1);
581 OSL_ASSERT(Addr2);
582 pAddr1 = &(Addr1->m_sockaddr);
583 pAddr2 = &(Addr2->m_sockaddr);
585 if (pAddr1 == pAddr2)
587 return (sal_True);
590 if (pAddr1->sa_family == pAddr2->sa_family)
592 switch (pAddr1->sa_family)
594 case AF_INET:
596 struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
597 struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
599 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
600 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
601 (pInetAddr1->sin_port == pInetAddr2->sin_port))
602 return (sal_True);
605 default:
607 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
612 return (sal_False);
615 /*****************************************************************************/
616 /* osl_createInetBroadcastAddr */
617 /*****************************************************************************/
618 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
619 rtl_uString *strDottedAddr,
620 sal_Int32 Port)
622 sal_uInt32 nAddr = OSL_INADDR_NONE;
623 oslSocketAddr pAddr;
625 if (strDottedAddr && strDottedAddr->length)
627 /* Dotted host address for limited broadcast */
628 rtl_String *pDottedAddr = NULL;
630 rtl_uString2String (
631 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
632 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
634 nAddr = inet_addr (pDottedAddr->buffer);
635 rtl_string_release (pDottedAddr);
638 if (nAddr != OSL_INADDR_NONE)
640 /* Limited broadcast */
641 nAddr = ntohl(nAddr);
642 if (IN_CLASSA(nAddr))
644 nAddr &= IN_CLASSA_NET;
645 nAddr |= IN_CLASSA_HOST;
647 else if (IN_CLASSB(nAddr))
649 nAddr &= IN_CLASSB_NET;
650 nAddr |= IN_CLASSB_HOST;
652 else if (IN_CLASSC(nAddr))
654 nAddr &= IN_CLASSC_NET;
655 nAddr |= IN_CLASSC_HOST;
657 else
659 /* No broadcast in class D */
660 return ((oslSocketAddr)NULL);
662 nAddr = htonl(nAddr);
665 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
666 return pAddr;
669 /*****************************************************************************/
670 /* osl_createInetSocketAddr */
671 /*****************************************************************************/
672 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
673 rtl_uString *ustrDottedAddr,
674 sal_Int32 Port)
676 rtl_String* strDottedAddr=0;
677 oslSocketAddr Addr;
678 sal_Char* pszDottedAddr=0;
680 if ( ustrDottedAddr != 0 )
682 rtl_uString2String( &strDottedAddr,
683 rtl_uString_getStr(ustrDottedAddr),
684 rtl_uString_getLength(ustrDottedAddr),
685 RTL_TEXTENCODING_UTF8,
686 OUSTRING_TO_OSTRING_CVTFLAGS);
687 pszDottedAddr = rtl_string_getStr(strDottedAddr);
691 Addr = osl_psz_createInetSocketAddr(pszDottedAddr, Port);
693 if ( strDottedAddr != 0 )
695 rtl_string_release(strDottedAddr);
698 return Addr;
701 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
702 const sal_Char* pszDottedAddr,
703 sal_Int32 Port)
705 oslSocketAddr pAddr = 0;
706 sal_Int32 Addr = inet_addr(pszDottedAddr);
707 if(Addr != -1)
709 /* valid dotted addr */
710 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
712 return pAddr;
715 /*****************************************************************************/
716 /* osl_setAddrOfSocketAddr */
717 /*****************************************************************************/
718 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
720 oslSocketResult res = osl_Socket_Error;
722 OSL_ASSERT( pAddr );
723 OSL_ASSERT( pByteSeq );
725 if( pAddr && pByteSeq )
727 struct sockaddr_in * pSystemInetAddr;
729 OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
730 OSL_ASSERT( pByteSeq->nElements == 4 );
732 pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
733 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
734 res = osl_Socket_Ok;
736 return res;
739 /*****************************************************************************/
740 /* osl_getAddrOfSocketAddr */
741 /*****************************************************************************/
742 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
744 oslSocketResult res = osl_Socket_Error;
746 OSL_ASSERT( pAddr );
747 OSL_ASSERT( ppByteSeq );
749 if( pAddr && ppByteSeq )
751 struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
752 rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
753 res = osl_Socket_Ok;
755 return res;
759 /*****************************************************************************/
760 /* _osl_getFullQualifiedDomainName */
761 /*****************************************************************************/
763 /** try to figure out a full-qualified hostname, by adding the current domain
764 as given by the domainname program to the given hostname.
765 This function MUST NOT call gethostbyname since pHostName already points
766 to data returned by gethostname and would be garbled: use gethostname_r
767 instead!
770 /* wrap around different interfaces to reentrant gethostbyname */
771 static struct hostent* _osl_gethostbyname_r (
772 const char *name, struct hostent *result,
773 char *buffer, int buflen, int *h_errnop)
775 #if defined(LINUX) || defined(ANDROID) || (defined(FREEBSD) && (__FreeBSD_version >= 601103)) || defined(DRAGONFLY)
776 struct hostent *__result; /* will be the same as result */
777 int __error;
778 __error = gethostbyname_r (name, result, buffer, buflen,
779 &__result, h_errnop);
780 return __error ? NULL : __result ;
781 #elif defined(AIX)
782 *h_errnop = gethostbyname_r (name, result, (struct hostent_data *)buffer);
783 (void)buflen;
784 return *h_errnop ? NULL : result ;
785 #else
786 return gethostbyname_r( name, result, buffer, buflen, h_errnop);
787 #endif
790 static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
792 struct hostent aHostByName;
793 struct hostent *pHostByName;
794 sal_Char pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
795 sal_Char *pFullQualifiedName = NULL;
796 int nErrorNo;
798 pHostByName = _osl_gethostbyname_r (
799 pHostName,
800 &aHostByName, pQualifiedHostBuffer,
801 sizeof(pQualifiedHostBuffer), &nErrorNo );
802 if (pHostByName != NULL)
804 pFullQualifiedName = strdup(pHostByName->h_name);
806 return pFullQualifiedName;
808 /*****************************************************************************/
809 /* _osl_isFullQualifiedDomainName */
810 /*****************************************************************************/
811 static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
813 /* a FQDN (aka 'hostname.domain.top_level_domain' )
814 * is a name which contains a dot '.' in it ( would
815 * match as well for 'hostname.' but is good enough
816 * for now )*/
817 return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
820 /*****************************************************************************/
821 /* oslHostAddr */
822 /*****************************************************************************/
823 struct oslHostAddrImpl
825 sal_Char *pHostName;
826 oslSocketAddr pSockAddr;
829 static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
831 oslHostAddr pAddr= NULL;
832 oslSocketAddr pSockAddr = 0;
834 sal_Char *cn;
836 if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
837 return ((oslHostAddr)NULL);
839 if (_osl_isFullQualifiedDomainName(he->h_name))
841 cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
842 OSL_ASSERT(cn);
843 if (cn == NULL)
844 return ((oslHostAddr)NULL);
846 strcpy(cn, he->h_name);
848 else
850 cn =_osl_getFullQualifiedDomainName (he->h_name);
851 OSL_ASSERT(cn);
852 if (cn == NULL)
853 return ((oslHostAddr)NULL);
856 pSockAddr = __osl_createSocketAddr();
857 OSL_ASSERT(pSockAddr);
858 if (pSockAddr == NULL)
860 free(cn);
861 return ((oslHostAddr)NULL);
864 pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
865 if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
867 struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
868 memcpy (
869 &(sin->sin_addr.s_addr),
870 he->h_addr_list[0],
871 he->h_length);
873 else
875 /* unknown address family */
876 /* future extensions for new families might be implemented here */
878 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.");
879 OSL_ASSERT(sal_False);
881 __osl_destroySocketAddr( pSockAddr );
882 free (cn);
883 return ((oslHostAddr)NULL);
886 pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
887 OSL_ASSERT(pAddr);
888 if (pAddr == NULL)
890 __osl_destroySocketAddr( pSockAddr );
891 free (cn);
892 return ((oslHostAddr)NULL);
895 pAddr->pHostName= cn;
896 pAddr->pSockAddr= pSockAddr;
898 return pAddr;
901 /*****************************************************************************/
902 /* osl_createHostAddr */
903 /*****************************************************************************/
904 oslHostAddr SAL_CALL osl_createHostAddr (
905 rtl_uString *ustrHostname,
906 const oslSocketAddr Addr)
908 oslHostAddr HostAddr;
909 rtl_String* strHostname=0;
910 sal_Char* pszHostName=0;
912 if ( ustrHostname != 0 )
914 rtl_uString2String( &strHostname,
915 rtl_uString_getStr(ustrHostname),
916 rtl_uString_getLength(ustrHostname),
917 RTL_TEXTENCODING_UTF8,
918 OUSTRING_TO_OSTRING_CVTFLAGS );
919 pszHostName = rtl_string_getStr(strHostname);
922 HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
924 if ( strHostname != 0 )
926 rtl_string_release(strHostname);
929 return HostAddr;
932 oslHostAddr SAL_CALL osl_psz_createHostAddr (
933 const sal_Char *pszHostname,
934 const oslSocketAddr pAddr)
936 oslHostAddr pHostAddr;
937 sal_Char *cn;
939 OSL_ASSERT(pszHostname && pAddr);
940 if ((pszHostname == NULL) || (pAddr == NULL))
941 return ((oslHostAddr)NULL);
943 cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
944 OSL_ASSERT(cn);
945 if (cn == NULL)
946 return ((oslHostAddr)NULL);
948 strcpy (cn, pszHostname);
950 pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
951 OSL_ASSERT(pHostAddr);
952 if (pHostAddr == NULL)
954 free (cn);
955 return ((oslHostAddr)NULL);
958 pHostAddr->pHostName= cn;
959 pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
961 return pHostAddr;
964 /*****************************************************************************/
965 /* osl_createHostAddrByName */
966 /*****************************************************************************/
967 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
969 oslHostAddr HostAddr;
970 rtl_String* strHostname=0;
971 sal_Char* pszHostName=0;
973 if ( ustrHostname != 0 )
975 rtl_uString2String( &strHostname,
976 rtl_uString_getStr(ustrHostname),
977 rtl_uString_getLength(ustrHostname),
978 RTL_TEXTENCODING_UTF8,
979 OUSTRING_TO_OSTRING_CVTFLAGS );
980 pszHostName=rtl_string_getStr(strHostname);
983 HostAddr = osl_psz_createHostAddrByName(pszHostName);
985 if ( strHostname != 0 )
987 rtl_string_release(strHostname);
990 return HostAddr;
993 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
995 struct hostent aHe;
996 struct hostent *pHe;
997 sal_Char heBuffer[ MAX_HOSTBUFFER_SIZE ];
998 int nErrorNo;
1000 pHe = _osl_gethostbyname_r (
1001 pszHostname,
1002 &aHe, heBuffer,
1003 sizeof(heBuffer), &nErrorNo );
1005 return _osl_hostentToHostAddr (pHe);
1008 /*****************************************************************************/
1009 /* osl_createHostAddrByAddr */
1010 /*****************************************************************************/
1011 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
1013 OSL_ASSERT(pAddr);
1015 if (pAddr == NULL)
1016 return ((oslHostAddr)NULL);
1018 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1020 const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
1021 struct hostent *he;
1023 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
1024 return ((oslHostAddr)NULL);
1026 he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
1027 sizeof (sin->sin_addr),
1028 sin->sin_family);
1029 return _osl_hostentToHostAddr (he);
1032 return ((oslHostAddr)NULL);
1035 /*****************************************************************************/
1036 /* osl_copyHostAddr */
1037 /*****************************************************************************/
1038 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
1040 OSL_ASSERT(pAddr);
1042 if (pAddr)
1043 return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
1044 else
1045 return ((oslHostAddr)NULL);
1048 /*****************************************************************************/
1049 /* osl_getHostnameOfHostAddr */
1050 /*****************************************************************************/
1051 void SAL_CALL osl_getHostnameOfHostAddr (
1052 const oslHostAddr Addr,
1053 rtl_uString **ustrHostname)
1055 const sal_Char* pHostname=0;
1057 pHostname = osl_psz_getHostnameOfHostAddr(Addr);
1059 rtl_uString_newFromAscii (ustrHostname, pHostname);
1061 return;
1064 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1066 if (pAddr)
1067 return pAddr->pHostName;
1068 else
1069 return NULL;
1072 /*****************************************************************************/
1073 /* osl_getSocketAddrOfHostAddr */
1074 /*****************************************************************************/
1075 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1077 OSL_ASSERT(pAddr);
1079 if (pAddr)
1080 return ((oslSocketAddr)(pAddr->pSockAddr));
1081 else
1082 return NULL;
1085 /*****************************************************************************/
1086 /* osl_destroyHostAddr */
1087 /*****************************************************************************/
1088 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1090 if (pAddr)
1092 if (pAddr->pHostName)
1093 free (pAddr->pHostName);
1094 if (pAddr->pSockAddr)
1095 osl_destroySocketAddr (pAddr->pSockAddr);
1096 free (pAddr);
1100 /*****************************************************************************/
1101 /* osl_getLocalHostname */
1102 /*****************************************************************************/
1103 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1105 oslSocketResult Result;
1106 sal_Char pszHostname[1024];
1108 pszHostname[0] = '\0';
1110 Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1112 rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1114 return Result;
1117 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1118 sal_Char *pBuffer, sal_uInt32 nBufLen)
1120 static sal_Char LocalHostname[256] = "";
1122 if (strlen(LocalHostname) == 0)
1124 const sal_Char *pStr;
1126 #ifdef SYSV
1127 struct utsname uts;
1129 if (uname(&uts) < 0)
1130 return osl_Socket_Error;
1132 if ((strlen(uts.nodename) + 1) > nBufLen)
1133 return osl_Socket_Error;
1135 strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1136 #else /* BSD compatible */
1138 if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1139 return osl_Socket_Error;
1140 LocalHostname[sizeof(LocalHostname)-1] = 0;
1141 #endif /* SYSV */
1143 /* check if we have an FQDN */
1144 if (strchr(LocalHostname, '.') == NULL)
1146 oslHostAddr Addr;
1148 /* no, determine it via dns */
1149 Addr = osl_psz_createHostAddrByName(LocalHostname);
1151 if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1153 strcpy(LocalHostname, pStr);
1155 osl_destroyHostAddr(Addr);
1159 if (strlen(LocalHostname) > 0)
1161 strncpy(pBuffer, LocalHostname, nBufLen);
1162 pBuffer[nBufLen - 1] = '\0';
1164 return osl_Socket_Ok;
1167 return osl_Socket_Error;
1170 /*****************************************************************************/
1171 /* osl_resolveHostname */
1172 /*****************************************************************************/
1173 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1175 oslSocketAddr Addr;
1176 rtl_String* strHostname=0;
1177 sal_Char* pszHostName=0;
1179 if ( ustrHostname != 0 )
1181 rtl_uString2String( &strHostname,
1182 rtl_uString_getStr(ustrHostname),
1183 rtl_uString_getLength(ustrHostname),
1184 RTL_TEXTENCODING_UTF8,
1185 OUSTRING_TO_OSTRING_CVTFLAGS );
1186 pszHostName = rtl_string_getStr(strHostname);
1190 Addr = osl_psz_resolveHostname(pszHostName);
1192 if ( strHostname != 0 )
1194 rtl_string_release(strHostname);
1198 return Addr;
1202 oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1204 struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1206 if (pAddr)
1208 oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1210 osl_destroyHostAddr(pAddr);
1212 return (SockAddr);
1215 return ((oslSocketAddr)NULL);
1218 /*****************************************************************************/
1219 /* osl_getServicePort */
1220 /*****************************************************************************/
1221 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1223 sal_Int32 nPort;
1224 rtl_String* strServicename=0;
1225 rtl_String* strProtocol=0;
1226 sal_Char* pszServiceName=0;
1227 sal_Char* pszProtocol=0;
1229 if ( ustrServicename != 0 )
1231 rtl_uString2String( &strServicename,
1232 rtl_uString_getStr(ustrServicename),
1233 rtl_uString_getLength(ustrServicename),
1234 RTL_TEXTENCODING_UTF8,
1235 OUSTRING_TO_OSTRING_CVTFLAGS );
1236 pszServiceName = rtl_string_getStr(strServicename);
1239 if ( ustrProtocol != 0 )
1241 rtl_uString2String( &strProtocol,
1242 rtl_uString_getStr(ustrProtocol),
1243 rtl_uString_getLength(ustrProtocol),
1244 RTL_TEXTENCODING_UTF8,
1245 OUSTRING_TO_OSTRING_CVTFLAGS );
1246 pszProtocol = rtl_string_getStr(strProtocol);
1249 nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1251 if ( strServicename != 0 )
1253 rtl_string_release(strServicename);
1256 if ( strProtocol != 0 )
1258 rtl_string_release(strProtocol);
1262 return nPort;
1266 sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1267 const sal_Char* pszProtocol)
1269 struct servent* ps;
1271 ps= getservbyname(pszServicename, pszProtocol);
1273 if (ps != 0)
1274 return ntohs(ps->s_port);
1276 return OSL_INVALID_PORT;
1279 /*****************************************************************************/
1280 /* osl_destroySocketAddr */
1281 /*****************************************************************************/
1282 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1284 __osl_destroySocketAddr( pAddr );
1287 /*****************************************************************************/
1288 /* osl_getFamilyOfSocketAddr */
1289 /*****************************************************************************/
1290 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1292 OSL_ASSERT(pAddr);
1294 if (pAddr)
1295 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1296 else
1297 return osl_Socket_FamilyInvalid;
1300 /*****************************************************************************/
1301 /* osl_getInetPortOfSocketAddr */
1302 /*****************************************************************************/
1303 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1305 OSL_ASSERT(pAddr);
1306 if( pAddr )
1308 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1310 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1311 return ntohs(pSystemInetAddr->sin_port);
1313 return OSL_INVALID_PORT;
1316 /*****************************************************************************/
1317 /* osl_setInetPortOfSocketAddr */
1318 /*****************************************************************************/
1319 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1321 OSL_ASSERT(pAddr);
1322 if( pAddr )
1324 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1325 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1327 pSystemInetAddr->sin_port= htons((short)Port);
1328 return sal_True;
1332 /* this is not a inet-addr => can't set port */
1333 return sal_False;
1336 /*****************************************************************************/
1337 /* osl_getHostnameOfSocketAddr */
1338 /*****************************************************************************/
1339 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1341 oslSocketResult Result;
1342 sal_Char pszHostname[1024];
1344 pszHostname[0] = '\0';
1346 Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1348 rtl_uString_newFromAscii(ustrHostname,pszHostname);
1350 return Result;
1354 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1355 sal_Char *pBuffer, sal_uInt32 BufferSize)
1357 oslHostAddr pHostAddr= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1359 if (pHostAddr)
1361 strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1363 pBuffer[BufferSize - 1] = '\0';
1365 osl_destroyHostAddr(pHostAddr);
1367 return osl_Socket_Ok;
1370 return osl_Socket_Error;
1373 /*****************************************************************************/
1374 /* osl_getDottedInetAddrOfSocketAddr */
1375 /*****************************************************************************/
1376 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1378 oslSocketResult Result;
1379 sal_Char pszDottedInetAddr[1024];
1381 pszDottedInetAddr[0] = '\0';
1383 Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1385 rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1387 return Result;
1391 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1392 sal_Char *pBuffer, sal_uInt32 BufferSize)
1394 OSL_ASSERT(pAddr);
1396 if( pAddr )
1398 struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1400 if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1402 strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1403 pBuffer[BufferSize - 1] = '\0';
1405 return osl_Socket_Ok;
1409 return osl_Socket_Error;
1412 /*****************************************************************************/
1413 /* osl_createSocket */
1414 /*****************************************************************************/
1415 oslSocket SAL_CALL osl_createSocket(oslAddrFamily Family,
1416 oslSocketType Type,
1417 oslProtocol Protocol)
1419 int Flags;
1420 oslSocket pSocket;
1422 /* alloc memory */
1423 pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1425 /* create socket */
1426 pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1427 TYPE_TO_NATIVE(Type),
1428 PROTOCOL_TO_NATIVE(Protocol));
1430 /* creation failed => free memory */
1431 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1433 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1434 errno,
1435 strerror(errno));
1437 __osl_destroySocketImpl((pSocket));
1438 pSocket= 0;
1440 else
1442 /* set close-on-exec flag */
1443 if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1445 Flags |= FD_CLOEXEC;
1446 if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1448 pSocket->m_nLastError=errno;
1449 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1450 errno,
1451 strerror(errno));
1454 else
1456 pSocket->m_nLastError=errno;
1460 return pSocket;
1463 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1465 osl_atomic_increment( &(pSocket->m_nRefCount ) );
1468 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1470 if( pSocket && 0 == osl_atomic_decrement( &(pSocket->m_nRefCount) ) )
1472 #if defined(LINUX)
1473 if ( pSocket->m_bIsAccepting == sal_True )
1475 OSL_FAIL("osl_destroySocket : attempt to destroy socket while accepting\n");
1476 return;
1478 #endif /* LINUX */
1479 osl_closeSocket( pSocket );
1480 __osl_destroySocketImpl( pSocket );
1486 /*****************************************************************************/
1487 /* osl_closeSocket */
1488 /*****************************************************************************/
1489 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1491 int nRet;
1492 int nFD;
1494 /* socket already invalid */
1495 if(pSocket==0)
1496 return;
1498 pSocket->m_nLastError=0;
1499 nFD = pSocket->m_Socket;
1501 if (nFD == OSL_INVALID_SOCKET)
1502 return;
1504 pSocket->m_Socket = OSL_INVALID_SOCKET;
1506 #if defined(LINUX)
1507 pSocket->m_bIsInShutdown = sal_True;
1509 if ( pSocket->m_bIsAccepting == sal_True )
1511 int nConnFD;
1512 union {
1513 struct sockaddr aSockAddr;
1514 struct sockaddr_in aSockAddrIn;
1515 } s;
1516 socklen_t nSockLen = sizeof(s.aSockAddr);
1518 nRet = getsockname(nFD, &s.aSockAddr, &nSockLen);
1519 if ( nRet < 0 )
1521 OSL_TRACE("getsockname call failed with error: %s", strerror(errno));
1524 if ( s.aSockAddr.sa_family == AF_INET )
1526 if ( s.aSockAddrIn.sin_addr.s_addr == htonl(INADDR_ANY) )
1528 s.aSockAddrIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1531 nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1532 if ( nConnFD < 0 )
1534 OSL_TRACE("socket call failed with error: %s", strerror(errno));
1537 nRet = connect(nConnFD, &s.aSockAddr, sizeof(s.aSockAddr));
1538 if ( nRet < 0 )
1540 OSL_TRACE("connect call failed with error: %s", strerror(errno));
1542 close(nConnFD);
1544 pSocket->m_bIsAccepting = sal_False;
1546 #endif /* LINUX */
1548 nRet=close(nFD);
1549 if ( nRet != 0 )
1551 pSocket->m_nLastError=errno;
1552 OSL_TRACE("closeSocket close error '%s'",strerror(errno));
1555 pSocket->m_Socket = OSL_INVALID_SOCKET;
1558 /*****************************************************************************/
1559 /* osl_getLocalAddrOfSocket */
1560 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1561 /* are the same! I don't like it very much but see no other easy way to conceal */
1562 /* the struct sockaddr from the eyes of the user. */
1563 /*****************************************************************************/
1564 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1566 socklen_t AddrLen;
1567 struct sockaddr Addr;
1568 oslSocketAddr pAddr;
1570 if (pSocket == NULL) /* ENOTSOCK */
1571 return ((oslSocketAddr)NULL);
1573 AddrLen= sizeof(struct sockaddr);
1575 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1576 return ((oslSocketAddr)NULL);
1578 pAddr = __osl_createSocketAddrFromSystem( &Addr );
1579 return pAddr;
1582 /*****************************************************************************/
1583 /* osl_getPeerAddrOfSocket */
1584 /*****************************************************************************/
1585 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1587 socklen_t AddrLen;
1588 struct sockaddr Addr;
1590 OSL_ASSERT(pSocket);
1591 if ( pSocket == 0 )
1593 return 0;
1596 pSocket->m_nLastError=0;
1597 AddrLen= sizeof(struct sockaddr);
1599 if(getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1601 pSocket->m_nLastError=errno;
1602 return 0;
1604 return __osl_createSocketAddrFromSystem( &Addr );
1607 /*****************************************************************************/
1608 /* osl_bindAddrToSocket */
1609 /*****************************************************************************/
1610 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
1611 oslSocketAddr pAddr)
1613 int nRet;
1615 OSL_ASSERT(pSocket && pAddr );
1616 if ( pSocket == 0 || pAddr == 0 )
1618 return sal_False;
1621 pSocket->m_nLastError=0;
1623 nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1625 if ( nRet == OSL_SOCKET_ERROR)
1627 pSocket->m_nLastError=errno;
1628 return sal_False;
1631 return sal_True;
1635 /*****************************************************************************/
1636 /* osl_listenOnSocket */
1637 /*****************************************************************************/
1638 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
1639 sal_Int32 MaxPendingConnections)
1641 int nRet;
1643 OSL_ASSERT(pSocket);
1644 if ( pSocket == 0 )
1646 return sal_False;
1649 pSocket->m_nLastError=0;
1651 nRet = listen(pSocket->m_Socket,
1652 MaxPendingConnections == -1 ?
1653 SOMAXCONN :
1654 MaxPendingConnections);
1655 if ( nRet == OSL_SOCKET_ERROR)
1657 pSocket->m_nLastError=errno;
1658 return sal_False;
1661 return sal_True;
1665 /*****************************************************************************/
1666 /* osl_connectSocketTo */
1667 /*****************************************************************************/
1668 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
1669 oslSocketAddr pAddr,
1670 const TimeValue* pTimeout)
1672 fd_set WriteSet;
1673 fd_set ExcptSet;
1674 int ReadyHandles;
1675 struct timeval tv;
1676 oslSocketResult Result= osl_Socket_Ok;
1678 OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
1680 if ( pSocket == 0 )
1682 return osl_Socket_Error;
1685 pSocket->m_nLastError=0;
1687 if (osl_isNonBlockingMode(pSocket))
1689 if (connect(pSocket->m_Socket,
1690 &(pAddr->m_sockaddr),
1691 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1692 return osl_Socket_Ok;
1693 else
1694 if (errno == EWOULDBLOCK || errno == EINPROGRESS)
1696 pSocket->m_nLastError=EINPROGRESS;
1697 return osl_Socket_InProgress;
1701 pSocket->m_nLastError=errno;
1702 OSL_TRACE("can't connect : '%s'",strerror(errno));
1703 return osl_Socket_Error;
1706 /* set socket temporarily to non-blocking */
1707 OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
1709 /* initiate connect */
1710 if(connect(pSocket->m_Socket,
1711 &(pAddr->m_sockaddr),
1712 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1714 /* immediate connection */
1715 osl_enableNonBlockingMode(pSocket, sal_False);
1717 return osl_Socket_Ok;
1719 else
1721 /* really an error or just delayed? */
1722 if (errno != EINPROGRESS)
1724 pSocket->m_nLastError=errno;
1725 OSL_TRACE(
1726 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
1727 errno, strerror(errno));
1729 osl_enableNonBlockingMode(pSocket, sal_False);
1730 return osl_Socket_Error;
1735 /* prepare select set for socket */
1736 FD_ZERO(&WriteSet);
1737 FD_ZERO(&ExcptSet);
1738 FD_SET(pSocket->m_Socket, &WriteSet);
1739 FD_SET(pSocket->m_Socket, &ExcptSet);
1741 /* prepare timeout */
1742 if (pTimeout)
1744 /* divide milliseconds into seconds and microseconds */
1745 tv.tv_sec= pTimeout->Seconds;
1746 tv.tv_usec= pTimeout->Nanosec / 1000L;
1749 /* select */
1750 ReadyHandles= select(pSocket->m_Socket+1,
1752 PTR_FD_SET(WriteSet),
1753 PTR_FD_SET(ExcptSet),
1754 (pTimeout) ? &tv : 0);
1756 if (ReadyHandles > 0) /* connected */
1758 if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
1760 int nErrorCode = 0;
1761 socklen_t nErrorSize = sizeof( nErrorCode );
1763 int nSockOpt;
1765 nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
1766 &nErrorCode, &nErrorSize );
1767 if ( (nSockOpt == 0) && (nErrorCode == 0))
1768 Result = osl_Socket_Ok;
1769 else
1770 Result = osl_Socket_Error;
1772 else
1774 Result= osl_Socket_Error;
1777 else if (ReadyHandles < 0) /* error */
1779 if (errno == EBADF) /* most probably interrupted by close() */
1781 /* do not access pSockImpl because it is about to be or */
1782 /* already destroyed */
1783 return osl_Socket_Interrupted;
1785 else
1787 pSocket->m_nLastError=errno;
1788 Result= osl_Socket_Error;
1791 else /* timeout */
1793 pSocket->m_nLastError=errno;
1794 Result= osl_Socket_TimedOut;
1797 osl_enableNonBlockingMode(pSocket, sal_False);
1799 return Result;
1803 /*****************************************************************************/
1804 /* osl_acceptConnectionOnSocket */
1805 /*****************************************************************************/
1806 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
1807 oslSocketAddr* ppAddr)
1809 struct sockaddr Addr;
1810 int Connection, Flags;
1811 oslSocket pConnectionSockImpl;
1813 socklen_t AddrLen = sizeof(struct sockaddr);
1814 OSL_ASSERT(pSocket);
1815 if ( pSocket == 0 )
1817 return 0;
1820 pSocket->m_nLastError=0;
1821 #if defined(LINUX)
1822 pSocket->m_bIsAccepting = sal_True;
1823 #endif /* LINUX */
1825 if( ppAddr && *ppAddr )
1827 osl_destroySocketAddr( *ppAddr );
1828 *ppAddr = 0;
1831 /* prevent Linux EINTR behaviour */
1834 Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
1835 } while (Connection == -1 && errno == EINTR);
1838 /* accept failed? */
1839 if( Connection == OSL_SOCKET_ERROR )
1841 pSocket->m_nLastError=errno;
1842 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'",strerror(errno));
1844 #if defined(LINUX)
1845 pSocket->m_bIsAccepting = sal_False;
1846 #endif /* LINUX */
1847 return 0;
1850 OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
1853 #if defined(LINUX)
1854 if ( pSocket->m_bIsInShutdown == sal_True )
1856 close(Connection);
1857 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept");
1858 return 0;
1860 #endif /* LINUX */
1863 if(ppAddr)
1865 *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
1868 /* alloc memory */
1869 pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1871 /* set close-on-exec flag */
1872 if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
1874 Flags |= FD_CLOEXEC;
1875 if (fcntl(Connection, F_SETFD, Flags) == -1)
1877 pSocket->m_nLastError=errno;
1878 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
1879 errno,
1880 strerror(errno));
1885 pConnectionSockImpl->m_Socket = Connection;
1886 pConnectionSockImpl->m_nLastError = 0;
1887 #if defined(LINUX)
1888 pConnectionSockImpl->m_bIsAccepting = sal_False;
1890 pSocket->m_bIsAccepting = sal_False;
1891 #endif /* LINUX */
1892 return pConnectionSockImpl;
1895 /*****************************************************************************/
1896 /* osl_receiveSocket */
1897 /*****************************************************************************/
1898 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
1899 void* pBuffer,
1900 sal_uInt32 BytesToRead,
1901 oslSocketMsgFlag Flag)
1903 int nRead;
1905 OSL_ASSERT(pSocket);
1906 if ( pSocket == 0 )
1908 OSL_TRACE("osl_receiveSocket : Invalid socket");
1909 return -1;
1912 pSocket->m_nLastError=0;
1916 nRead = recv(pSocket->m_Socket,
1917 (sal_Char*)pBuffer,
1918 BytesToRead,
1919 MSG_FLAG_TO_NATIVE(Flag));
1920 } while ( nRead < 0 && errno == EINTR );
1922 if ( nRead < 0 )
1924 pSocket->m_nLastError=errno;
1925 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
1927 else if ( nRead == 0 )
1929 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
1932 return nRead;
1936 /*****************************************************************************/
1937 /* osl_receiveFromSocket */
1938 /*****************************************************************************/
1939 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
1940 oslSocketAddr pSenderAddr,
1941 void* pBuffer,
1942 sal_uInt32 BufferSize,
1943 oslSocketMsgFlag Flag)
1945 int nRead;
1946 struct sockaddr *pSystemSockAddr = 0;
1947 socklen_t AddrLen = 0;
1948 if( pSenderAddr )
1950 AddrLen = sizeof( struct sockaddr );
1951 pSystemSockAddr = &(pSenderAddr->m_sockaddr);
1954 OSL_ASSERT(pSocket);
1955 if ( pSocket == 0 )
1957 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
1958 return -1;
1961 pSocket->m_nLastError=0;
1963 nRead = recvfrom(pSocket->m_Socket,
1964 (sal_Char*)pBuffer,
1965 BufferSize,
1966 MSG_FLAG_TO_NATIVE(Flag),
1967 pSystemSockAddr,
1968 &AddrLen);
1970 if ( nRead < 0 )
1972 pSocket->m_nLastError=errno;
1973 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
1975 else if ( nRead == 0 )
1977 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
1980 return nRead;
1984 /*****************************************************************************/
1985 /* osl_sendSocket */
1986 /*****************************************************************************/
1987 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
1988 const void* pBuffer,
1989 sal_uInt32 BytesToSend,
1990 oslSocketMsgFlag Flag)
1992 int nWritten;
1994 OSL_ASSERT(pSocket);
1995 if ( pSocket == 0 )
1997 OSL_TRACE("osl_sendSocket : Invalid socket");
1998 return -1;
2001 pSocket->m_nLastError=0;
2005 nWritten = send(pSocket->m_Socket,
2006 (sal_Char*)pBuffer,
2007 BytesToSend,
2008 MSG_FLAG_TO_NATIVE(Flag));
2009 } while ( nWritten < 0 && errno == EINTR );
2012 if ( nWritten < 0 )
2014 pSocket->m_nLastError=errno;
2015 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
2017 else if ( nWritten == 0 )
2019 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
2022 return nWritten;
2025 /*****************************************************************************/
2026 /* osl_sendToSocket */
2027 /*****************************************************************************/
2028 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
2029 oslSocketAddr ReceiverAddr,
2030 const void* pBuffer,
2031 sal_uInt32 BytesToSend,
2032 oslSocketMsgFlag Flag)
2034 int nWritten;
2036 struct sockaddr *pSystemSockAddr = 0;
2037 int AddrLen = 0;
2038 if( ReceiverAddr )
2040 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
2041 AddrLen = sizeof( struct sockaddr );
2044 OSL_ASSERT(pSocket);
2045 if ( pSocket == 0 )
2047 OSL_TRACE("osl_sendToSocket : Invalid socket");
2048 return -1;
2051 pSocket->m_nLastError=0;
2053 /* ReceiverAddr might be 0 when used on a connected socket. */
2054 /* Then sendto should behave like send. */
2056 nWritten = sendto(pSocket->m_Socket,
2057 (sal_Char*)pBuffer,
2058 BytesToSend,
2059 MSG_FLAG_TO_NATIVE(Flag),
2060 pSystemSockAddr,
2061 AddrLen);
2063 if ( nWritten < 0 )
2065 pSocket->m_nLastError=errno;
2066 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
2068 else if ( nWritten == 0 )
2070 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
2073 return nWritten;
2076 /*****************************************************************************/
2077 /* osl_readSocket */
2078 /*****************************************************************************/
2079 sal_Int32 SAL_CALL osl_readSocket (
2080 oslSocket pSocket, void *pBuffer, sal_Int32 n )
2082 sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
2083 sal_uInt32 BytesRead= 0;
2084 sal_uInt32 BytesToRead= n;
2086 OSL_ASSERT( pSocket);
2088 /* loop until all desired bytes were read or an error occurred */
2089 while (BytesToRead > 0)
2091 sal_Int32 RetVal;
2092 RetVal= osl_receiveSocket(pSocket,
2093 Ptr,
2094 BytesToRead,
2095 osl_Socket_MsgNormal);
2097 /* error occurred? */
2098 if(RetVal <= 0)
2100 break;
2103 BytesToRead -= RetVal;
2104 BytesRead += RetVal;
2105 Ptr += RetVal;
2108 return BytesRead;
2111 /*****************************************************************************/
2112 /* osl_writeSocket */
2113 /*****************************************************************************/
2114 sal_Int32 SAL_CALL osl_writeSocket(
2115 oslSocket pSocket, const void *pBuffer, sal_Int32 n )
2117 /* loop until all desired bytes were send or an error occurred */
2118 sal_uInt32 BytesSend= 0;
2119 sal_uInt32 BytesToSend= n;
2120 sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
2122 OSL_ASSERT( pSocket );
2124 while (BytesToSend > 0)
2126 sal_Int32 RetVal;
2128 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
2130 /* error occurred? */
2131 if(RetVal <= 0)
2133 break;
2136 BytesToSend -= RetVal;
2137 BytesSend += RetVal;
2138 Ptr += RetVal;
2141 return BytesSend;
2144 /*****************************************************************************/
2145 /* __osl_socket_poll */
2146 /*****************************************************************************/
2148 #ifdef HAVE_POLL_H /* poll() */
2150 sal_Bool __osl_socket_poll (
2151 oslSocket pSocket,
2152 const TimeValue* pTimeout,
2153 short nEvent)
2155 struct pollfd fds;
2156 int timeout;
2157 int result;
2159 OSL_ASSERT(0 != pSocket);
2160 if (0 == pSocket)
2161 return sal_False; /* EINVAL */
2163 pSocket->m_nLastError = 0;
2165 fds.fd = pSocket->m_Socket;
2166 fds.events = nEvent;
2167 fds.revents = 0;
2169 timeout = -1;
2170 if (pTimeout)
2172 /* Convert to [ms] */
2173 timeout = pTimeout->Seconds * 1000;
2174 timeout += pTimeout->Nanosec / (1000 * 1000);
2177 result = poll (&fds, 1, timeout);
2178 if (result < 0)
2180 pSocket->m_nLastError = errno;
2181 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2182 errno, strerror(errno));
2183 return sal_False;
2185 if (result == 0)
2187 /* Timeout */
2188 return sal_False;
2191 return ((fds.revents & nEvent) == nEvent);
2194 #else /* select() */
2196 sal_Bool __osl_socket_poll (
2197 oslSocket pSocket,
2198 const TimeValue* pTimeout,
2199 short nEvent)
2201 fd_set fds;
2202 struct timeval tv;
2203 int result;
2205 OSL_ASSERT(0 != pSocket);
2206 if (0 == pSocket)
2207 return sal_False; /* EINVAL */
2209 pSocket->m_nLastError = 0;
2211 FD_ZERO(&fds);
2212 FD_SET(pSocket->m_Socket, &fds);
2214 if (pTimeout)
2216 /* Convert to 'timeval' */
2217 tv.tv_sec = pTimeout->Seconds;
2218 tv.tv_usec = pTimeout->Nanosec / 1000;
2221 result = select (
2222 pSocket->m_Socket + 1,
2223 (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2224 (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2225 (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2226 (pTimeout) ? &tv : NULL);
2228 if (result < 0)
2230 pSocket->m_nLastError = errno;
2231 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2232 errno, strerror(errno));
2233 return sal_False;
2235 if (result == 0)
2237 /* Timeout */
2238 return sal_False;
2241 return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2244 #endif /* HAVE_POLL_H */
2246 /*****************************************************************************/
2247 /* osl_isReceiveReady */
2248 /*****************************************************************************/
2249 sal_Bool SAL_CALL osl_isReceiveReady (
2250 oslSocket pSocket, const TimeValue* pTimeout)
2252 OSL_ASSERT(pSocket);
2253 if (pSocket == NULL)
2255 /* ENOTSOCK */
2256 return sal_False;
2259 return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2262 /*****************************************************************************/
2263 /* osl_isSendReady */
2264 /*****************************************************************************/
2265 sal_Bool SAL_CALL osl_isSendReady (
2266 oslSocket pSocket, const TimeValue* pTimeout)
2268 OSL_ASSERT(pSocket);
2269 if (pSocket == NULL)
2271 /* ENOTSOCK */
2272 return sal_False;
2275 return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2278 /*****************************************************************************/
2279 /* osl_isExceptionPending */
2280 /*****************************************************************************/
2281 sal_Bool SAL_CALL osl_isExceptionPending (
2282 oslSocket pSocket, const TimeValue* pTimeout)
2284 OSL_ASSERT(pSocket);
2285 if (pSocket == NULL)
2287 /* ENOTSOCK */
2288 return sal_False;
2291 return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2294 /*****************************************************************************/
2295 /* osl_shutdownSocket */
2296 /*****************************************************************************/
2297 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2298 oslSocketDirection Direction)
2300 int nRet;
2302 OSL_ASSERT(pSocket);
2303 if ( pSocket == 0 )
2305 return sal_False;
2308 pSocket->m_nLastError=0;
2310 nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2311 if (nRet != 0 )
2313 pSocket->m_nLastError=errno;
2314 OSL_TRACE("shutdown error '%s'",strerror(errno));
2316 return (nRet==0);
2320 /*****************************************************************************/
2321 /* osl_getSocketOption */
2322 /*****************************************************************************/
2323 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2324 oslSocketOptionLevel Level,
2325 oslSocketOption Option,
2326 void* pBuffer,
2327 sal_uInt32 BufferLen)
2329 socklen_t nOptLen = (socklen_t) BufferLen;
2331 OSL_ASSERT(pSocket);
2332 if ( pSocket == 0 )
2334 return -1;
2337 pSocket->m_nLastError=0;
2339 if(getsockopt(pSocket->m_Socket,
2340 OPTION_LEVEL_TO_NATIVE(Level),
2341 OPTION_TO_NATIVE(Option),
2342 (sal_Char*)pBuffer,
2343 &nOptLen) == -1)
2345 pSocket->m_nLastError=errno;
2346 return -1;
2349 return BufferLen;
2352 /*****************************************************************************/
2353 /* osl_setSocketOption */
2354 /*****************************************************************************/
2355 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2356 oslSocketOptionLevel Level,
2357 oslSocketOption Option,
2358 void* pBuffer,
2359 sal_uInt32 BufferLen)
2361 int nRet;
2363 OSL_ASSERT(pSocket);
2364 if ( pSocket == 0 )
2366 return sal_False;
2369 pSocket->m_nLastError=0;
2371 nRet = setsockopt(pSocket->m_Socket,
2372 OPTION_LEVEL_TO_NATIVE(Level),
2373 OPTION_TO_NATIVE(Option),
2374 (sal_Char*)pBuffer,
2375 BufferLen);
2377 if ( nRet < 0 )
2379 pSocket->m_nLastError=errno;
2380 return sal_False;
2383 return sal_True;
2386 /*****************************************************************************/
2387 /* osl_enableNonBlockingMode */
2388 /*****************************************************************************/
2389 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2390 sal_Bool On)
2392 int flags;
2393 int nRet;
2395 OSL_ASSERT(pSocket);
2396 if ( pSocket == 0 )
2398 return sal_False;
2401 pSocket->m_nLastError=0;
2403 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2405 if (On)
2406 flags |= O_NONBLOCK;
2407 else
2408 flags &= ~(O_NONBLOCK);
2410 nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2412 if ( nRet < 0 )
2414 pSocket->m_nLastError=errno;
2415 return sal_False;
2418 return sal_True;
2421 /*****************************************************************************/
2422 /* osl_isNonBlockingMode */
2423 /*****************************************************************************/
2424 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2426 int flags;
2428 OSL_ASSERT(pSocket);
2429 if ( pSocket == 0 )
2431 return sal_False;
2434 pSocket->m_nLastError=0;
2436 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2438 if (flags == -1 || !(flags & O_NONBLOCK))
2439 return sal_False;
2440 else
2441 return sal_True;
2444 /*****************************************************************************/
2445 /* osl_getSocketType */
2446 /*****************************************************************************/
2447 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2449 int Type=0;
2450 socklen_t TypeSize= sizeof(Type);
2452 OSL_ASSERT(pSocket);
2453 if ( pSocket == 0 )
2455 return osl_Socket_TypeInvalid;
2458 pSocket->m_nLastError=0;
2460 if(getsockopt(pSocket->m_Socket,
2461 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2462 OPTION_TO_NATIVE(osl_Socket_OptionType),
2463 (sal_Char*)&Type,
2464 &TypeSize) == -1)
2466 /* error */
2467 pSocket->m_nLastError=errno;
2468 return osl_Socket_TypeInvalid;
2471 return TYPE_FROM_NATIVE(Type);
2475 /*****************************************************************************/
2476 /* osl_getLastSocketErrorDescription */
2477 /*****************************************************************************/
2478 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2480 sal_Char pszError[1024];
2482 pszError[0] = '\0';
2484 osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2486 rtl_uString_newFromAscii(ustrError,pszError);
2488 return;
2492 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2494 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2495 pBuffer[BufferSize-1]= '\0';
2497 if ( pSocket == 0 )
2499 strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2500 return;
2503 strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2504 return;
2507 /*****************************************************************************/
2508 /* osl_getLastSocketError */
2509 /*****************************************************************************/
2510 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2512 if ( pSocket == 0 )
2514 return ERROR_FROM_NATIVE(EINVAL);
2517 return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2520 /*****************************************************************************/
2521 /* SocketSet */
2522 /*****************************************************************************/
2523 typedef struct _TSocketSetImpl
2525 int m_MaxHandle; /* for select(), the largest descriptor in the set */
2526 fd_set m_Set; /* the set of descriptors */
2528 } TSocketSetImpl;
2530 /*****************************************************************************/
2531 /* osl_createSocketSet */
2532 /*****************************************************************************/
2533 oslSocketSet SAL_CALL osl_createSocketSet()
2535 TSocketSetImpl* pSet;
2537 pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2539 OSL_ASSERT(pSet);
2541 if(pSet)
2543 pSet->m_MaxHandle= 0;
2544 FD_ZERO(&pSet->m_Set);
2547 return (oslSocketSet)pSet;
2550 /*****************************************************************************/
2551 /* osl_destroySocketSet */
2552 /*****************************************************************************/
2553 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2555 if(Set)
2556 free(Set);
2559 /*****************************************************************************/
2560 /* osl_clearSocketSet */
2561 /*****************************************************************************/
2562 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2564 TSocketSetImpl* pSet;
2565 OSL_ASSERT(Set);
2566 if ( Set == 0 )
2568 return;
2571 pSet= (TSocketSetImpl*)Set;
2572 pSet->m_MaxHandle= 0;
2574 FD_ZERO(&pSet->m_Set);
2577 /*****************************************************************************/
2578 /* osl_addToSocketSet */
2579 /*****************************************************************************/
2580 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2582 TSocketSetImpl* pSet;
2584 OSL_ASSERT(Set);
2585 OSL_ASSERT(pSocket);
2587 if ( Set == 0 || pSocket == 0)
2589 return;
2592 pSet= (TSocketSetImpl*)Set;
2594 /* correct max handle */
2595 if(pSocket->m_Socket > pSet->m_MaxHandle)
2596 pSet->m_MaxHandle= pSocket->m_Socket;
2597 FD_SET(pSocket->m_Socket, &pSet->m_Set);
2601 /*****************************************************************************/
2602 /* osl_removeFromSocketSet */
2603 /*****************************************************************************/
2604 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
2606 TSocketSetImpl* pSet;
2608 OSL_ASSERT(Set);
2609 OSL_ASSERT(pSocket);
2611 if ( Set == 0 || pSocket == 0)
2613 return;
2616 pSet= (TSocketSetImpl*)Set;
2618 /* correct max handle */
2619 if(pSocket->m_Socket == pSet->m_MaxHandle)
2621 /* not optimal, since the next used descriptor might be */
2622 /* much smaller than m_Socket-1, but it will do */
2623 pSet->m_MaxHandle--;
2624 if(pSet->m_MaxHandle < 0)
2626 pSet->m_MaxHandle= 0; /* avoid underflow */
2630 FD_CLR(pSocket->m_Socket, &pSet->m_Set);
2633 /*****************************************************************************/
2634 /* osl_isInSocketSet */
2635 /*****************************************************************************/
2636 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
2638 TSocketSetImpl* pSet;
2640 OSL_ASSERT(Set);
2641 OSL_ASSERT(pSocket);
2642 if ( Set == 0 || pSocket == 0 )
2644 return sal_False;
2647 pSet= (TSocketSetImpl*)Set;
2649 return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
2652 /*****************************************************************************/
2653 /* osl_demultiplexSocketEvents */
2654 /*****************************************************************************/
2655 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
2656 oslSocketSet OutgoingSet,
2657 oslSocketSet OutOfBandSet,
2658 const TimeValue* pTimeout)
2660 int MaxHandle= 0;
2661 struct timeval tv;
2662 TSocketSetImpl* pInSet;
2663 TSocketSetImpl* pOutSet;
2664 TSocketSetImpl* pOOBSet;
2666 if (pTimeout)
2668 /* non-blocking call */
2669 tv.tv_sec = pTimeout->Seconds;
2670 tv.tv_usec = pTimeout->Nanosec / 1000L;
2673 /* map opaque data to impl-types */
2674 pInSet= (TSocketSetImpl*)IncomingSet;
2675 pOutSet= (TSocketSetImpl*)OutgoingSet;
2676 pOOBSet= (TSocketSetImpl*)OutOfBandSet;
2678 /* get max handle from all sets */
2679 if (pInSet)
2680 MaxHandle= pInSet->m_MaxHandle;
2682 if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
2683 MaxHandle= pOutSet->m_MaxHandle;
2685 if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
2686 MaxHandle= pOOBSet->m_MaxHandle;
2688 return select(MaxHandle+1,
2689 pInSet ? PTR_FD_SET(pInSet->m_Set) : 0,
2690 pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
2691 pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
2692 pTimeout ? &tv : 0);
2695 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */