Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / sal / osl / unx / socket.c
blob1743dc0868138694b97d11ec3c5d8efc3a3df04c
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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 #if OSL_DEBUG_LEVEL > 1
444 static sal_uInt32 g_nSocketImpl = 0;
445 static sal_uInt32 g_nSocketAddr = 0;
447 /* sorry, must be implemented otherwise */
449 #endif /* OSL_DEBUG_LEVEL */
452 oslSocket __osl_createSocketImpl(int Socket)
454 oslSocket pSocket;
456 pSocket = (oslSocket)calloc(1, sizeof(struct oslSocketImpl));
458 pSocket->m_Socket = Socket;
459 pSocket->m_nLastError = 0;
460 pSocket->m_nRefCount = 1;
462 #if defined(LINUX)
463 pSocket->m_bIsAccepting = sal_False;
464 #endif
466 #if OSL_DEBUG_LEVEL > 1
467 g_nSocketImpl ++;
468 #endif
469 return pSocket;
472 void __osl_destroySocketImpl(oslSocket Socket)
474 if ( Socket != NULL)
475 free((struct oslSocketImpl *) Socket);
476 #if OSL_DEBUG_LEVEL > 1
477 g_nSocketImpl --;
478 #endif
481 static oslSocketAddr __osl_createSocketAddr( )
483 oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
484 #if OSL_DEBUG_LEVEL > 1
485 g_nSocketAddr ++;
486 #endif
487 return pAddr;
490 static oslSocketAddr __osl_createSocketAddrWithFamily(
491 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
493 oslSocketAddr pAddr;
495 OSL_ASSERT( family == osl_Socket_FamilyInet );
497 pAddr = __osl_createSocketAddr();
498 switch( family )
500 case osl_Socket_FamilyInet:
502 struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
504 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
505 pInetAddr->sin_addr.s_addr = nAddr;
506 pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
507 break;
509 default:
510 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
512 return pAddr;
515 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
517 oslSocketAddr pAddr = __osl_createSocketAddr();
518 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
519 return pAddr;
522 static void __osl_destroySocketAddr( oslSocketAddr addr )
524 #if OSL_DEBUG_LEVEL > 1
525 g_nSocketAddr --;
526 #endif
527 rtl_freeMemory( addr );
530 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
532 oslSocketAddr pAddr = 0;
534 /* is it an internet-Addr? */
535 if (Family == osl_Socket_FamilyInet)
537 pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
539 else
541 pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
544 return pAddr;
547 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
549 oslSocketAddr pCopy = 0;
550 if (Addr)
552 pCopy = __osl_createSocketAddr();
554 if (pCopy)
555 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
557 return pCopy;
560 sal_Bool SAL_CALL osl_isEqualSocketAddr (
561 oslSocketAddr Addr1,
562 oslSocketAddr Addr2)
564 struct sockaddr* pAddr1 = NULL;
565 struct sockaddr* pAddr2 = NULL;
567 OSL_ASSERT(Addr1);
568 OSL_ASSERT(Addr2);
569 pAddr1 = &(Addr1->m_sockaddr);
570 pAddr2 = &(Addr2->m_sockaddr);
572 if (pAddr1 == pAddr2)
574 return (sal_True);
577 if (pAddr1->sa_family == pAddr2->sa_family)
579 switch (pAddr1->sa_family)
581 case AF_INET:
583 struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
584 struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
586 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
587 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
588 (pInetAddr1->sin_port == pInetAddr2->sin_port))
589 return (sal_True);
592 default:
594 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
599 return (sal_False);
602 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
603 rtl_uString *strDottedAddr,
604 sal_Int32 Port)
606 sal_uInt32 nAddr = OSL_INADDR_NONE;
607 oslSocketAddr pAddr;
609 if (strDottedAddr && strDottedAddr->length)
611 /* Dotted host address for limited broadcast */
612 rtl_String *pDottedAddr = NULL;
614 rtl_uString2String (
615 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
616 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
618 nAddr = inet_addr (pDottedAddr->buffer);
619 rtl_string_release (pDottedAddr);
622 if (nAddr != OSL_INADDR_NONE)
624 /* Limited broadcast */
625 nAddr = ntohl(nAddr);
626 if (IN_CLASSA(nAddr))
628 nAddr &= IN_CLASSA_NET;
629 nAddr |= IN_CLASSA_HOST;
631 else if (IN_CLASSB(nAddr))
633 nAddr &= IN_CLASSB_NET;
634 nAddr |= IN_CLASSB_HOST;
636 else if (IN_CLASSC(nAddr))
638 nAddr &= IN_CLASSC_NET;
639 nAddr |= IN_CLASSC_HOST;
641 else
643 /* No broadcast in class D */
644 return ((oslSocketAddr)NULL);
646 nAddr = htonl(nAddr);
649 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
650 return pAddr;
653 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
654 rtl_uString *ustrDottedAddr,
655 sal_Int32 Port)
657 rtl_String* strDottedAddr=0;
658 oslSocketAddr Addr;
659 sal_Char* pszDottedAddr=0;
661 if ( ustrDottedAddr != 0 )
663 rtl_uString2String( &strDottedAddr,
664 rtl_uString_getStr(ustrDottedAddr),
665 rtl_uString_getLength(ustrDottedAddr),
666 RTL_TEXTENCODING_UTF8,
667 OUSTRING_TO_OSTRING_CVTFLAGS);
668 pszDottedAddr = rtl_string_getStr(strDottedAddr);
672 Addr = osl_psz_createInetSocketAddr(pszDottedAddr, Port);
674 if ( strDottedAddr != 0 )
676 rtl_string_release(strDottedAddr);
679 return Addr;
682 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
683 const sal_Char* pszDottedAddr,
684 sal_Int32 Port)
686 oslSocketAddr pAddr = 0;
687 sal_Int32 Addr = inet_addr(pszDottedAddr);
688 if(Addr != -1)
690 /* valid dotted addr */
691 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
693 return pAddr;
696 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
698 oslSocketResult res = osl_Socket_Error;
700 OSL_ASSERT( pAddr );
701 OSL_ASSERT( pByteSeq );
703 if( pAddr && pByteSeq )
705 struct sockaddr_in * pSystemInetAddr;
707 OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
708 OSL_ASSERT( pByteSeq->nElements == 4 );
710 pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
711 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
712 res = osl_Socket_Ok;
714 return res;
717 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
719 oslSocketResult res = osl_Socket_Error;
721 OSL_ASSERT( pAddr );
722 OSL_ASSERT( ppByteSeq );
724 if( pAddr && ppByteSeq )
726 struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
727 rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
728 res = osl_Socket_Ok;
730 return res;
734 /** try to figure out a full-qualified hostname, by adding the current domain
735 as given by the domainname program to the given hostname.
736 This function MUST NOT call gethostbyname since pHostName already points
737 to data returned by gethostname and would be garbled: use gethostname_r
738 instead!
741 /* wrap around different interfaces to reentrant gethostbyname */
742 static struct hostent* _osl_gethostbyname_r (
743 const char *name, struct hostent *result,
744 char *buffer, int buflen, int *h_errnop)
746 #if defined(LINUX) || defined(ANDROID) || (defined(FREEBSD) && (__FreeBSD_version >= 601103)) || defined(DRAGONFLY)
747 struct hostent *__result; /* will be the same as result */
748 int __error;
749 __error = gethostbyname_r (name, result, buffer, buflen,
750 &__result, h_errnop);
751 return __error ? NULL : __result ;
752 #elif defined(AIX)
753 *h_errnop = gethostbyname_r (name, result, (struct hostent_data *)buffer);
754 (void)buflen;
755 return *h_errnop ? NULL : result ;
756 #else
757 return gethostbyname_r( name, result, buffer, buflen, h_errnop);
758 #endif
761 static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
763 struct hostent aHostByName;
764 struct hostent *pHostByName;
765 sal_Char pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
766 sal_Char *pFullQualifiedName = NULL;
767 int nErrorNo;
769 pHostByName = _osl_gethostbyname_r (
770 pHostName,
771 &aHostByName, pQualifiedHostBuffer,
772 sizeof(pQualifiedHostBuffer), &nErrorNo );
773 if (pHostByName != NULL)
775 pFullQualifiedName = strdup(pHostByName->h_name);
777 return pFullQualifiedName;
780 static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
782 /* a FQDN (aka 'hostname.domain.top_level_domain' )
783 * is a name which contains a dot '.' in it ( would
784 * match as well for 'hostname.' but is good enough
785 * for now )*/
786 return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
789 struct oslHostAddrImpl
791 sal_Char *pHostName;
792 oslSocketAddr pSockAddr;
795 static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
797 oslHostAddr pAddr= NULL;
798 oslSocketAddr pSockAddr = 0;
800 sal_Char *cn;
802 if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
803 return ((oslHostAddr)NULL);
805 if (_osl_isFullQualifiedDomainName(he->h_name))
807 cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
808 OSL_ASSERT(cn);
809 if (cn == NULL)
810 return ((oslHostAddr)NULL);
812 strcpy(cn, he->h_name);
814 else
816 cn =_osl_getFullQualifiedDomainName (he->h_name);
817 OSL_ASSERT(cn);
818 if (cn == NULL)
819 return ((oslHostAddr)NULL);
822 pSockAddr = __osl_createSocketAddr();
823 OSL_ASSERT(pSockAddr);
824 if (pSockAddr == NULL)
826 free(cn);
827 return ((oslHostAddr)NULL);
830 pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
831 if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
833 struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
834 memcpy (
835 &(sin->sin_addr.s_addr),
836 he->h_addr_list[0],
837 he->h_length);
839 else
841 /* unknown address family */
842 /* future extensions for new families might be implemented here */
844 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.");
845 OSL_ASSERT(sal_False);
847 __osl_destroySocketAddr( pSockAddr );
848 free (cn);
849 return ((oslHostAddr)NULL);
852 pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
853 OSL_ASSERT(pAddr);
854 if (pAddr == NULL)
856 __osl_destroySocketAddr( pSockAddr );
857 free (cn);
858 return ((oslHostAddr)NULL);
861 pAddr->pHostName= cn;
862 pAddr->pSockAddr= pSockAddr;
864 return pAddr;
867 oslHostAddr SAL_CALL osl_createHostAddr (
868 rtl_uString *ustrHostname,
869 const oslSocketAddr Addr)
871 oslHostAddr HostAddr;
872 rtl_String* strHostname=0;
873 sal_Char* pszHostName=0;
875 if ( ustrHostname != 0 )
877 rtl_uString2String( &strHostname,
878 rtl_uString_getStr(ustrHostname),
879 rtl_uString_getLength(ustrHostname),
880 RTL_TEXTENCODING_UTF8,
881 OUSTRING_TO_OSTRING_CVTFLAGS );
882 pszHostName = rtl_string_getStr(strHostname);
885 HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
887 if ( strHostname != 0 )
889 rtl_string_release(strHostname);
892 return HostAddr;
895 oslHostAddr SAL_CALL osl_psz_createHostAddr (
896 const sal_Char *pszHostname,
897 const oslSocketAddr pAddr)
899 oslHostAddr pHostAddr;
900 sal_Char *cn;
902 OSL_ASSERT(pszHostname && pAddr);
903 if ((pszHostname == NULL) || (pAddr == NULL))
904 return ((oslHostAddr)NULL);
906 cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
907 OSL_ASSERT(cn);
908 if (cn == NULL)
909 return ((oslHostAddr)NULL);
911 strcpy (cn, pszHostname);
913 pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
914 OSL_ASSERT(pHostAddr);
915 if (pHostAddr == NULL)
917 free (cn);
918 return ((oslHostAddr)NULL);
921 pHostAddr->pHostName= cn;
922 pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
924 return pHostAddr;
927 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
929 oslHostAddr HostAddr;
930 rtl_String* strHostname=0;
931 sal_Char* pszHostName=0;
933 if ( ustrHostname != 0 )
935 rtl_uString2String( &strHostname,
936 rtl_uString_getStr(ustrHostname),
937 rtl_uString_getLength(ustrHostname),
938 RTL_TEXTENCODING_UTF8,
939 OUSTRING_TO_OSTRING_CVTFLAGS );
940 pszHostName=rtl_string_getStr(strHostname);
943 HostAddr = osl_psz_createHostAddrByName(pszHostName);
945 if ( strHostname != 0 )
947 rtl_string_release(strHostname);
950 return HostAddr;
953 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
955 struct hostent aHe;
956 struct hostent *pHe;
957 sal_Char heBuffer[ MAX_HOSTBUFFER_SIZE ];
958 int nErrorNo;
960 pHe = _osl_gethostbyname_r (
961 pszHostname,
962 &aHe, heBuffer,
963 sizeof(heBuffer), &nErrorNo );
965 return _osl_hostentToHostAddr (pHe);
968 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
970 OSL_ASSERT(pAddr);
972 if (pAddr == NULL)
973 return ((oslHostAddr)NULL);
975 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
977 const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
978 struct hostent *he;
980 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
981 return ((oslHostAddr)NULL);
983 he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
984 sizeof (sin->sin_addr),
985 sin->sin_family);
986 return _osl_hostentToHostAddr (he);
989 return ((oslHostAddr)NULL);
992 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
994 OSL_ASSERT(pAddr);
996 if (pAddr)
997 return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
998 else
999 return ((oslHostAddr)NULL);
1002 void SAL_CALL osl_getHostnameOfHostAddr (
1003 const oslHostAddr Addr,
1004 rtl_uString **ustrHostname)
1006 const sal_Char* pHostname=0;
1008 pHostname = osl_psz_getHostnameOfHostAddr(Addr);
1010 rtl_uString_newFromAscii (ustrHostname, pHostname);
1012 return;
1015 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1017 if (pAddr)
1018 return pAddr->pHostName;
1019 else
1020 return NULL;
1023 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1025 OSL_ASSERT(pAddr);
1027 if (pAddr)
1028 return ((oslSocketAddr)(pAddr->pSockAddr));
1029 else
1030 return NULL;
1033 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1035 if (pAddr)
1037 if (pAddr->pHostName)
1038 free (pAddr->pHostName);
1039 if (pAddr->pSockAddr)
1040 osl_destroySocketAddr (pAddr->pSockAddr);
1041 free (pAddr);
1045 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1047 oslSocketResult Result;
1048 sal_Char pszHostname[1024];
1050 pszHostname[0] = '\0';
1052 Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1054 rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1056 return Result;
1059 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1060 sal_Char *pBuffer, sal_uInt32 nBufLen)
1062 static sal_Char LocalHostname[256] = "";
1064 if (strlen(LocalHostname) == 0)
1066 const sal_Char *pStr;
1068 #ifdef SYSV
1069 struct utsname uts;
1071 if (uname(&uts) < 0)
1072 return osl_Socket_Error;
1074 if ((strlen(uts.nodename) + 1) > nBufLen)
1075 return osl_Socket_Error;
1077 strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1078 #else /* BSD compatible */
1080 if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1081 return osl_Socket_Error;
1082 LocalHostname[sizeof(LocalHostname)-1] = 0;
1083 #endif /* SYSV */
1085 /* check if we have an FQDN */
1086 if (strchr(LocalHostname, '.') == NULL)
1088 oslHostAddr Addr;
1090 /* no, determine it via dns */
1091 Addr = osl_psz_createHostAddrByName(LocalHostname);
1093 if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1095 strcpy(LocalHostname, pStr);
1097 osl_destroyHostAddr(Addr);
1101 if (strlen(LocalHostname) > 0)
1103 strncpy(pBuffer, LocalHostname, nBufLen);
1104 pBuffer[nBufLen - 1] = '\0';
1106 return osl_Socket_Ok;
1109 return osl_Socket_Error;
1112 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1114 oslSocketAddr Addr;
1115 rtl_String* strHostname=0;
1116 sal_Char* pszHostName=0;
1118 if ( ustrHostname != 0 )
1120 rtl_uString2String( &strHostname,
1121 rtl_uString_getStr(ustrHostname),
1122 rtl_uString_getLength(ustrHostname),
1123 RTL_TEXTENCODING_UTF8,
1124 OUSTRING_TO_OSTRING_CVTFLAGS );
1125 pszHostName = rtl_string_getStr(strHostname);
1129 Addr = osl_psz_resolveHostname(pszHostName);
1131 if ( strHostname != 0 )
1133 rtl_string_release(strHostname);
1137 return Addr;
1141 oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1143 struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1145 if (pAddr)
1147 oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1149 osl_destroyHostAddr(pAddr);
1151 return (SockAddr);
1154 return ((oslSocketAddr)NULL);
1157 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1159 sal_Int32 nPort;
1160 rtl_String* strServicename=0;
1161 rtl_String* strProtocol=0;
1162 sal_Char* pszServiceName=0;
1163 sal_Char* pszProtocol=0;
1165 if ( ustrServicename != 0 )
1167 rtl_uString2String( &strServicename,
1168 rtl_uString_getStr(ustrServicename),
1169 rtl_uString_getLength(ustrServicename),
1170 RTL_TEXTENCODING_UTF8,
1171 OUSTRING_TO_OSTRING_CVTFLAGS );
1172 pszServiceName = rtl_string_getStr(strServicename);
1175 if ( ustrProtocol != 0 )
1177 rtl_uString2String( &strProtocol,
1178 rtl_uString_getStr(ustrProtocol),
1179 rtl_uString_getLength(ustrProtocol),
1180 RTL_TEXTENCODING_UTF8,
1181 OUSTRING_TO_OSTRING_CVTFLAGS );
1182 pszProtocol = rtl_string_getStr(strProtocol);
1185 nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1187 if ( strServicename != 0 )
1189 rtl_string_release(strServicename);
1192 if ( strProtocol != 0 )
1194 rtl_string_release(strProtocol);
1198 return nPort;
1202 sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1203 const sal_Char* pszProtocol)
1205 struct servent* ps;
1207 ps= getservbyname(pszServicename, pszProtocol);
1209 if (ps != 0)
1210 return ntohs(ps->s_port);
1212 return OSL_INVALID_PORT;
1215 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1217 __osl_destroySocketAddr( pAddr );
1220 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1222 OSL_ASSERT(pAddr);
1224 if (pAddr)
1225 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1226 else
1227 return osl_Socket_FamilyInvalid;
1230 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1232 OSL_ASSERT(pAddr);
1233 if( pAddr )
1235 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1237 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1238 return ntohs(pSystemInetAddr->sin_port);
1240 return OSL_INVALID_PORT;
1243 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1245 OSL_ASSERT(pAddr);
1246 if( pAddr )
1248 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1249 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1251 pSystemInetAddr->sin_port= htons((short)Port);
1252 return sal_True;
1256 /* this is not a inet-addr => can't set port */
1257 return sal_False;
1260 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1262 oslSocketResult Result;
1263 sal_Char pszHostname[1024];
1265 pszHostname[0] = '\0';
1267 Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1269 rtl_uString_newFromAscii(ustrHostname,pszHostname);
1271 return Result;
1275 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1276 sal_Char *pBuffer, sal_uInt32 BufferSize)
1278 oslHostAddr pHostAddr= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1280 if (pHostAddr)
1282 strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1284 pBuffer[BufferSize - 1] = '\0';
1286 osl_destroyHostAddr(pHostAddr);
1288 return osl_Socket_Ok;
1291 return osl_Socket_Error;
1294 /*****************************************************************************/
1295 /* osl_getDottedInetAddrOfSocketAddr */
1296 /*****************************************************************************/
1297 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1299 oslSocketResult Result;
1300 sal_Char pszDottedInetAddr[1024];
1302 pszDottedInetAddr[0] = '\0';
1304 Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1306 rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1308 return Result;
1312 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1313 sal_Char *pBuffer, sal_uInt32 BufferSize)
1315 OSL_ASSERT(pAddr);
1317 if( pAddr )
1319 struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1321 if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1323 strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1324 pBuffer[BufferSize - 1] = '\0';
1326 return osl_Socket_Ok;
1330 return osl_Socket_Error;
1333 oslSocket SAL_CALL osl_createSocket(oslAddrFamily Family,
1334 oslSocketType Type,
1335 oslProtocol Protocol)
1337 int Flags;
1338 oslSocket pSocket;
1340 /* alloc memory */
1341 pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1343 /* create socket */
1344 pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1345 TYPE_TO_NATIVE(Type),
1346 PROTOCOL_TO_NATIVE(Protocol));
1348 /* creation failed => free memory */
1349 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1351 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1352 errno,
1353 strerror(errno));
1355 __osl_destroySocketImpl((pSocket));
1356 pSocket= 0;
1358 else
1360 /* set close-on-exec flag */
1361 if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1363 Flags |= FD_CLOEXEC;
1364 if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1366 pSocket->m_nLastError=errno;
1367 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1368 errno,
1369 strerror(errno));
1372 else
1374 pSocket->m_nLastError=errno;
1378 return pSocket;
1381 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1383 osl_atomic_increment( &(pSocket->m_nRefCount ) );
1386 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1388 if( pSocket && 0 == osl_atomic_decrement( &(pSocket->m_nRefCount) ) )
1390 #if defined(LINUX)
1391 if ( pSocket->m_bIsAccepting == sal_True )
1393 OSL_FAIL("osl_destroySocket : attempt to destroy socket while accepting\n");
1394 return;
1396 #endif /* LINUX */
1397 osl_closeSocket( pSocket );
1398 __osl_destroySocketImpl( pSocket );
1402 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1404 int nRet;
1405 int nFD;
1407 /* socket already invalid */
1408 if(pSocket==0)
1409 return;
1411 pSocket->m_nLastError=0;
1412 nFD = pSocket->m_Socket;
1414 if (nFD == OSL_INVALID_SOCKET)
1415 return;
1417 pSocket->m_Socket = OSL_INVALID_SOCKET;
1419 #if defined(LINUX)
1420 pSocket->m_bIsInShutdown = sal_True;
1422 if ( pSocket->m_bIsAccepting == sal_True )
1424 int nConnFD;
1425 union {
1426 struct sockaddr aSockAddr;
1427 struct sockaddr_in aSockAddrIn;
1428 } s;
1429 socklen_t nSockLen = sizeof(s.aSockAddr);
1431 nRet = getsockname(nFD, &s.aSockAddr, &nSockLen);
1432 if ( nRet < 0 )
1434 OSL_TRACE("getsockname call failed with error: %s", strerror(errno));
1437 if ( s.aSockAddr.sa_family == AF_INET )
1439 if ( s.aSockAddrIn.sin_addr.s_addr == htonl(INADDR_ANY) )
1441 s.aSockAddrIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1444 nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1445 if ( nConnFD < 0 )
1447 OSL_TRACE("socket call failed with error: %s", strerror(errno));
1450 nRet = connect(nConnFD, &s.aSockAddr, sizeof(s.aSockAddr));
1451 if ( nRet < 0 )
1453 OSL_TRACE("connect call failed with error: %s", strerror(errno));
1455 close(nConnFD);
1457 pSocket->m_bIsAccepting = sal_False;
1459 #endif /* LINUX */
1461 nRet=close(nFD);
1462 if ( nRet != 0 )
1464 pSocket->m_nLastError=errno;
1465 OSL_TRACE("closeSocket close error '%s'",strerror(errno));
1468 pSocket->m_Socket = OSL_INVALID_SOCKET;
1471 /*****************************************************************************/
1472 /* osl_getLocalAddrOfSocket */
1473 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1474 /* are the same! I don't like it very much but see no other easy way to conceal */
1475 /* the struct sockaddr from the eyes of the user. */
1476 /*****************************************************************************/
1477 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1479 socklen_t AddrLen;
1480 struct sockaddr Addr;
1481 oslSocketAddr pAddr;
1483 if (pSocket == NULL) /* ENOTSOCK */
1484 return ((oslSocketAddr)NULL);
1486 AddrLen= sizeof(struct sockaddr);
1488 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1489 return ((oslSocketAddr)NULL);
1491 pAddr = __osl_createSocketAddrFromSystem( &Addr );
1492 return pAddr;
1495 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1497 socklen_t AddrLen;
1498 struct sockaddr Addr;
1500 OSL_ASSERT(pSocket);
1501 if ( pSocket == 0 )
1503 return 0;
1506 pSocket->m_nLastError=0;
1507 AddrLen= sizeof(struct sockaddr);
1509 if(getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1511 pSocket->m_nLastError=errno;
1512 return 0;
1514 return __osl_createSocketAddrFromSystem( &Addr );
1517 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
1518 oslSocketAddr pAddr)
1520 int nRet;
1522 OSL_ASSERT(pSocket && pAddr );
1523 if ( pSocket == 0 || pAddr == 0 )
1525 return sal_False;
1528 pSocket->m_nLastError=0;
1530 nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1532 if ( nRet == OSL_SOCKET_ERROR)
1534 pSocket->m_nLastError=errno;
1535 return sal_False;
1538 return sal_True;
1541 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
1542 sal_Int32 MaxPendingConnections)
1544 int nRet;
1546 OSL_ASSERT(pSocket);
1547 if ( pSocket == 0 )
1549 return sal_False;
1552 pSocket->m_nLastError=0;
1554 nRet = listen(pSocket->m_Socket,
1555 MaxPendingConnections == -1 ?
1556 SOMAXCONN :
1557 MaxPendingConnections);
1558 if ( nRet == OSL_SOCKET_ERROR)
1560 pSocket->m_nLastError=errno;
1561 return sal_False;
1564 return sal_True;
1567 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
1568 oslSocketAddr pAddr,
1569 const TimeValue* pTimeout)
1571 fd_set WriteSet;
1572 fd_set ExcptSet;
1573 int ReadyHandles;
1574 struct timeval tv;
1575 oslSocketResult Result= osl_Socket_Ok;
1577 OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
1579 if ( pSocket == 0 )
1581 return osl_Socket_Error;
1584 pSocket->m_nLastError=0;
1586 if (osl_isNonBlockingMode(pSocket))
1588 if (connect(pSocket->m_Socket,
1589 &(pAddr->m_sockaddr),
1590 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1591 return osl_Socket_Ok;
1592 else
1593 if (errno == EWOULDBLOCK || errno == EINPROGRESS)
1595 pSocket->m_nLastError=EINPROGRESS;
1596 return osl_Socket_InProgress;
1600 pSocket->m_nLastError=errno;
1601 OSL_TRACE("can't connect : '%s'",strerror(errno));
1602 return osl_Socket_Error;
1605 /* set socket temporarily to non-blocking */
1606 OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
1608 /* initiate connect */
1609 if(connect(pSocket->m_Socket,
1610 &(pAddr->m_sockaddr),
1611 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1613 /* immediate connection */
1614 osl_enableNonBlockingMode(pSocket, sal_False);
1616 return osl_Socket_Ok;
1618 else
1620 /* really an error or just delayed? */
1621 if (errno != EINPROGRESS)
1623 pSocket->m_nLastError=errno;
1624 OSL_TRACE(
1625 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
1626 errno, strerror(errno));
1628 osl_enableNonBlockingMode(pSocket, sal_False);
1629 return osl_Socket_Error;
1634 /* prepare select set for socket */
1635 FD_ZERO(&WriteSet);
1636 FD_ZERO(&ExcptSet);
1637 FD_SET(pSocket->m_Socket, &WriteSet);
1638 FD_SET(pSocket->m_Socket, &ExcptSet);
1640 /* prepare timeout */
1641 if (pTimeout)
1643 /* divide milliseconds into seconds and microseconds */
1644 tv.tv_sec= pTimeout->Seconds;
1645 tv.tv_usec= pTimeout->Nanosec / 1000L;
1648 /* select */
1649 ReadyHandles= select(pSocket->m_Socket+1,
1651 PTR_FD_SET(WriteSet),
1652 PTR_FD_SET(ExcptSet),
1653 (pTimeout) ? &tv : 0);
1655 if (ReadyHandles > 0) /* connected */
1657 if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
1659 int nErrorCode = 0;
1660 socklen_t nErrorSize = sizeof( nErrorCode );
1662 int nSockOpt;
1664 nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
1665 &nErrorCode, &nErrorSize );
1666 if ( (nSockOpt == 0) && (nErrorCode == 0))
1667 Result = osl_Socket_Ok;
1668 else
1669 Result = osl_Socket_Error;
1671 else
1673 Result= osl_Socket_Error;
1676 else if (ReadyHandles < 0) /* error */
1678 if (errno == EBADF) /* most probably interrupted by close() */
1680 /* do not access pSockImpl because it is about to be or */
1681 /* already destroyed */
1682 return osl_Socket_Interrupted;
1684 else
1686 pSocket->m_nLastError=errno;
1687 Result= osl_Socket_Error;
1690 else /* timeout */
1692 pSocket->m_nLastError=errno;
1693 Result= osl_Socket_TimedOut;
1696 osl_enableNonBlockingMode(pSocket, sal_False);
1698 return Result;
1702 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
1703 oslSocketAddr* ppAddr)
1705 struct sockaddr Addr;
1706 int Connection, Flags;
1707 oslSocket pConnectionSockImpl;
1709 socklen_t AddrLen = sizeof(struct sockaddr);
1710 OSL_ASSERT(pSocket);
1711 if ( pSocket == 0 )
1713 return 0;
1716 pSocket->m_nLastError=0;
1717 #if defined(LINUX)
1718 pSocket->m_bIsAccepting = sal_True;
1719 #endif /* LINUX */
1721 if( ppAddr && *ppAddr )
1723 osl_destroySocketAddr( *ppAddr );
1724 *ppAddr = 0;
1727 /* prevent Linux EINTR behaviour */
1730 Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
1731 } while (Connection == -1 && errno == EINTR);
1734 /* accept failed? */
1735 if( Connection == OSL_SOCKET_ERROR )
1737 pSocket->m_nLastError=errno;
1738 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'",strerror(errno));
1740 #if defined(LINUX)
1741 pSocket->m_bIsAccepting = sal_False;
1742 #endif /* LINUX */
1743 return 0;
1746 OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
1749 #if defined(LINUX)
1750 if ( pSocket->m_bIsInShutdown == sal_True )
1752 close(Connection);
1753 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept");
1754 return 0;
1756 #endif /* LINUX */
1759 if(ppAddr)
1761 *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
1764 /* alloc memory */
1765 pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1767 /* set close-on-exec flag */
1768 if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
1770 Flags |= FD_CLOEXEC;
1771 if (fcntl(Connection, F_SETFD, Flags) == -1)
1773 pSocket->m_nLastError=errno;
1774 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
1775 errno,
1776 strerror(errno));
1781 pConnectionSockImpl->m_Socket = Connection;
1782 pConnectionSockImpl->m_nLastError = 0;
1783 #if defined(LINUX)
1784 pConnectionSockImpl->m_bIsAccepting = sal_False;
1786 pSocket->m_bIsAccepting = sal_False;
1787 #endif /* LINUX */
1788 return pConnectionSockImpl;
1791 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
1792 void* pBuffer,
1793 sal_uInt32 BytesToRead,
1794 oslSocketMsgFlag Flag)
1796 int nRead;
1798 OSL_ASSERT(pSocket);
1799 if ( pSocket == 0 )
1801 OSL_TRACE("osl_receiveSocket : Invalid socket");
1802 return -1;
1805 pSocket->m_nLastError=0;
1809 nRead = recv(pSocket->m_Socket,
1810 (sal_Char*)pBuffer,
1811 BytesToRead,
1812 MSG_FLAG_TO_NATIVE(Flag));
1813 } while ( nRead < 0 && errno == EINTR );
1815 if ( nRead < 0 )
1817 pSocket->m_nLastError=errno;
1818 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
1820 else if ( nRead == 0 )
1822 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
1825 return nRead;
1829 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
1830 oslSocketAddr pSenderAddr,
1831 void* pBuffer,
1832 sal_uInt32 BufferSize,
1833 oslSocketMsgFlag Flag)
1835 int nRead;
1836 struct sockaddr *pSystemSockAddr = 0;
1837 socklen_t AddrLen = 0;
1838 if( pSenderAddr )
1840 AddrLen = sizeof( struct sockaddr );
1841 pSystemSockAddr = &(pSenderAddr->m_sockaddr);
1844 OSL_ASSERT(pSocket);
1845 if ( pSocket == 0 )
1847 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
1848 return -1;
1851 pSocket->m_nLastError=0;
1853 nRead = recvfrom(pSocket->m_Socket,
1854 (sal_Char*)pBuffer,
1855 BufferSize,
1856 MSG_FLAG_TO_NATIVE(Flag),
1857 pSystemSockAddr,
1858 &AddrLen);
1860 if ( nRead < 0 )
1862 pSocket->m_nLastError=errno;
1863 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
1865 else if ( nRead == 0 )
1867 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
1870 return nRead;
1873 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
1874 const void* pBuffer,
1875 sal_uInt32 BytesToSend,
1876 oslSocketMsgFlag Flag)
1878 int nWritten;
1880 OSL_ASSERT(pSocket);
1881 if ( pSocket == 0 )
1883 OSL_TRACE("osl_sendSocket : Invalid socket");
1884 return -1;
1887 pSocket->m_nLastError=0;
1891 nWritten = send(pSocket->m_Socket,
1892 (sal_Char*)pBuffer,
1893 BytesToSend,
1894 MSG_FLAG_TO_NATIVE(Flag));
1895 } while ( nWritten < 0 && errno == EINTR );
1898 if ( nWritten < 0 )
1900 pSocket->m_nLastError=errno;
1901 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
1903 else if ( nWritten == 0 )
1905 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
1908 return nWritten;
1911 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
1912 oslSocketAddr ReceiverAddr,
1913 const void* pBuffer,
1914 sal_uInt32 BytesToSend,
1915 oslSocketMsgFlag Flag)
1917 int nWritten;
1919 struct sockaddr *pSystemSockAddr = 0;
1920 int AddrLen = 0;
1921 if( ReceiverAddr )
1923 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1924 AddrLen = sizeof( struct sockaddr );
1927 OSL_ASSERT(pSocket);
1928 if ( pSocket == 0 )
1930 OSL_TRACE("osl_sendToSocket : Invalid socket");
1931 return -1;
1934 pSocket->m_nLastError=0;
1936 /* ReceiverAddr might be 0 when used on a connected socket. */
1937 /* Then sendto should behave like send. */
1939 nWritten = sendto(pSocket->m_Socket,
1940 (sal_Char*)pBuffer,
1941 BytesToSend,
1942 MSG_FLAG_TO_NATIVE(Flag),
1943 pSystemSockAddr,
1944 AddrLen);
1946 if ( nWritten < 0 )
1948 pSocket->m_nLastError=errno;
1949 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
1951 else if ( nWritten == 0 )
1953 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
1956 return nWritten;
1959 sal_Int32 SAL_CALL osl_readSocket (
1960 oslSocket pSocket, void *pBuffer, sal_Int32 n )
1962 sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
1963 sal_uInt32 BytesRead= 0;
1964 sal_uInt32 BytesToRead= n;
1966 OSL_ASSERT( pSocket);
1968 /* loop until all desired bytes were read or an error occurred */
1969 while (BytesToRead > 0)
1971 sal_Int32 RetVal;
1972 RetVal= osl_receiveSocket(pSocket,
1973 Ptr,
1974 BytesToRead,
1975 osl_Socket_MsgNormal);
1977 /* error occurred? */
1978 if(RetVal <= 0)
1980 break;
1983 BytesToRead -= RetVal;
1984 BytesRead += RetVal;
1985 Ptr += RetVal;
1988 return BytesRead;
1991 sal_Int32 SAL_CALL osl_writeSocket(
1992 oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1994 /* loop until all desired bytes were send or an error occurred */
1995 sal_uInt32 BytesSend= 0;
1996 sal_uInt32 BytesToSend= n;
1997 sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
1999 OSL_ASSERT( pSocket );
2001 while (BytesToSend > 0)
2003 sal_Int32 RetVal;
2005 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
2007 /* error occurred? */
2008 if(RetVal <= 0)
2010 break;
2013 BytesToSend -= RetVal;
2014 BytesSend += RetVal;
2015 Ptr += RetVal;
2018 return BytesSend;
2021 #ifdef HAVE_POLL_H /* poll() */
2023 sal_Bool __osl_socket_poll (
2024 oslSocket pSocket,
2025 const TimeValue* pTimeout,
2026 short nEvent)
2028 struct pollfd fds;
2029 int timeout;
2030 int result;
2032 OSL_ASSERT(0 != pSocket);
2033 if (0 == pSocket)
2034 return sal_False; /* EINVAL */
2036 pSocket->m_nLastError = 0;
2038 fds.fd = pSocket->m_Socket;
2039 fds.events = nEvent;
2040 fds.revents = 0;
2042 timeout = -1;
2043 if (pTimeout)
2045 /* Convert to [ms] */
2046 timeout = pTimeout->Seconds * 1000;
2047 timeout += pTimeout->Nanosec / (1000 * 1000);
2050 result = poll (&fds, 1, timeout);
2051 if (result < 0)
2053 pSocket->m_nLastError = errno;
2054 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2055 errno, strerror(errno));
2056 return sal_False;
2058 if (result == 0)
2060 /* Timeout */
2061 return sal_False;
2064 return ((fds.revents & nEvent) == nEvent);
2067 #else /* select() */
2069 sal_Bool __osl_socket_poll (
2070 oslSocket pSocket,
2071 const TimeValue* pTimeout,
2072 short nEvent)
2074 fd_set fds;
2075 struct timeval tv;
2076 int result;
2078 OSL_ASSERT(0 != pSocket);
2079 if (0 == pSocket)
2080 return sal_False; /* EINVAL */
2082 pSocket->m_nLastError = 0;
2084 FD_ZERO(&fds);
2085 FD_SET(pSocket->m_Socket, &fds);
2087 if (pTimeout)
2089 /* Convert to 'timeval' */
2090 tv.tv_sec = pTimeout->Seconds;
2091 tv.tv_usec = pTimeout->Nanosec / 1000;
2094 result = select (
2095 pSocket->m_Socket + 1,
2096 (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2097 (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2098 (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2099 (pTimeout) ? &tv : NULL);
2101 if (result < 0)
2103 pSocket->m_nLastError = errno;
2104 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2105 errno, strerror(errno));
2106 return sal_False;
2108 if (result == 0)
2110 /* Timeout */
2111 return sal_False;
2114 return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2117 #endif /* HAVE_POLL_H */
2119 sal_Bool SAL_CALL osl_isReceiveReady (
2120 oslSocket pSocket, const TimeValue* pTimeout)
2122 OSL_ASSERT(pSocket);
2123 if (pSocket == NULL)
2125 /* ENOTSOCK */
2126 return sal_False;
2129 return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2132 sal_Bool SAL_CALL osl_isSendReady (
2133 oslSocket pSocket, const TimeValue* pTimeout)
2135 OSL_ASSERT(pSocket);
2136 if (pSocket == NULL)
2138 /* ENOTSOCK */
2139 return sal_False;
2142 return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2145 sal_Bool SAL_CALL osl_isExceptionPending (
2146 oslSocket pSocket, const TimeValue* pTimeout)
2148 OSL_ASSERT(pSocket);
2149 if (pSocket == NULL)
2151 /* ENOTSOCK */
2152 return sal_False;
2155 return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2158 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2159 oslSocketDirection Direction)
2161 int nRet;
2163 OSL_ASSERT(pSocket);
2164 if ( pSocket == 0 )
2166 return sal_False;
2169 pSocket->m_nLastError=0;
2171 nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2172 if (nRet != 0 )
2174 pSocket->m_nLastError=errno;
2175 OSL_TRACE("shutdown error '%s'",strerror(errno));
2177 return (nRet==0);
2181 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2182 oslSocketOptionLevel Level,
2183 oslSocketOption Option,
2184 void* pBuffer,
2185 sal_uInt32 BufferLen)
2187 socklen_t nOptLen = (socklen_t) BufferLen;
2189 OSL_ASSERT(pSocket);
2190 if ( pSocket == 0 )
2192 return -1;
2195 pSocket->m_nLastError=0;
2197 if(getsockopt(pSocket->m_Socket,
2198 OPTION_LEVEL_TO_NATIVE(Level),
2199 OPTION_TO_NATIVE(Option),
2200 (sal_Char*)pBuffer,
2201 &nOptLen) == -1)
2203 pSocket->m_nLastError=errno;
2204 return -1;
2207 return BufferLen;
2210 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2211 oslSocketOptionLevel Level,
2212 oslSocketOption Option,
2213 void* pBuffer,
2214 sal_uInt32 BufferLen)
2216 int nRet;
2218 OSL_ASSERT(pSocket);
2219 if ( pSocket == 0 )
2221 return sal_False;
2224 pSocket->m_nLastError=0;
2226 nRet = setsockopt(pSocket->m_Socket,
2227 OPTION_LEVEL_TO_NATIVE(Level),
2228 OPTION_TO_NATIVE(Option),
2229 (sal_Char*)pBuffer,
2230 BufferLen);
2232 if ( nRet < 0 )
2234 pSocket->m_nLastError=errno;
2235 return sal_False;
2238 return sal_True;
2241 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2242 sal_Bool On)
2244 int flags;
2245 int nRet;
2247 OSL_ASSERT(pSocket);
2248 if ( pSocket == 0 )
2250 return sal_False;
2253 pSocket->m_nLastError=0;
2255 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2257 if (On)
2258 flags |= O_NONBLOCK;
2259 else
2260 flags &= ~(O_NONBLOCK);
2262 nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2264 if ( nRet < 0 )
2266 pSocket->m_nLastError=errno;
2267 return sal_False;
2270 return sal_True;
2273 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2275 int flags;
2277 OSL_ASSERT(pSocket);
2278 if ( pSocket == 0 )
2280 return sal_False;
2283 pSocket->m_nLastError=0;
2285 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2287 if (flags == -1 || !(flags & O_NONBLOCK))
2288 return sal_False;
2289 else
2290 return sal_True;
2293 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2295 int Type=0;
2296 socklen_t TypeSize= sizeof(Type);
2298 OSL_ASSERT(pSocket);
2299 if ( pSocket == 0 )
2301 return osl_Socket_TypeInvalid;
2304 pSocket->m_nLastError=0;
2306 if(getsockopt(pSocket->m_Socket,
2307 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2308 OPTION_TO_NATIVE(osl_Socket_OptionType),
2309 (sal_Char*)&Type,
2310 &TypeSize) == -1)
2312 /* error */
2313 pSocket->m_nLastError=errno;
2314 return osl_Socket_TypeInvalid;
2317 return TYPE_FROM_NATIVE(Type);
2321 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2323 sal_Char pszError[1024];
2325 pszError[0] = '\0';
2327 osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2329 rtl_uString_newFromAscii(ustrError,pszError);
2331 return;
2335 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2337 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2338 pBuffer[BufferSize-1]= '\0';
2340 if ( pSocket == 0 )
2342 strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2343 return;
2346 strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2347 return;
2350 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2352 if ( pSocket == 0 )
2354 return ERROR_FROM_NATIVE(EINVAL);
2357 return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2360 typedef struct _TSocketSetImpl
2362 int m_MaxHandle; /* for select(), the largest descriptor in the set */
2363 fd_set m_Set; /* the set of descriptors */
2365 } TSocketSetImpl;
2367 oslSocketSet SAL_CALL osl_createSocketSet()
2369 TSocketSetImpl* pSet;
2371 pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2373 OSL_ASSERT(pSet);
2375 if(pSet)
2377 pSet->m_MaxHandle= 0;
2378 FD_ZERO(&pSet->m_Set);
2381 return (oslSocketSet)pSet;
2384 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2386 if(Set)
2387 free(Set);
2390 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2392 TSocketSetImpl* pSet;
2393 OSL_ASSERT(Set);
2394 if ( Set == 0 )
2396 return;
2399 pSet= (TSocketSetImpl*)Set;
2400 pSet->m_MaxHandle= 0;
2402 FD_ZERO(&pSet->m_Set);
2405 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2407 TSocketSetImpl* pSet;
2409 OSL_ASSERT(Set);
2410 OSL_ASSERT(pSocket);
2412 if ( Set == 0 || pSocket == 0)
2414 return;
2417 pSet= (TSocketSetImpl*)Set;
2419 /* correct max handle */
2420 if(pSocket->m_Socket > pSet->m_MaxHandle)
2421 pSet->m_MaxHandle= pSocket->m_Socket;
2422 FD_SET(pSocket->m_Socket, &pSet->m_Set);
2426 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
2428 TSocketSetImpl* pSet;
2430 OSL_ASSERT(Set);
2431 OSL_ASSERT(pSocket);
2433 if ( Set == 0 || pSocket == 0)
2435 return;
2438 pSet= (TSocketSetImpl*)Set;
2440 /* correct max handle */
2441 if(pSocket->m_Socket == pSet->m_MaxHandle)
2443 /* not optimal, since the next used descriptor might be */
2444 /* much smaller than m_Socket-1, but it will do */
2445 pSet->m_MaxHandle--;
2446 if(pSet->m_MaxHandle < 0)
2448 pSet->m_MaxHandle= 0; /* avoid underflow */
2452 FD_CLR(pSocket->m_Socket, &pSet->m_Set);
2455 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
2457 TSocketSetImpl* pSet;
2459 OSL_ASSERT(Set);
2460 OSL_ASSERT(pSocket);
2461 if ( Set == 0 || pSocket == 0 )
2463 return sal_False;
2466 pSet= (TSocketSetImpl*)Set;
2468 return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
2471 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
2472 oslSocketSet OutgoingSet,
2473 oslSocketSet OutOfBandSet,
2474 const TimeValue* pTimeout)
2476 int MaxHandle= 0;
2477 struct timeval tv;
2478 TSocketSetImpl* pInSet;
2479 TSocketSetImpl* pOutSet;
2480 TSocketSetImpl* pOOBSet;
2482 if (pTimeout)
2484 /* non-blocking call */
2485 tv.tv_sec = pTimeout->Seconds;
2486 tv.tv_usec = pTimeout->Nanosec / 1000L;
2489 /* map opaque data to impl-types */
2490 pInSet= (TSocketSetImpl*)IncomingSet;
2491 pOutSet= (TSocketSetImpl*)OutgoingSet;
2492 pOOBSet= (TSocketSetImpl*)OutOfBandSet;
2494 /* get max handle from all sets */
2495 if (pInSet)
2496 MaxHandle= pInSet->m_MaxHandle;
2498 if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
2499 MaxHandle= pOutSet->m_MaxHandle;
2501 if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
2502 MaxHandle= pOOBSet->m_MaxHandle;
2504 return select(MaxHandle+1,
2505 pInSet ? PTR_FD_SET(pInSet->m_Set) : 0,
2506 pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
2507 pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
2508 pTimeout ? &tv : 0);
2511 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */