lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / sal / osl / unx / socket.cxx
blobe4a70b5083a169cee80fd0c70ecd1d2abc179514
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.hxx"
22 #include <osl/socket.h>
23 #include <osl/mutex.h>
24 #include <osl/signal.h>
26 #include <rtl/alloc.h>
27 #include <rtl/byteseq.h>
28 #include <assert.h>
29 #include <sal/types.h>
30 #include <sal/log.hxx>
32 #include "sockimpl.hxx"
33 #include "unixerrnostring.hxx"
35 /* defines for poll */
36 #ifdef HAVE_POLL_H
37 #undef HAVE_POLL_H
38 #endif
40 #if defined(LINUX) || defined(NETBSD) || defined ( FREEBSD ) || \
41 defined (MACOSX) || defined (OPENBSD) || defined(DRAGONFLY)
42 #include <sys/poll.h>
43 #define HAVE_POLL_H
44 #endif /* HAVE_POLL_H */
46 #if defined(__sun)
47 #include <poll.h>
48 #define HAVE_POLL_H
49 #endif /* __sun */
51 #ifndef HAVE_POLL_H
52 #define POLLIN 0x0001
53 #define POLLOUT 0x0002
54 #define POLLPRI 0x0004
55 #endif /* HAVE_POLL_H */
57 /* defines for shutdown */
58 #define SD_RECEIVE 0
59 #define SD_SEND 1
60 #define SD_BOTH 2
63 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
64 I refrained from using sockaddr_in because of possible further
65 extensions of this socket-interface (IP-NG?).
66 The intention was to hide all Berkeley data-structures from
67 direct access past the osl-interface.
69 The current implementation is internet (IP) centered. All
70 the constructor-functions (osl_create...) take parameters
71 that will probably make sense only in the IP-environment
72 (e.g. because of using the dotted-address-format).
74 If the interface will be extended to host other protocol-
75 families, I expect no externally visible changes in the
76 existing functions. You'll probably need only new
77 constructor-functions who take the different address
78 formats into consideration (maybe a long dotted address
79 or whatever).
82 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
83 /* are the same! I don't like it very much but see no other easy way to */
84 /* conceal the struct sockaddr from the eyes of the user. */
86 #define OSL_INVALID_SOCKET -1
87 #define OSL_SOCKET_ERROR -1
89 /* Buffer size for gethostbyname */
90 #define MAX_HOSTBUFFER_SIZE 2048
92 static const unsigned long FamilyMap[]= {
93 AF_INET, /* osl_Socket_FamilyInet */
94 AF_IPX, /* osl_Socket_FamilyIpx */
95 0 /* osl_Socket_FamilyInvalid */
98 static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
100 oslAddrFamily i= oslAddrFamily(0);
102 while(i != osl_Socket_FamilyInvalid)
104 if(FamilyMap[i] == nativeType)
105 return i;
106 i = static_cast<oslAddrFamily>( i + 1 );
109 return i;
112 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
113 #define FAMILY_TO_NATIVE(x) static_cast<short>(FamilyMap[x])
115 static const sal_uInt32 ProtocolMap[]= {
116 0, /* osl_Socket_ProtocolIp */
117 NSPROTO_IPX, /* osl_Socket_ProtocolIpx */
118 NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
119 NSPROTO_SPXII, /* osl_Socket_ProtocolSpxII */
120 0 /* osl_Socket_ProtocolInvalid */
123 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
125 static const sal_uInt32 TypeMap[]= {
126 SOCK_STREAM, /* osl_Socket_TypeStream */
127 SOCK_DGRAM, /* osl_Socket_TypeDgram */
128 SOCK_RAW, /* osl_Socket_TypeRaw */
129 SOCK_RDM, /* osl_Socket_TypeRdm */
130 SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
131 0 /* osl_Socket_TypeInvalid */
134 static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
136 oslSocketType i= oslSocketType(0);
138 while(i != osl_Socket_TypeInvalid)
140 if(TypeMap[i] == nativeType)
141 return i;
142 i = static_cast<oslSocketType>(i + 1);
145 return i;
148 #define TYPE_TO_NATIVE(x) TypeMap[x]
149 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
151 static const sal_uInt32 OptionMap[]= {
152 SO_DEBUG, /* osl_Socket_OptionDebug */
153 SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
154 SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
155 SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
156 SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
157 SO_BROADCAST, /* osl_Socket_OptionBroadcast */
158 SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
159 SO_LINGER, /* osl_Socket_OptionLinger */
160 SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
161 SO_SNDBUF, /* osl_Socket_OptionSndBuf */
162 SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
163 SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
164 SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
165 SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
166 SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
167 SO_ERROR, /* osl_Socket_OptionError */
168 SO_TYPE, /* osl_Socket_OptionType */
169 TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
170 0 /* osl_Socket_OptionInvalid */
173 #define OPTION_TO_NATIVE(x) OptionMap[x]
175 static const sal_uInt32 OptionLevelMap[]= {
176 SOL_SOCKET, /* osl_Socket_LevelSocket */
177 IPPROTO_TCP, /* osl_Socket_LevelTcp */
178 0 /* osl_Socket_LevelInvalid */
181 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
183 static const sal_uInt32 SocketMsgFlagMap[]= {
184 0, /* osl_Socket_MsgNormal */
185 MSG_OOB, /* osl_Socket_MsgOOB */
186 MSG_PEEK, /* osl_Socket_MsgPeek */
187 MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
188 MSG_MAXIOVLEN, /* osl_Socket_MsgMaxIOVLen */
189 0 /* osl_Socket_MsgInvalid */
192 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
194 static const sal_uInt32 SocketDirection[]= {
195 SD_RECEIVE, /* osl_Socket_DirRead */
196 SD_SEND, /* osl_Socket_DirWrite */
197 SD_BOTH, /* osl_Socket_DirReadWrite */
198 0 /* osl_Socket_DirInvalid */
201 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
203 static const struct
205 int const errcode;
206 oslSocketError const error;
207 } SocketError[]= {
208 { 0, osl_Socket_E_None }, /* no error */
209 { ENOTSOCK, osl_Socket_E_NotSocket }, /* Socket operation on non-socket */
210 { EDESTADDRREQ, osl_Socket_E_DestAddrReq }, /* Destination address required */
211 { EMSGSIZE, osl_Socket_E_MsgSize }, /* Message too long */
212 { EPROTOTYPE, osl_Socket_E_Prototype }, /* Protocol wrong type for socket */
213 { ENOPROTOOPT, osl_Socket_E_NoProtocol }, /* Protocol not available */
214 { EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
215 #ifdef ESOCKTNOSUPPORT
216 { ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport }, /* Socket type not supported */
217 #endif
218 { EOPNOTSUPP, osl_Socket_E_OpNotSupport }, /* Operation not supported on socket */
219 { EPFNOSUPPORT, osl_Socket_E_PfNoSupport }, /* Protocol family not supported */
220 { EAFNOSUPPORT, osl_Socket_E_AfNoSupport }, /* Address family not supported by
221 protocol family */
222 { EADDRINUSE, osl_Socket_E_AddrInUse }, /* Address already in use */
223 { EADDRNOTAVAIL, osl_Socket_E_AddrNotAvail }, /* Can't assign requested address */
224 { ENETDOWN, osl_Socket_E_NetDown }, /* Network is down */
225 { ENETUNREACH, osl_Socket_E_NetUnreachable }, /* Network is unreachable */
226 { ENETRESET, osl_Socket_E_NetReset }, /* Network dropped connection because
227 of reset */
228 { ECONNABORTED, osl_Socket_E_ConnAborted }, /* Software caused connection abort */
229 { ECONNRESET, osl_Socket_E_ConnReset }, /* Connection reset by peer */
230 { ENOBUFS, osl_Socket_E_NoBufferSpace }, /* No buffer space available */
231 { EISCONN, osl_Socket_E_IsConnected }, /* Socket is already connected */
232 { ENOTCONN, osl_Socket_E_NotConnected }, /* Socket is not connected */
233 { ESHUTDOWN, osl_Socket_E_Shutdown }, /* Can't send after socket shutdown */
234 #ifdef ETOOMANYREFS
235 { ETOOMANYREFS, osl_Socket_E_TooManyRefs }, /* Too many references: can't splice */
236 #endif
237 { ETIMEDOUT, osl_Socket_E_TimedOut }, /* Connection timed out */
238 { ECONNREFUSED, osl_Socket_E_ConnRefused }, /* Connection refused */
239 { EHOSTDOWN, osl_Socket_E_HostDown }, /* Host is down */
240 { EHOSTUNREACH, osl_Socket_E_HostUnreachable }, /* No route to host */
241 { EWOULDBLOCK, osl_Socket_E_WouldBlock }, /* call would block on non-blocking socket */
242 { EALREADY, osl_Socket_E_Already }, /* operation already in progress */
243 { EINPROGRESS, osl_Socket_E_InProgress }, /* operation now in progress */
244 { EAGAIN, osl_Socket_E_WouldBlock }, /* same as EWOULDBLOCK */
245 { -1, osl_Socket_E_InvalidError }
248 static oslSocketError osl_SocketErrorFromNative(int nativeType)
250 int i = 0;
252 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
253 (SocketError[i].errcode != nativeType)) i++;
255 return SocketError[i].error;
258 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
260 static oslSocketAddr osl_psz_createInetSocketAddr (
261 const sal_Char* pszDottedAddr, sal_Int32 Port);
263 static oslHostAddr osl_psz_createHostAddr (
264 const sal_Char *pszHostname, const oslSocketAddr Addr);
266 static oslHostAddr osl_psz_createHostAddrByName (
267 const sal_Char *pszHostname);
269 static const sal_Char* osl_psz_getHostnameOfHostAddr (
270 const oslHostAddr Addr);
272 static oslSocketResult osl_psz_getLocalHostname (
273 sal_Char *pBuffer, sal_uInt32 nBufLen);
275 static oslSocketAddr osl_psz_resolveHostname (
276 const sal_Char* pszHostname);
278 static sal_Int32 osl_psz_getServicePort (
279 const sal_Char* pszServicename, const sal_Char* pszProtocol);
281 static oslSocketResult osl_psz_getHostnameOfSocketAddr (
282 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
284 static oslSocketResult osl_psz_getDottedInetAddrOfSocketAddr (
285 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
287 static void osl_psz_getLastSocketErrorDescription (
288 oslSocket Socket, sal_Char* pBuffer, sal_uInt32 BufferSize);
290 static oslSocket createSocketImpl(int Socket)
292 oslSocket pSocket;
294 pSocket = static_cast<oslSocket>(calloc(1, sizeof(struct oslSocketImpl)));
296 pSocket->m_Socket = Socket;
297 pSocket->m_nLastError = 0;
298 pSocket->m_nRefCount = 1;
300 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
301 pSocket->m_bIsAccepting = false;
302 #endif
304 return pSocket;
307 static void destroySocketImpl(oslSocket Socket)
309 if ( Socket != nullptr)
310 free(Socket);
313 static oslSocketAddr createSocketAddr()
315 oslSocketAddr pAddr = static_cast<oslSocketAddr>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl )));
316 return pAddr;
319 static oslSocketAddr createSocketAddrWithFamily(
320 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
322 oslSocketAddr pAddr;
324 SAL_WARN_IF( family != osl_Socket_FamilyInet, "sal.osl", "creating socket for non-IP address family" );
326 pAddr = createSocketAddr();
327 switch( family )
329 case osl_Socket_FamilyInet:
331 struct sockaddr_in* pInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
333 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
334 pInetAddr->sin_addr.s_addr = nAddr;
335 pInetAddr->sin_port = static_cast<sal_uInt16>(port&0xffff);
336 break;
338 default:
339 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
341 return pAddr;
344 static oslSocketAddr createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
346 oslSocketAddr pAddr = createSocketAddr();
347 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
348 return pAddr;
351 static void destroySocketAddr( oslSocketAddr addr )
353 free( addr );
356 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
358 oslSocketAddr pAddr = nullptr;
360 /* is it an internet-Addr? */
361 if (Family == osl_Socket_FamilyInet)
363 pAddr = createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
365 else
367 pAddr = createSocketAddrWithFamily( Family , 0 , 0 );
370 return pAddr;
373 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
375 oslSocketAddr pCopy = nullptr;
376 if (Addr)
378 pCopy = createSocketAddr();
380 if (pCopy)
381 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
383 return pCopy;
386 sal_Bool SAL_CALL osl_isEqualSocketAddr (
387 oslSocketAddr Addr1,
388 oslSocketAddr Addr2)
390 struct sockaddr* pAddr1 = nullptr;
391 struct sockaddr* pAddr2 = nullptr;
393 assert(Addr1 && Addr2);
394 pAddr1 = &(Addr1->m_sockaddr);
395 pAddr2 = &(Addr2->m_sockaddr);
397 if (pAddr1 == pAddr2)
399 return true;
402 if (pAddr1->sa_family == pAddr2->sa_family)
404 switch (pAddr1->sa_family)
406 case AF_INET:
408 struct sockaddr_in* pInetAddr1= reinterpret_cast<sockaddr_in*>(pAddr1);
409 struct sockaddr_in* pInetAddr2= reinterpret_cast<sockaddr_in*>(pAddr2);
411 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
412 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
413 (pInetAddr1->sin_port == pInetAddr2->sin_port))
414 return true;
415 SAL_FALLTHROUGH;
418 default:
420 return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
425 return false;
428 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
429 rtl_uString *strDottedAddr,
430 sal_Int32 Port)
432 sal_uInt32 nAddr = OSL_INADDR_NONE;
433 oslSocketAddr pAddr;
435 if (strDottedAddr && strDottedAddr->length)
437 /* Dotted host address for limited broadcast */
438 rtl_String *pDottedAddr = nullptr;
440 rtl_uString2String (
441 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
442 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
444 nAddr = inet_addr (pDottedAddr->buffer);
445 rtl_string_release (pDottedAddr);
448 if (nAddr != OSL_INADDR_NONE)
450 /* Limited broadcast */
451 nAddr = ntohl(nAddr);
452 if (IN_CLASSA(nAddr))
454 nAddr &= IN_CLASSA_NET;
455 nAddr |= IN_CLASSA_HOST;
457 else if (IN_CLASSB(nAddr))
459 nAddr &= IN_CLASSB_NET;
460 nAddr |= IN_CLASSB_HOST;
462 else if (IN_CLASSC(nAddr))
464 nAddr &= IN_CLASSC_NET;
465 nAddr |= IN_CLASSC_HOST;
467 else
469 /* No broadcast in class D */
470 return nullptr;
472 nAddr = htonl(nAddr);
475 pAddr = createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
476 return pAddr;
479 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
480 rtl_uString *ustrDottedAddr,
481 sal_Int32 Port)
483 rtl_String* strDottedAddr=nullptr;
484 oslSocketAddr Addr;
485 sal_Char* pszDottedAddr=nullptr;
487 if ( ustrDottedAddr != nullptr )
489 rtl_uString2String( &strDottedAddr,
490 rtl_uString_getStr(ustrDottedAddr),
491 rtl_uString_getLength(ustrDottedAddr),
492 RTL_TEXTENCODING_UTF8,
493 OUSTRING_TO_OSTRING_CVTFLAGS);
494 pszDottedAddr = rtl_string_getStr(strDottedAddr);
497 Addr = pszDottedAddr ? osl_psz_createInetSocketAddr(pszDottedAddr, Port) : nullptr;
499 if ( strDottedAddr != nullptr )
501 rtl_string_release(strDottedAddr);
504 return Addr;
507 oslSocketAddr osl_psz_createInetSocketAddr (
508 const sal_Char* pszDottedAddr,
509 sal_Int32 Port)
511 oslSocketAddr pAddr = nullptr;
512 sal_Int32 Addr = inet_addr(pszDottedAddr);
513 if(Addr != -1)
515 /* valid dotted addr */
516 pAddr = createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
518 return pAddr;
521 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
523 oslSocketResult res = osl_Socket_Error;
525 SAL_WARN_IF( !pAddr, "sal.osl", "setting address of undefined socket address" );
526 SAL_WARN_IF( !pByteSeq, "sal.osl", "setting undefined address for socket address" );
528 if( pAddr && pByteSeq )
530 struct sockaddr_in * pSystemInetAddr;
532 assert( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
533 assert( pByteSeq->nElements == 4 );
535 pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
536 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
537 res = osl_Socket_Ok;
539 return res;
542 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
544 oslSocketResult res = osl_Socket_Error;
546 SAL_WARN_IF( !pAddr, "sal.osl", "getting address of undefined socket address" );
547 SAL_WARN_IF( !ppByteSeq, "sal.osl", "getting address to undefined address pointer" );
549 if( pAddr && ppByteSeq )
551 struct sockaddr_in * pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
552 rtl_byte_sequence_constructFromArray( ppByteSeq, reinterpret_cast<sal_Int8 *>(&pSystemInetAddr->sin_addr), 4);
553 res = osl_Socket_Ok;
555 return res;
558 /** try to figure out a full-qualified hostname, by adding the current domain
559 as given by the domainname program to the given hostname.
560 This function MUST NOT call gethostbyname since pHostName already points
561 to data returned by gethostname and would be garbled: use gethostname_r
562 instead!
565 /* wrap around different interfaces to reentrant gethostbyname */
566 static struct hostent* osl_gethostbyname_r (
567 const char *name, struct hostent *result,
568 char *buffer, int buflen, int *h_errnop)
570 #if defined(LINUX) || defined(ANDROID) || defined(FREEBSD) || defined(DRAGONFLY)
571 struct hostent *result_; /* will be the same as result */
572 int e;
573 e = gethostbyname_r (name, result, buffer, buflen,
574 &result_, h_errnop);
575 return e ? nullptr : result_ ;
576 #elif defined(AIX)
577 *h_errnop = gethostbyname_r (name, result, (struct hostent_data *)buffer);
578 (void)buflen;
579 return *h_errnop ? NULL : result ;
580 #else
581 return gethostbyname_r( name, result, buffer, buflen, h_errnop);
582 #endif
585 static bool isFullQualifiedDomainName (const sal_Char *pHostName)
587 /* a FQDN (aka 'hostname.domain.top_level_domain' )
588 * is a name which contains a dot '.' in it ( would
589 * match as well for 'hostname.' but is good enough
590 * for now )*/
591 return strchr( pHostName, int('.') ) != nullptr;
594 static sal_Char* getFullQualifiedDomainName (const sal_Char *pHostName)
596 sal_Char *pFullQualifiedName = nullptr;
598 if (isFullQualifiedDomainName(pHostName))
600 pFullQualifiedName = strdup(pHostName);
602 else
604 struct hostent aHostByName;
605 struct hostent *pHostByName;
606 sal_Char pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
607 int nErrorNo;
609 pHostByName = osl_gethostbyname_r (
610 pHostName,
611 &aHostByName, pQualifiedHostBuffer,
612 sizeof(pQualifiedHostBuffer), &nErrorNo );
613 if (pHostByName != nullptr)
615 pFullQualifiedName = strdup(pHostByName->h_name);
619 return pFullQualifiedName;
622 struct oslHostAddrImpl
624 sal_Char *pHostName;
625 oslSocketAddr pSockAddr;
628 static oslHostAddr hostentToHostAddr (const struct hostent *he)
630 oslHostAddr pAddr= nullptr;
631 oslSocketAddr pSockAddr = nullptr;
633 sal_Char *cn;
635 if ((he == nullptr) || (he->h_name == nullptr) || (he->h_addr_list[0] == nullptr))
636 return nullptr;
638 cn = getFullQualifiedDomainName (he->h_name);
639 SAL_WARN_IF( !cn, "sal.osl", "couldn't get full qualified domain name" );
640 if (cn == nullptr)
641 return nullptr;
643 pSockAddr = createSocketAddr();
644 SAL_WARN_IF( !pSockAddr, "sal.osl", "insufficient memory" );
645 if (pSockAddr == nullptr)
647 free(cn);
648 return nullptr;
651 pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
652 if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
654 struct sockaddr_in *sin= reinterpret_cast<sockaddr_in *>(&pSockAddr->m_sockaddr);
655 memcpy (
656 &(sin->sin_addr.s_addr),
657 he->h_addr_list[0],
658 he->h_length);
660 else
662 /* unknown address family */
663 /* future extensions for new families might be implemented here */
665 SAL_WARN( "sal.osl", "unknown address family" );
667 destroySocketAddr( pSockAddr );
668 free (cn);
669 return nullptr;
672 pAddr= static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
673 SAL_WARN_IF( !pAddr, "sal.osl", "allocation error" );
674 if (pAddr == nullptr)
676 destroySocketAddr( pSockAddr );
677 free (cn);
678 return nullptr;
681 pAddr->pHostName= cn;
682 pAddr->pSockAddr= pSockAddr;
684 return pAddr;
687 oslHostAddr SAL_CALL osl_createHostAddr (
688 rtl_uString *ustrHostname,
689 const oslSocketAddr Addr)
691 oslHostAddr HostAddr;
692 rtl_String* strHostname=nullptr;
693 sal_Char* pszHostName=nullptr;
695 if ( ustrHostname != nullptr )
697 rtl_uString2String( &strHostname,
698 rtl_uString_getStr(ustrHostname),
699 rtl_uString_getLength(ustrHostname),
700 RTL_TEXTENCODING_UTF8,
701 OUSTRING_TO_OSTRING_CVTFLAGS );
702 pszHostName = rtl_string_getStr(strHostname);
705 HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
707 if ( strHostname != nullptr )
709 rtl_string_release(strHostname);
712 return HostAddr;
715 oslHostAddr osl_psz_createHostAddr (
716 const sal_Char *pszHostname,
717 const oslSocketAddr pAddr)
719 oslHostAddr pHostAddr;
720 sal_Char *cn;
722 SAL_WARN_IF( !pszHostname, "sal.osl", "undefined hostname" );
723 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
724 if ((pszHostname == nullptr) || (pAddr == nullptr))
725 return nullptr;
727 cn = strdup(pszHostname);
728 SAL_WARN_IF( !cn, "sal.osl", "insufficient memory" );
729 if (cn == nullptr)
730 return nullptr;
732 pHostAddr= static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
733 SAL_WARN_IF( !pHostAddr, "sal.osl", "allocation error" );
734 if (pHostAddr == nullptr)
736 free (cn);
737 return nullptr;
740 pHostAddr->pHostName= cn;
741 pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
743 return pHostAddr;
746 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
748 oslHostAddr HostAddr;
749 rtl_String* strHostname=nullptr;
750 sal_Char* pszHostName=nullptr;
752 if ( ustrHostname != nullptr )
754 rtl_uString2String( &strHostname,
755 rtl_uString_getStr(ustrHostname),
756 rtl_uString_getLength(ustrHostname),
757 RTL_TEXTENCODING_UTF8,
758 OUSTRING_TO_OSTRING_CVTFLAGS );
759 pszHostName=rtl_string_getStr(strHostname);
762 HostAddr = osl_psz_createHostAddrByName(pszHostName);
764 if ( strHostname != nullptr )
766 rtl_string_release(strHostname);
769 return HostAddr;
772 oslHostAddr osl_psz_createHostAddrByName (const sal_Char *pszHostname)
774 struct hostent aHe;
775 struct hostent *pHe;
776 sal_Char heBuffer[ MAX_HOSTBUFFER_SIZE ];
777 int nErrorNo;
779 pHe = osl_gethostbyname_r (
780 pszHostname,
781 &aHe, heBuffer,
782 sizeof(heBuffer), &nErrorNo );
784 return hostentToHostAddr (pHe);
787 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
789 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
791 if (pAddr == nullptr)
792 return nullptr;
794 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
796 const struct sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
797 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
798 return nullptr;
800 char host[MAX_HOSTBUFFER_SIZE];
801 int res = getnameinfo(&pAddr->m_sockaddr, sizeof(struct sockaddr_in),
802 host, sizeof(host), nullptr, 0, NI_NAMEREQD);
803 if (res != 0)
804 return nullptr;
806 sal_Char *cn = getFullQualifiedDomainName(host);
807 SAL_WARN_IF( !cn, "sal.osl", "couldn't get full qualified domain name" );
808 if (cn == nullptr)
809 return nullptr;
811 oslSocketAddr pSockAddr = createSocketAddr();
812 SAL_WARN_IF( !pSockAddr, "sal.osl", "insufficient memory" );
813 if (pSockAddr == nullptr)
815 free(cn);
816 return nullptr;
819 memcpy(&pSockAddr->m_sockaddr, &pAddr->m_sockaddr, sizeof(pAddr->m_sockaddr));
821 oslHostAddr pHostAddr = static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
822 SAL_WARN_IF( !pAddr, "sal.osl", "allocation error" );
823 if (pHostAddr == nullptr)
825 destroySocketAddr(pSockAddr);
826 free(cn);
827 return nullptr;
830 pHostAddr->pHostName = cn;
831 pHostAddr->pSockAddr = pSockAddr;
833 return pHostAddr;
836 return nullptr;
839 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
841 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
843 if (pAddr)
844 return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
845 return nullptr;
848 void SAL_CALL osl_getHostnameOfHostAddr (
849 const oslHostAddr Addr,
850 rtl_uString **ustrHostname)
852 const sal_Char* pHostname=nullptr;
854 pHostname = osl_psz_getHostnameOfHostAddr(Addr);
856 rtl_uString_newFromAscii (ustrHostname, pHostname);
859 const sal_Char* osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
861 if (pAddr)
862 return pAddr->pHostName;
863 return nullptr;
866 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
868 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
870 if (pAddr)
871 return pAddr->pSockAddr;
872 return nullptr;
875 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
877 if (pAddr)
879 if (pAddr->pHostName)
880 free (pAddr->pHostName);
881 if (pAddr->pSockAddr)
882 osl_destroySocketAddr (pAddr->pSockAddr);
883 free (pAddr);
887 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
889 oslSocketResult Result;
890 sal_Char pszHostname[1024];
892 pszHostname[0] = '\0';
894 Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
896 rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
898 return Result;
901 oslSocketResult osl_psz_getLocalHostname (
902 sal_Char *pBuffer, sal_uInt32 nBufLen)
904 static sal_Char LocalHostname[256] = "";
906 if (strlen(LocalHostname) == 0)
909 #ifdef SYSV
910 struct utsname uts;
912 if (uname(&uts) < 0)
913 return osl_Socket_Error;
915 if ((strlen(uts.nodename) + 1) > nBufLen)
916 return osl_Socket_Error;
918 strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
919 #else /* BSD compatible */
920 if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
921 return osl_Socket_Error;
922 #endif /* SYSV */
923 LocalHostname[sizeof(LocalHostname)-1] = 0;
925 /* check if we have an FQDN */
926 if (strchr(LocalHostname, '.') == nullptr)
928 oslHostAddr Addr;
930 /* no, determine it via dns */
931 Addr = osl_psz_createHostAddrByName(LocalHostname);
933 const sal_Char *pStr;
934 if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != nullptr)
936 strncpy(LocalHostname, pStr, sizeof( LocalHostname ));
937 LocalHostname[sizeof(LocalHostname)-1] = 0;
939 osl_destroyHostAddr(Addr);
943 if (strlen(LocalHostname) > 0)
945 strncpy(pBuffer, LocalHostname, nBufLen);
946 pBuffer[nBufLen - 1] = '\0';
948 return osl_Socket_Ok;
951 return osl_Socket_Error;
954 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
956 oslSocketAddr Addr;
957 rtl_String* strHostname=nullptr;
958 sal_Char* pszHostName=nullptr;
960 if ( ustrHostname != nullptr )
962 rtl_uString2String( &strHostname,
963 rtl_uString_getStr(ustrHostname),
964 rtl_uString_getLength(ustrHostname),
965 RTL_TEXTENCODING_UTF8,
966 OUSTRING_TO_OSTRING_CVTFLAGS );
967 pszHostName = rtl_string_getStr(strHostname);
970 Addr = osl_psz_resolveHostname(pszHostName);
972 if ( strHostname != nullptr )
974 rtl_string_release(strHostname);
977 return Addr;
980 oslSocketAddr osl_psz_resolveHostname(const sal_Char* pszHostname)
982 struct oslHostAddrImpl *pAddr = osl_psz_createHostAddrByName(pszHostname);
984 if (pAddr)
986 oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
988 osl_destroyHostAddr(pAddr);
990 return SockAddr;
993 return nullptr;
996 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
998 sal_Int32 nPort;
999 rtl_String* strServicename=nullptr;
1000 rtl_String* strProtocol=nullptr;
1001 sal_Char* pszServiceName=nullptr;
1002 sal_Char* pszProtocol=nullptr;
1004 if ( ustrServicename != nullptr )
1006 rtl_uString2String( &strServicename,
1007 rtl_uString_getStr(ustrServicename),
1008 rtl_uString_getLength(ustrServicename),
1009 RTL_TEXTENCODING_UTF8,
1010 OUSTRING_TO_OSTRING_CVTFLAGS );
1011 pszServiceName = rtl_string_getStr(strServicename);
1014 if ( ustrProtocol != nullptr )
1016 rtl_uString2String( &strProtocol,
1017 rtl_uString_getStr(ustrProtocol),
1018 rtl_uString_getLength(ustrProtocol),
1019 RTL_TEXTENCODING_UTF8,
1020 OUSTRING_TO_OSTRING_CVTFLAGS );
1021 pszProtocol = rtl_string_getStr(strProtocol);
1024 nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1026 if ( strServicename != nullptr )
1028 rtl_string_release(strServicename);
1031 if ( strProtocol != nullptr )
1033 rtl_string_release(strProtocol);
1036 return nPort;
1039 sal_Int32 osl_psz_getServicePort(const sal_Char* pszServicename,
1040 const sal_Char* pszProtocol)
1042 struct servent* ps;
1044 ps= getservbyname(pszServicename, pszProtocol);
1046 if (ps != nullptr)
1047 return ntohs(ps->s_port);
1049 return OSL_INVALID_PORT;
1052 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1054 destroySocketAddr( pAddr );
1057 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1059 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1061 if (pAddr)
1062 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1063 return osl_Socket_FamilyInvalid;
1066 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1068 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1070 if( pAddr )
1072 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
1074 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1075 return ntohs(pSystemInetAddr->sin_port);
1077 return OSL_INVALID_PORT;
1080 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1082 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1084 if( pAddr )
1086 struct sockaddr_in* pSystemInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
1087 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1089 pSystemInetAddr->sin_port= htons(static_cast<short>(Port));
1090 return true;
1094 /* this is not a inet-addr => can't set port */
1095 return false;
1098 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1100 oslSocketResult Result;
1101 sal_Char pszHostname[1024];
1103 pszHostname[0] = '\0';
1105 Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1106 if (Result == osl_Socket_Ok)
1108 rtl_uString_newFromAscii(ustrHostname,pszHostname);
1111 return Result;
1114 oslSocketResult osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1115 sal_Char *pBuffer, sal_uInt32 BufferSize)
1117 oslHostAddr pHostAddr= osl_createHostAddrByAddr(pAddr);
1119 if (pHostAddr)
1121 strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1122 pBuffer[BufferSize - 1] = '\0';
1124 osl_destroyHostAddr(pHostAddr);
1126 return osl_Socket_Ok;
1129 return osl_Socket_Error;
1132 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1134 oslSocketResult Result;
1135 sal_Char pszDottedInetAddr[1024];
1137 pszDottedInetAddr[0] = '\0';
1139 Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1141 rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1143 return Result;
1147 oslSocketResult osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1148 sal_Char *pBuffer, sal_uInt32 BufferSize)
1150 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1152 if( pAddr )
1154 struct sockaddr_in* pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
1156 if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1158 strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1159 pBuffer[BufferSize - 1] = '\0';
1161 return osl_Socket_Ok;
1165 return osl_Socket_Error;
1168 oslSocket SAL_CALL osl_createSocket(
1169 oslAddrFamily Family,
1170 oslSocketType Type,
1171 oslProtocol Protocol)
1173 oslSocket pSocket;
1175 /* alloc memory */
1176 pSocket= createSocketImpl(OSL_INVALID_SOCKET);
1178 /* create socket */
1179 pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1180 TYPE_TO_NATIVE(Type),
1181 PROTOCOL_TO_NATIVE(Protocol));
1183 /* creation failed => free memory */
1184 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1186 int nErrno = errno;
1187 SAL_WARN( "sal.osl", "socket creation failed: " << UnixErrnoString(nErrno) );
1189 destroySocketImpl(pSocket);
1190 pSocket= nullptr;
1192 else
1194 sal_Int32 nFlags=0;
1195 /* set close-on-exec flag */
1196 if ((nFlags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1198 nFlags |= FD_CLOEXEC;
1199 if (fcntl(pSocket->m_Socket, F_SETFD, nFlags) == -1)
1201 pSocket->m_nLastError=errno;
1202 int nErrno = errno;
1203 SAL_WARN( "sal.osl", "failed changing socket flags: " << UnixErrnoString(nErrno) );
1206 else
1208 pSocket->m_nLastError=errno;
1212 return pSocket;
1215 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1217 osl_atomic_increment(&(pSocket->m_nRefCount));
1220 void SAL_CALL osl_releaseSocket(oslSocket pSocket)
1222 if (pSocket && osl_atomic_decrement(&(pSocket->m_nRefCount)) == 0)
1224 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1225 if (pSocket->m_bIsAccepting)
1227 SAL_WARN( "sal.osl", "attempt to destroy socket while accepting" );
1228 return;
1230 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1231 osl_closeSocket(pSocket);
1232 destroySocketImpl(pSocket);
1236 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1238 /* socket already invalid */
1239 if (!pSocket)
1240 return;
1242 pSocket->m_nLastError=0;
1243 sal_Int32 nFD = pSocket->m_Socket;
1245 if (nFD == OSL_INVALID_SOCKET)
1246 return;
1248 pSocket->m_Socket = OSL_INVALID_SOCKET;
1250 sal_Int32 nRet=0;
1251 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1252 pSocket->m_bIsInShutdown = true;
1254 if (pSocket->m_bIsAccepting)
1256 union {
1257 struct sockaddr aSockAddr;
1258 struct sockaddr_in aSockAddrIn;
1259 } s;
1260 socklen_t nSockLen = sizeof(s.aSockAddr);
1262 nRet = getsockname(nFD, &s.aSockAddr, &nSockLen);
1263 if (nRet < 0)
1265 int nErrno = errno;
1266 SAL_WARN( "sal.osl", "getsockname call failed: " << UnixErrnoString(nErrno) );
1269 if (s.aSockAddr.sa_family == AF_INET)
1271 if (s.aSockAddrIn.sin_addr.s_addr == htonl(INADDR_ANY))
1273 s.aSockAddrIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1276 int nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1277 if (nConnFD < 0)
1279 int nErrno = errno;
1280 SAL_WARN( "sal.osl", "socket call failed: " << UnixErrnoString(nErrno) );
1282 else
1284 nRet = connect(nConnFD, &s.aSockAddr, sizeof(s.aSockAddr));
1285 if (nRet < 0)
1287 int nErrno = errno;
1288 SAL_WARN( "sal.osl", "connect call failed: " << UnixErrnoString(nErrno) );
1290 close(nConnFD);
1293 pSocket->m_bIsAccepting = false;
1295 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1297 nRet=close(nFD);
1298 if (nRet != 0)
1300 pSocket->m_nLastError=errno;
1301 int nErrno = errno;
1302 SAL_WARN( "sal.osl", "closeSocket close failed: " << UnixErrnoString(nErrno) );
1305 pSocket->m_Socket = OSL_INVALID_SOCKET;
1308 /* Note from function creator: I rely on the fact that oslSocketAddr and struct sockaddr
1309 are the same! I don't like it very much but see no other easy way to conceal
1310 the struct sockaddr from the eyes of the user. */
1311 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1313 socklen_t AddrLen;
1314 struct sockaddr Addr;
1315 oslSocketAddr pAddr;
1317 if (pSocket == nullptr) /* ENOTSOCK */
1318 return nullptr;
1320 AddrLen= sizeof(struct sockaddr);
1322 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1323 return nullptr;
1325 pAddr = createSocketAddrFromSystem( &Addr );
1326 return pAddr;
1329 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1331 socklen_t AddrLen;
1332 struct sockaddr Addr;
1334 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1335 if ( pSocket == nullptr )
1337 return nullptr;
1340 pSocket->m_nLastError=0;
1341 AddrLen= sizeof(struct sockaddr);
1343 if(getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1345 pSocket->m_nLastError=errno;
1346 return nullptr;
1348 return createSocketAddrFromSystem( &Addr );
1351 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
1352 oslSocketAddr pAddr)
1354 int nRet;
1356 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1357 SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1358 if ( pSocket == nullptr || pAddr == nullptr )
1360 return false;
1363 pSocket->m_nLastError=0;
1365 nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1367 if ( nRet == OSL_SOCKET_ERROR)
1369 pSocket->m_nLastError=errno;
1370 return false;
1373 return true;
1376 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
1377 sal_Int32 MaxPendingConnections)
1379 int nRet;
1381 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1382 if ( pSocket == nullptr )
1384 return false;
1387 pSocket->m_nLastError=0;
1389 nRet = listen(pSocket->m_Socket,
1390 MaxPendingConnections == -1 ?
1391 SOMAXCONN :
1392 MaxPendingConnections);
1393 if ( nRet == OSL_SOCKET_ERROR)
1395 pSocket->m_nLastError=errno;
1396 return false;
1399 return true;
1402 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
1403 oslSocketAddr pAddr,
1404 const TimeValue* pTimeout)
1406 fd_set WriteSet;
1407 fd_set ExcptSet;
1408 int ReadyHandles;
1409 struct timeval tv;
1411 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1413 if ( pSocket == nullptr )
1415 return osl_Socket_Error;
1418 pSocket->m_nLastError=0;
1420 if (osl_isNonBlockingMode(pSocket))
1422 if (connect(pSocket->m_Socket,
1423 &(pAddr->m_sockaddr),
1424 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1425 return osl_Socket_Ok;
1427 if (errno == EWOULDBLOCK || errno == EINPROGRESS)
1429 pSocket->m_nLastError=EINPROGRESS;
1430 return osl_Socket_InProgress;
1433 pSocket->m_nLastError=errno;
1434 int nErrno = errno;
1435 SAL_WARN( "sal.osl", "connection failed: " << UnixErrnoString(nErrno) );
1436 return osl_Socket_Error;
1439 /* set socket temporarily to non-blocking */
1440 if( !osl_enableNonBlockingMode(pSocket, true) )
1441 SAL_WARN( "sal.osl", "failed to enable non-blocking mode" );
1443 /* initiate connect */
1444 if(connect(pSocket->m_Socket,
1445 &(pAddr->m_sockaddr),
1446 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1448 /* immediate connection */
1449 osl_enableNonBlockingMode(pSocket, false);
1451 return osl_Socket_Ok;
1454 /* really an error or just delayed? */
1455 if (errno != EINPROGRESS)
1457 pSocket->m_nLastError=errno;
1458 int nErrno = errno;
1459 SAL_WARN( "sal.osl", "connection failed: " << UnixErrnoString(nErrno) );
1461 osl_enableNonBlockingMode(pSocket, false);
1462 return osl_Socket_Error;
1465 /* prepare select set for socket */
1466 FD_ZERO(&WriteSet);
1467 FD_ZERO(&ExcptSet);
1468 FD_SET(pSocket->m_Socket, &WriteSet);
1469 FD_SET(pSocket->m_Socket, &ExcptSet);
1471 /* prepare timeout */
1472 if (pTimeout)
1474 /* divide milliseconds into seconds and microseconds */
1475 tv.tv_sec= pTimeout->Seconds;
1476 tv.tv_usec= pTimeout->Nanosec / 1000L;
1479 /* select */
1480 ReadyHandles= select(pSocket->m_Socket+1,
1481 nullptr,
1482 PTR_FD_SET(WriteSet),
1483 PTR_FD_SET(ExcptSet),
1484 pTimeout ? &tv : nullptr);
1486 if (ReadyHandles > 0) /* connected */
1488 if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
1490 int nErrorCode = 0;
1491 socklen_t nErrorSize = sizeof( nErrorCode );
1493 int nSockOpt;
1495 nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
1496 &nErrorCode, &nErrorSize );
1497 if ( (nSockOpt == 0) && (nErrorCode == 0))
1499 osl_enableNonBlockingMode(pSocket, false);
1500 return osl_Socket_Ok;
1502 else
1504 pSocket->m_nLastError = (nSockOpt == 0) ? nErrorCode : errno;
1505 return osl_Socket_Error;
1508 else
1510 return osl_Socket_Error;
1513 else if (ReadyHandles < 0) /* error */
1515 if (errno == EBADF) /* most probably interrupted by close() */
1517 /* do not access pSockImpl because it is about to be or */
1518 /* already destroyed */
1519 return osl_Socket_Interrupted;
1521 pSocket->m_nLastError=errno;
1522 return osl_Socket_Error;
1524 else /* timeout */
1526 pSocket->m_nLastError=errno;
1527 return osl_Socket_TimedOut;
1531 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
1532 oslSocketAddr* ppAddr)
1534 struct sockaddr Addr;
1535 int Connection, Flags;
1536 oslSocket pConnectionSockImpl;
1538 socklen_t AddrLen = sizeof(struct sockaddr);
1539 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1540 if ( pSocket == nullptr )
1542 return nullptr;
1545 pSocket->m_nLastError=0;
1546 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1547 pSocket->m_bIsAccepting = true;
1548 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1550 if( ppAddr && *ppAddr )
1552 osl_destroySocketAddr( *ppAddr );
1553 *ppAddr = nullptr;
1556 /* prevent Linux EINTR behaviour */
1559 Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
1560 } while (Connection == -1 && errno == EINTR);
1562 /* accept failed? */
1563 if( Connection == OSL_SOCKET_ERROR )
1565 pSocket->m_nLastError=errno;
1566 int nErrno = errno;
1567 SAL_WARN( "sal.osl", "accept connection failed: " << UnixErrnoString(nErrno) );
1569 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1570 pSocket->m_bIsAccepting = false;
1571 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1572 return nullptr;
1575 assert(AddrLen == sizeof(struct sockaddr));
1577 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1578 if ( pSocket->m_bIsInShutdown )
1580 close(Connection);
1581 SAL_WARN( "sal.osl", "close while accept" );
1582 return nullptr;
1584 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1586 if(ppAddr)
1588 *ppAddr= createSocketAddrFromSystem(&Addr);
1591 /* alloc memory */
1592 pConnectionSockImpl= createSocketImpl(OSL_INVALID_SOCKET);
1594 /* set close-on-exec flag */
1595 if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
1597 Flags |= FD_CLOEXEC;
1598 if (fcntl(Connection, F_SETFD, Flags) == -1)
1600 pSocket->m_nLastError=errno;
1601 int nErrno = errno;
1602 SAL_WARN( "sal.osl", "fcntl failed: " << UnixErrnoString(nErrno) );
1607 pConnectionSockImpl->m_Socket = Connection;
1608 pConnectionSockImpl->m_nLastError = 0;
1609 #if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
1610 pConnectionSockImpl->m_bIsAccepting = false;
1612 pSocket->m_bIsAccepting = false;
1613 #endif /* CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT */
1614 return pConnectionSockImpl;
1617 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
1618 void* pBuffer,
1619 sal_uInt32 BytesToRead,
1620 oslSocketMsgFlag Flag)
1622 int nRead;
1624 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1625 if ( pSocket == nullptr )
1627 return -1;
1630 pSocket->m_nLastError=0;
1634 nRead = recv(pSocket->m_Socket,
1635 pBuffer,
1636 BytesToRead,
1637 MSG_FLAG_TO_NATIVE(Flag));
1638 } while ( nRead < 0 && errno == EINTR );
1640 if ( nRead < 0 )
1642 pSocket->m_nLastError=errno;
1643 int nErrno = errno;
1644 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: " << UnixErrnoString(nErrno) );
1646 else if ( nRead == 0 )
1648 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: EOL" );
1651 return nRead;
1654 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
1655 oslSocketAddr pSenderAddr,
1656 void* pBuffer,
1657 sal_uInt32 BufferSize,
1658 oslSocketMsgFlag Flag)
1660 int nRead;
1661 struct sockaddr *pSystemSockAddr = nullptr;
1662 socklen_t AddrLen = 0;
1663 if( pSenderAddr )
1665 AddrLen = sizeof( struct sockaddr );
1666 pSystemSockAddr = &(pSenderAddr->m_sockaddr);
1669 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1670 if ( pSocket == nullptr )
1672 return -1;
1675 pSocket->m_nLastError=0;
1677 nRead = recvfrom(pSocket->m_Socket,
1678 pBuffer,
1679 BufferSize,
1680 MSG_FLAG_TO_NATIVE(Flag),
1681 pSystemSockAddr,
1682 &AddrLen);
1684 if ( nRead < 0 )
1686 pSocket->m_nLastError=errno;
1687 int nErrno = errno;
1688 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: " << UnixErrnoString(nErrno) );
1690 else if ( nRead == 0 )
1692 SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: EOL" );
1695 return nRead;
1698 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
1699 const void* pBuffer,
1700 sal_uInt32 BytesToSend,
1701 oslSocketMsgFlag Flag)
1703 int nWritten;
1705 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1706 if ( pSocket == nullptr )
1708 return -1;
1711 pSocket->m_nLastError=0;
1715 nWritten = send(pSocket->m_Socket,
1716 pBuffer,
1717 BytesToSend,
1718 MSG_FLAG_TO_NATIVE(Flag));
1719 } while ( nWritten < 0 && errno == EINTR );
1721 if ( nWritten < 0 )
1723 pSocket->m_nLastError=errno;
1724 int nErrno = errno;
1725 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: " << UnixErrnoString(nErrno) );
1727 else if ( nWritten == 0 )
1729 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: EOL" );
1732 return nWritten;
1735 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
1736 oslSocketAddr ReceiverAddr,
1737 const void* pBuffer,
1738 sal_uInt32 BytesToSend,
1739 oslSocketMsgFlag Flag)
1741 int nWritten;
1743 struct sockaddr *pSystemSockAddr = nullptr;
1744 int AddrLen = 0;
1745 if( ReceiverAddr )
1747 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1748 AddrLen = sizeof( struct sockaddr );
1751 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1752 if ( pSocket == nullptr )
1754 return -1;
1757 pSocket->m_nLastError=0;
1759 /* ReceiverAddr might be 0 when used on a connected socket. */
1760 /* Then sendto should behave like send. */
1762 nWritten = sendto(pSocket->m_Socket,
1763 pBuffer,
1764 BytesToSend,
1765 MSG_FLAG_TO_NATIVE(Flag),
1766 pSystemSockAddr,
1767 AddrLen);
1769 if ( nWritten < 0 )
1771 pSocket->m_nLastError=errno;
1772 int nErrno = errno;
1773 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: " << UnixErrnoString(nErrno) );
1775 else if ( nWritten == 0 )
1777 SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: EOL" );
1780 return nWritten;
1783 sal_Int32 SAL_CALL osl_readSocket (
1784 oslSocket pSocket, void *pBuffer, sal_Int32 n )
1786 sal_uInt8 * Ptr = static_cast<sal_uInt8 *>(pBuffer);
1787 sal_uInt32 BytesRead= 0;
1788 sal_uInt32 BytesToRead= n;
1790 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1792 /* loop until all desired bytes were read or an error occurred */
1793 while (BytesToRead > 0)
1795 sal_Int32 RetVal;
1796 RetVal= osl_receiveSocket(pSocket,
1797 Ptr,
1798 BytesToRead,
1799 osl_Socket_MsgNormal);
1801 /* error occurred? */
1802 if(RetVal <= 0)
1804 break;
1807 BytesToRead -= RetVal;
1808 BytesRead += RetVal;
1809 Ptr += RetVal;
1812 return BytesRead;
1815 sal_Int32 SAL_CALL osl_writeSocket(
1816 oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1818 /* loop until all desired bytes were send or an error occurred */
1819 sal_uInt32 BytesSend= 0;
1820 sal_uInt32 BytesToSend= n;
1821 sal_uInt8 const *Ptr = static_cast<sal_uInt8 const *>(pBuffer);
1823 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1825 while (BytesToSend > 0)
1827 sal_Int32 RetVal;
1829 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1831 /* error occurred? */
1832 if(RetVal <= 0)
1834 break;
1837 BytesToSend -= RetVal;
1838 BytesSend += RetVal;
1839 Ptr += RetVal;
1842 return BytesSend;
1845 #ifdef HAVE_POLL_H /* poll() */
1847 static bool socket_poll (
1848 oslSocket pSocket,
1849 const TimeValue* pTimeout,
1850 short nEvent)
1852 struct pollfd fds;
1853 int timeout;
1854 int result;
1856 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1857 if (pSocket == nullptr)
1858 return false; /* EINVAL */
1860 pSocket->m_nLastError = 0;
1862 fds.fd = pSocket->m_Socket;
1863 fds.events = nEvent;
1864 fds.revents = 0;
1866 timeout = -1;
1867 if (pTimeout)
1869 /* Convert to [ms] */
1870 timeout = pTimeout->Seconds * 1000;
1871 timeout += pTimeout->Nanosec / (1000 * 1000);
1874 result = poll (&fds, 1, timeout);
1875 if (result < 0)
1877 pSocket->m_nLastError = errno;
1878 int nErrno = errno;
1879 SAL_WARN( "sal.osl", "poll failed: " << UnixErrnoString(nErrno) );
1880 return false;
1882 if (result == 0)
1884 /* Timeout */
1885 return false;
1888 return ((fds.revents & nEvent) == nEvent);
1891 #else /* select() */
1893 static sal_Bool socket_poll (
1894 oslSocket pSocket,
1895 const TimeValue* pTimeout,
1896 short nEvent)
1898 fd_set fds;
1899 struct timeval tv;
1900 int result;
1902 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1903 if (0 == pSocket)
1904 return sal_False; /* EINVAL */
1906 pSocket->m_nLastError = 0;
1908 FD_ZERO(&fds);
1909 FD_SET(pSocket->m_Socket, &fds);
1911 if (pTimeout)
1913 /* Convert to 'timeval' */
1914 tv.tv_sec = pTimeout->Seconds;
1915 tv.tv_usec = pTimeout->Nanosec / 1000;
1918 result = select (
1919 pSocket->m_Socket + 1,
1920 (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
1921 (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
1922 (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
1923 (pTimeout) ? &tv : NULL);
1925 if (result < 0)
1927 pSocket->m_nLastError = errno;
1928 int nErrno = errno;
1929 SAL_WARN( "sal.osl", "select failed: " << UnixErrnoString(nErrno) );
1930 return sal_False;
1932 if (result == 0)
1934 /* Timeout */
1935 return sal_False;
1938 return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
1941 #endif /* HAVE_POLL_H */
1943 sal_Bool SAL_CALL osl_isReceiveReady (
1944 oslSocket pSocket, const TimeValue* pTimeout)
1946 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1947 if (pSocket == nullptr)
1949 /* ENOTSOCK */
1950 return false;
1953 return socket_poll (pSocket, pTimeout, POLLIN);
1956 sal_Bool SAL_CALL osl_isSendReady (
1957 oslSocket pSocket, const TimeValue* pTimeout)
1959 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1960 if (pSocket == nullptr)
1962 /* ENOTSOCK */
1963 return false;
1966 return socket_poll (pSocket, pTimeout, POLLOUT);
1969 sal_Bool SAL_CALL osl_isExceptionPending (
1970 oslSocket pSocket, const TimeValue* pTimeout)
1972 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1973 if (pSocket == nullptr)
1975 /* ENOTSOCK */
1976 return false;
1979 return socket_poll (pSocket, pTimeout, POLLPRI);
1982 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
1983 oslSocketDirection Direction)
1985 int nRet;
1987 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1988 if ( pSocket == nullptr )
1990 return false;
1993 pSocket->m_nLastError=0;
1995 nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
1996 if (nRet != 0 )
1998 pSocket->m_nLastError=errno;
1999 int nErrno = errno;
2000 SAL_WARN( "sal.osl", "shutdown failed: " << UnixErrnoString(nErrno) );
2002 return (nRet==0);
2005 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2006 oslSocketOptionLevel Level,
2007 oslSocketOption Option,
2008 void* pBuffer,
2009 sal_uInt32 BufferLen)
2011 socklen_t nOptLen = static_cast<socklen_t>(BufferLen);
2013 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2014 if ( pSocket == nullptr )
2016 return -1;
2019 pSocket->m_nLastError=0;
2021 if(getsockopt(pSocket->m_Socket,
2022 OPTION_LEVEL_TO_NATIVE(Level),
2023 OPTION_TO_NATIVE(Option),
2024 pBuffer,
2025 &nOptLen) == -1)
2027 pSocket->m_nLastError=errno;
2028 return -1;
2031 return nOptLen;
2034 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2035 oslSocketOptionLevel Level,
2036 oslSocketOption Option,
2037 void* pBuffer,
2038 sal_uInt32 BufferLen)
2040 int nRet;
2042 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2043 if ( pSocket == nullptr )
2045 return false;
2048 pSocket->m_nLastError=0;
2050 nRet = setsockopt(pSocket->m_Socket,
2051 OPTION_LEVEL_TO_NATIVE(Level),
2052 OPTION_TO_NATIVE(Option),
2053 pBuffer,
2054 BufferLen);
2056 if ( nRet < 0 )
2058 pSocket->m_nLastError=errno;
2059 return false;
2062 return true;
2065 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2066 sal_Bool On)
2068 int flags;
2069 int nRet;
2071 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2072 if ( pSocket == nullptr )
2074 return false;
2077 pSocket->m_nLastError=0;
2079 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2081 if (On)
2082 flags |= O_NONBLOCK;
2083 else
2084 flags &= ~(O_NONBLOCK);
2086 nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2088 if ( nRet < 0 )
2090 pSocket->m_nLastError=errno;
2091 return false;
2094 return true;
2097 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2099 int flags;
2101 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2102 if ( pSocket == nullptr )
2104 return false;
2107 pSocket->m_nLastError=0;
2109 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2111 if (flags == -1 || !(flags & O_NONBLOCK))
2112 return false;
2114 return true;
2117 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2119 int Type=0;
2120 socklen_t TypeSize= sizeof(Type);
2122 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2123 if ( pSocket == nullptr )
2125 return osl_Socket_TypeInvalid;
2128 pSocket->m_nLastError=0;
2130 if(getsockopt(pSocket->m_Socket,
2131 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2132 OPTION_TO_NATIVE(osl_Socket_OptionType),
2133 &Type,
2134 &TypeSize) == -1)
2136 /* error */
2137 pSocket->m_nLastError=errno;
2138 return osl_Socket_TypeInvalid;
2141 return TYPE_FROM_NATIVE(Type);
2145 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2147 sal_Char pszError[1024];
2149 pszError[0] = '\0';
2151 osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2153 rtl_uString_newFromAscii(ustrError,pszError);
2156 void osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2158 /* make sure pBuffer will be a zero-terminated string even when strncpy has to cut */
2159 pBuffer[BufferSize-1]= '\0';
2161 if ( pSocket == nullptr )
2163 strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2164 return;
2167 strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2170 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2172 if ( pSocket == nullptr )
2174 return ERROR_FROM_NATIVE(EINVAL);
2177 return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2180 struct oslSocketSetImpl
2182 int m_MaxHandle; /* for select(), the largest descriptor in the set */
2183 fd_set m_Set; /* the set of descriptors */
2187 oslSocketSet SAL_CALL osl_createSocketSet()
2189 oslSocketSetImpl* pSet;
2191 pSet= static_cast<oslSocketSetImpl*>(malloc(sizeof(oslSocketSetImpl)));
2193 SAL_WARN_IF( !pSet, "sal.osl", "allocation error" );
2195 if(pSet)
2197 pSet->m_MaxHandle= 0;
2198 FD_ZERO(&pSet->m_Set);
2201 return pSet;
2204 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2206 if(Set)
2207 free(Set);
2210 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2212 SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2213 if ( Set == nullptr )
2215 return;
2218 Set->m_MaxHandle= 0;
2220 FD_ZERO(&Set->m_Set);
2223 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2225 SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2226 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2228 if ( Set == nullptr || pSocket == nullptr)
2230 return;
2233 /* correct max handle */
2234 if(pSocket->m_Socket > Set->m_MaxHandle)
2235 Set->m_MaxHandle= pSocket->m_Socket;
2236 FD_SET(pSocket->m_Socket, &Set->m_Set);
2240 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
2242 SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2243 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2245 if ( Set == nullptr || pSocket == nullptr)
2247 return;
2250 /* correct max handle */
2251 if(pSocket->m_Socket == Set->m_MaxHandle)
2253 /* not optimal, since the next used descriptor might be */
2254 /* much smaller than m_Socket-1, but it will do */
2255 Set->m_MaxHandle--;
2256 if(Set->m_MaxHandle < 0)
2258 Set->m_MaxHandle= 0; /* avoid underflow */
2262 FD_CLR(pSocket->m_Socket, &Set->m_Set);
2265 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
2267 SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2268 SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2269 if ( Set == nullptr || pSocket == nullptr )
2271 return false;
2274 return bool(FD_ISSET(pSocket->m_Socket, &Set->m_Set));
2277 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
2278 oslSocketSet OutgoingSet,
2279 oslSocketSet OutOfBandSet,
2280 const TimeValue* pTimeout)
2282 int MaxHandle= 0;
2283 struct timeval tv;
2285 if (pTimeout)
2287 /* non-blocking call */
2288 tv.tv_sec = pTimeout->Seconds;
2289 tv.tv_usec = pTimeout->Nanosec / 1000L;
2292 /* get max handle from all sets */
2293 if (IncomingSet)
2294 MaxHandle= IncomingSet->m_MaxHandle;
2296 if (OutgoingSet && (OutgoingSet->m_MaxHandle > MaxHandle))
2297 MaxHandle= OutgoingSet->m_MaxHandle;
2299 if (OutOfBandSet && (OutOfBandSet->m_MaxHandle > MaxHandle))
2300 MaxHandle= OutOfBandSet->m_MaxHandle;
2302 return select(MaxHandle+1,
2303 IncomingSet ? PTR_FD_SET(IncomingSet->m_Set) : nullptr,
2304 OutgoingSet ? PTR_FD_SET(OutgoingSet->m_Set) : nullptr,
2305 OutOfBandSet ? PTR_FD_SET(OutOfBandSet->m_Set) : nullptr,
2306 pTimeout ? &tv : nullptr);
2309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */