merge the formfield patch from ooo-build
[ooovba.git] / sal / osl / os2 / socket.c
blob0497b7447901e7dc38439171dedc0f32649f5db7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: socket.c,v $
10 * $Revision: 1.5.60.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "system.h"
33 #include <osl/socket.h>
34 #include <osl/diagnose.h>
35 #include <osl/mutex.h>
36 #include <osl/signal.h>
38 #include <rtl/alloc.h>
40 #include <ctype.h>
41 #include <sal/types.h>
43 #include "sockimpl.h"
46 /* defines for poll */
47 #ifdef HAVE_POLL_H
48 #undef HAVE_POLL_H
49 #endif
51 #if defined(LINUX) || defined (IRIX) || defined(NETBSD) || defined ( FREEBSD ) || defined (MACOSX)
52 #include <sys/poll.h>
53 #define HAVE_POLL_H
54 #endif /* HAVE_POLL_H */
56 #if defined(SOLARIS)
57 #include <poll.h>
58 #define HAVE_POLL_H
59 #endif /* SOLARIS */
61 #ifndef HAVE_POLL_H
62 #define POLLIN 0x0001
63 #define POLLOUT 0x0002
64 #define POLLPRI 0x0004
65 #endif /* HAVE_POLL_H */
68 /* defines for shutdown */
69 #define SD_RECEIVE 0
70 #define SD_SEND 1
71 #define SD_BOTH 2
75 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
76 I refrained from using sockaddr_in because of possible further
77 extensions of this socket-interface (IP-NG?).
78 The intention was to hide all Berkeley data-structures from
79 direct access past the osl-interface.
81 The current implementation is internet (IP) centered. All
82 the constructor-functions (osl_create...) take parameters
83 that will probably make sense only in the IP-environment
84 (e.g. because of using the dotted-address-format).
86 If the interface will be extended to host other protocol-
87 families, I expect no externally visible changes in the
88 existing functions. You'll probably need only new
89 constructor-functions who take the different address
90 formats into consideration (maybe a long dotted address
91 or whatever).
94 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
95 /* are the same! I don't like it very much but see no other easy way to */
96 /* conceal the struct sockaddr from the eyes of the user. */
99 #define OSL_INVALID_SOCKET -1
100 #define OSL_SOCKET_ERROR -1
103 /* Buffer size for gethostbyname */
104 #define MAX_HOSTBUFFER_SIZE 2048
106 /*****************************************************************************/
107 /* enum oslAddrFamily */
108 /*****************************************************************************/
110 /* map */
111 static unsigned long FamilyMap[]= {
112 AF_INET, /* osl_Socket_FamilyInet */
113 AF_IPX, /* osl_Socket_FamilyIpx */
114 0 /* osl_Socket_FamilyInvalid */
117 /* reverse map */
118 static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
120 oslAddrFamily i= (oslAddrFamily)0;
122 while(i != osl_Socket_FamilyInvalid)
124 if(FamilyMap[i] == nativeType)
125 return i;
126 i = (oslAddrFamily) ( i + 1 );
129 return i;
132 /* macros */
133 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
134 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
136 /*****************************************************************************/
137 /* enum oslProtocol */
138 /*****************************************************************************/
140 /* map */
141 static sal_uInt32 ProtocolMap[]= {
142 0, /* osl_Socket_ProtocolIp */
143 NSPROTO_IPX, /* osl_Socket_ProtocolIpx */
144 NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
145 NSPROTO_SPXII, /* osl_Socket_ProtocolSpxII */
146 0 /* osl_Socket_ProtocolInvalid */
149 /* reverse map */
150 /* mfe: NOT USED
151 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
153 oslProtocol i= (oslProtocol)0;
155 while(i != osl_Socket_ProtocolInvalid)
157 if(ProtocolMap[i] == nativeType)
158 return i;
159 i = (oslProtocol) ( i + 1);
162 return i;
166 /* macros */
167 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
168 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
171 /*****************************************************************************/
172 /* enum oslSocketType */
173 /*****************************************************************************/
175 /* map */
176 static sal_uInt32 TypeMap[]= {
177 SOCK_STREAM, /* osl_Socket_TypeStream */
178 SOCK_DGRAM, /* osl_Socket_TypeDgram */
179 SOCK_RAW, /* osl_Socket_TypeRaw */
180 SOCK_RDM, /* osl_Socket_TypeRdm */
181 SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
182 0 /* osl_Socket_TypeInvalid */
185 /* reverse map */
186 static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
188 oslSocketType i= (oslSocketType)0;
190 while(i != osl_Socket_TypeInvalid)
192 if(TypeMap[i] == nativeType)
193 return i;
194 i = (oslSocketType)(i + 1);
197 return i;
200 /* macros */
201 #define TYPE_TO_NATIVE(x) TypeMap[x]
202 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
205 /*****************************************************************************/
206 /* enum oslSocketOption */
207 /*****************************************************************************/
209 /* map */
210 static sal_uInt32 OptionMap[]= {
211 SO_DEBUG, /* osl_Socket_OptionDebug */
212 SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
213 SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
214 SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
215 SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
216 SO_BROADCAST, /* osl_Socket_OptionBroadcast */
217 SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
218 SO_LINGER, /* osl_Socket_OptionLinger */
219 SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
220 SO_SNDBUF, /* osl_Socket_OptionSndBuf */
221 SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
222 SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
223 SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
224 SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
225 SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
226 SO_ERROR, /* osl_Socket_OptionError */
227 SO_TYPE, /* osl_Socket_OptionType */
228 TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
229 0 /* osl_Socket_OptionInvalid */
232 /* reverse map */
233 /* mfe: NOT USED
234 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
236 oslSocketOption i= (oslSocketOption)0;
238 while(i != osl_Socket_OptionInvalid)
240 if(OptionMap[i] == nativeType)
241 return i;
242 i = (oslSocketOption) ( i + 1 );
245 return i;
248 /* macros */
249 #define OPTION_TO_NATIVE(x) OptionMap[x]
250 #define OPTION_FROM_NATIVE(y) osl_SocketOptionFromNative(y)
253 /*****************************************************************************/
254 /* enum oslSocketOptionLevel */
255 /*****************************************************************************/
257 static sal_uInt32 OptionLevelMap[]= {
258 SOL_SOCKET, /* osl_Socket_LevelSocket */
259 IPPROTO_TCP, /* osl_Socket_LevelTcp */
260 0 /* osl_Socket_LevelInvalid */
263 /* reverse map */
264 /* mfe: NOT USED
265 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
267 oslSocketOptionLevel i= (oslSocketOptionLevel)0;
269 while(i != osl_Socket_LevelInvalid)
271 if(OptionLevelMap[i] == nativeType)
272 return i;
273 i = (oslSocketOptionLevel) ( i + 1 );
276 return i;
279 /* macros */
280 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
281 #define OPTION_LEVEL_FROM_NATIVE(y) osl_SocketOptionLevelFromNative(y)
283 /*****************************************************************************/
284 /* enum oslSocketMsgFlag */
285 /*****************************************************************************/
287 static sal_uInt32 SocketMsgFlagMap[]= {
288 0, /* osl_Socket_MsgNormal */
289 MSG_OOB, /* osl_Socket_MsgOOB */
290 MSG_PEEK, /* osl_Socket_MsgPeek */
291 MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
292 MSG_MAXIOVLEN, /* osl_Socket_MsgMaxIOVLen */
293 0 /* osl_Socket_MsgInvalid */
296 /* reverse map */
297 /* mfe: NOT USED
298 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
300 oslSocketMsgFlag i= (oslSocketMsgFlag)0;
302 while(i != osl_Socket_MsgInvalid)
304 if(SocketMsgFlagMap[i] == nativeType)
305 return i;
306 i = (oslSocketMsgFlag) ( i + 1 );
309 return i;
313 /* macros */
314 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
315 #define MSG_FLAG_FROM_NATIVE(y) osl_SocketMsgFlagFromNative(y)
318 /*****************************************************************************/
319 /* enum oslSocketDirection */
320 /*****************************************************************************/
322 static sal_uInt32 SocketDirection[]= {
323 SD_RECEIVE, /* osl_Socket_DirRead */
324 SD_SEND, /* osl_Socket_DirWrite */
325 SD_BOTH, /* osl_Socket_DirReadWrite */
326 0 /* osl_Socket_DirInvalid */
329 /* reverse map */
330 /* mfe: NOT USED
331 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
333 oslSocketDirection i= (oslSocketDirection)0;
335 while(i != osl_Socket_DirInvalid)
337 if(SocketDirection[i] == nativeType)
338 return i;
339 i = (oslSocketDirection) ( i + 1 );
342 return i;
346 /* macros */
347 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
348 #define DIRECTION_FROM_NATIVE(y) osl_SocketDirectionFromNative(y)
350 /*****************************************************************************/
351 /* enum oslSocketError */
352 /*****************************************************************************/
354 static struct
356 int errcode;
357 oslSocketError error;
358 } SocketError[]= {
359 { 0, osl_Socket_E_None }, /* no error */
360 { ENOTSOCK, osl_Socket_E_NotSocket }, /* Socket operation on non-socket */
361 { EDESTADDRREQ, osl_Socket_E_DestAddrReq }, /* Destination address required */
362 { EMSGSIZE, osl_Socket_E_MsgSize }, /* Message too long */
363 { EPROTOTYPE, osl_Socket_E_Prototype }, /* Protocol wrong type for socket */
364 { ENOPROTOOPT, osl_Socket_E_NoProtocol }, /* Protocol not available */
365 { EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
366 { ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport }, /* Socket type not supported */
367 { EOPNOTSUPP, osl_Socket_E_OpNotSupport }, /* Operation not supported on socket */
368 { EPFNOSUPPORT, osl_Socket_E_PfNoSupport }, /* Protocol family not supported */
369 { EAFNOSUPPORT, osl_Socket_E_AfNoSupport }, /* Address family not supported by */
370 /* protocol family */
371 { EADDRINUSE, osl_Socket_E_AddrInUse }, /* Address already in use */
372 { EADDRNOTAVAIL, osl_Socket_E_AddrNotAvail }, /* Can't assign requested address */
373 { ENETDOWN, osl_Socket_E_NetDown }, /* Network is down */
374 { ENETUNREACH, osl_Socket_E_NetUnreachable }, /* Network is unreachable */
375 { ENETRESET, osl_Socket_E_NetReset }, /* Network dropped connection because */
376 /* of reset */
377 { ECONNABORTED, osl_Socket_E_ConnAborted }, /* Software caused connection abort */
378 { ECONNRESET, osl_Socket_E_ConnReset }, /* Connection reset by peer */
379 { ENOBUFS, osl_Socket_E_NoBufferSpace }, /* No buffer space available */
380 { EISCONN, osl_Socket_E_IsConnected }, /* Socket is already connected */
381 { ENOTCONN, osl_Socket_E_NotConnected }, /* Socket is not connected */
382 { ESHUTDOWN, osl_Socket_E_Shutdown }, /* Can't send after socket shutdown */
383 { ETOOMANYREFS, osl_Socket_E_TooManyRefs }, /* Too many references: can't splice */
384 { ETIMEDOUT, osl_Socket_E_TimedOut }, /* Connection timed out */
385 { ECONNREFUSED, osl_Socket_E_ConnRefused }, /* Connection refused */
386 { EHOSTDOWN, osl_Socket_E_HostDown }, /* Host is down */
387 { EHOSTUNREACH, osl_Socket_E_HostUnreachable }, /* No route to host */
388 { EWOULDBLOCK, osl_Socket_E_WouldBlock }, /* call would block on non-blocking socket */
389 { EALREADY, osl_Socket_E_Already }, /* operation already in progress */
390 { EINPROGRESS, osl_Socket_E_InProgress }, /* operation now in progress */
391 { EAGAIN, osl_Socket_E_WouldBlock }, /* same as EWOULDBLOCK */
392 { -1, osl_Socket_E_InvalidError }
395 /* map */
396 /* mfe: NOT USED
397 static int osl_NativeFromSocketError(oslSocketError errorCode)
399 int i = 0;
401 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
402 (SocketError[i].error != errorCode)) i++;
404 return SocketError[i].errcode;
408 /* reverse map */
409 static oslSocketError osl_SocketErrorFromNative(int nativeType)
411 int i = 0;
413 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
414 (SocketError[i].errcode != nativeType)) i++;
416 return SocketError[i].error;
419 /* macros */
420 #define ERROR_TO_NATIVE(x) osl_NativeFromSocketError(x)
421 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
423 /*****************************************************************************/
424 /* local function prototypes */
425 /*****************************************************************************/
427 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
428 const sal_Char* pszDottedAddr, sal_Int32 Port);
430 oslSocketAddr SAL_CALL osl_psz_createIpxSocketAddr (
431 const sal_Char NetNumber[4],
432 const sal_Char NodeNumber[6],
433 sal_uInt32 SocketNumber);
435 oslHostAddr SAL_CALL osl_psz_createHostAddr (
436 const sal_Char *pszHostname, const oslSocketAddr Addr);
438 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (
439 const sal_Char *pszHostname);
441 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (
442 const oslHostAddr Addr);
444 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
445 sal_Char *pBuffer, sal_uInt32 nBufLen);
447 oslSocketAddr SAL_CALL osl_psz_resolveHostname (
448 const sal_Char* pszHostname);
450 sal_Int32 SAL_CALL osl_psz_getServicePort (
451 const sal_Char* pszServicename, const sal_Char* pszProtocol);
453 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr (
454 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
456 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr (
457 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
459 void SAL_CALL osl_psz_getLastSocketErrorDescription (
460 oslSocket Socket, sal_Char* pBuffer, sal_uInt32 BufferSize);
462 /*****************************************************************************/
463 /* osl_create/destroy-SocketImpl */
464 /*****************************************************************************/
466 #if OSL_DEBUG_LEVEL > 1
467 static sal_uInt32 g_nSocketImpl = 0;
468 static sal_uInt32 g_nSocketAddr = 0;
470 /* sorry, must be implemented otherwise */
471 #if 0
472 struct LeakWarning
474 ~LeakWarning()
476 if( g_nSocketImpl )
477 OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl );
478 if( g_nSocketAddr )
479 OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr );
482 LeakWarning socketWarning;
483 #endif
485 #endif /* OSL_DEBUG_LEVEL */
488 oslSocket __osl_createSocketImpl(int Socket)
490 oslSocket pSocket;
492 pSocket = (oslSocket)calloc(1, sizeof(struct oslSocketImpl));
494 pSocket->m_Socket = Socket;
495 pSocket->m_nLastError = 0;
496 pSocket->m_CloseCallback = 0;
497 pSocket->m_CallbackArg = 0;
498 pSocket->m_nRefCount = 1;
500 #if defined(LINUX)
501 pSocket->m_bIsAccepting = sal_False;
502 #endif
504 #if OSL_DEBUG_LEVEL > 1
505 g_nSocketImpl ++;
506 #endif
507 return pSocket;
510 void __osl_destroySocketImpl(oslSocket Socket)
512 if ( Socket != NULL)
513 free((struct oslSocketImpl *) Socket);
514 #if OSL_DEBUG_LEVEL > 1
515 g_nSocketImpl --;
516 #endif
519 static oslSocketAddr __osl_createSocketAddr( )
521 oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
522 #if OSL_DEBUG_LEVEL > 1
523 g_nSocketAddr ++;
524 #endif
525 return pAddr;
528 static oslSocketAddr __osl_createSocketAddrWithFamily(
529 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
531 oslSocketAddr pAddr;
533 OSL_ASSERT( family == osl_Socket_FamilyInet );
535 pAddr = __osl_createSocketAddr();
536 switch( family )
538 case osl_Socket_FamilyInet:
540 struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
542 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
543 pInetAddr->sin_addr.s_addr = nAddr;
544 pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
545 break;
547 default:
548 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
550 return pAddr;
553 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
555 oslSocketAddr pAddr = __osl_createSocketAddr();
556 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
557 return pAddr;
560 static void __osl_destroySocketAddr( oslSocketAddr addr )
562 #if OSL_DEBUG_LEVEL > 1
563 g_nSocketAddr --;
564 #endif
565 rtl_freeMemory( addr );
568 /*****************************************************************************/
569 /* osl_createEmptySocketAddr */
570 /*****************************************************************************/
571 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
573 oslSocketAddr pAddr = 0;
575 /* is it an internet-Addr? */
576 if (Family == osl_Socket_FamilyInet)
578 pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
580 else
582 pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
585 return pAddr;
588 /*****************************************************************************/
589 /* osl_copySocketAddr */
590 /*****************************************************************************/
591 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
593 oslSocketAddr pCopy = 0;
594 if (Addr)
596 pCopy = __osl_createSocketAddr();
598 if (pCopy)
599 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
601 return pCopy;
604 /*****************************************************************************/
605 /* osl_isEqualSocketAddr */
606 /*****************************************************************************/
607 sal_Bool SAL_CALL osl_isEqualSocketAddr (
608 oslSocketAddr Addr1,
609 oslSocketAddr Addr2)
611 struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
612 struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
614 OSL_ASSERT(pAddr1);
615 OSL_ASSERT(pAddr2);
617 if (pAddr1->sa_family == pAddr2->sa_family)
619 switch (pAddr1->sa_family)
621 case AF_INET:
623 struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
624 struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
626 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
627 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
628 (pInetAddr1->sin_port == pInetAddr2->sin_port))
629 return (sal_True);
632 default:
634 return (memcmp(pAddr1, Addr2, sizeof(struct sockaddr)) == 0);
639 return (sal_False);
642 /*****************************************************************************/
643 /* osl_createInetBroadcastAddr */
644 /*****************************************************************************/
645 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
646 rtl_uString *strDottedAddr,
647 sal_Int32 Port)
649 sal_uInt32 nAddr = OSL_INADDR_NONE;
650 oslSocketAddr pAddr;
652 if (strDottedAddr && strDottedAddr->length)
654 /* Dotted host address for limited broadcast */
655 rtl_String *pDottedAddr = NULL;
657 rtl_uString2String (
658 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
659 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
661 nAddr = inet_addr (pDottedAddr->buffer);
662 rtl_string_release (pDottedAddr);
665 if (nAddr != OSL_INADDR_NONE)
667 /* Limited broadcast */
668 nAddr = ntohl(nAddr);
669 if (IN_CLASSA(nAddr))
671 nAddr &= IN_CLASSA_NET;
672 nAddr |= IN_CLASSA_HOST;
674 else if (IN_CLASSB(nAddr))
676 nAddr &= IN_CLASSB_NET;
677 nAddr |= IN_CLASSB_HOST;
679 else if (IN_CLASSC(nAddr))
681 nAddr &= IN_CLASSC_NET;
682 nAddr |= IN_CLASSC_HOST;
684 else
686 /* No broadcast in class D */
687 return ((oslSocketAddr)NULL);
689 nAddr = htonl(nAddr);
692 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
693 return pAddr;
696 /*****************************************************************************/
697 /* osl_createInetSocketAddr */
698 /*****************************************************************************/
699 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
700 rtl_uString *ustrDottedAddr,
701 sal_Int32 Port)
703 rtl_String* strDottedAddr=0;
704 oslSocketAddr Addr;
705 sal_Char* pszDottedAddr=0;
707 if ( ustrDottedAddr != 0 )
709 rtl_uString2String( &strDottedAddr,
710 rtl_uString_getStr(ustrDottedAddr),
711 rtl_uString_getLength(ustrDottedAddr),
712 RTL_TEXTENCODING_UTF8,
713 OUSTRING_TO_OSTRING_CVTFLAGS);
714 pszDottedAddr = rtl_string_getStr(strDottedAddr);
718 Addr = osl_psz_createInetSocketAddr(pszDottedAddr, Port);
720 if ( strDottedAddr != 0 )
722 rtl_string_release(strDottedAddr);
725 return Addr;
728 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
729 const sal_Char* pszDottedAddr,
730 sal_Int32 Port)
732 oslSocketAddr pAddr = 0;
733 sal_Int32 Addr = inet_addr(pszDottedAddr);
734 if(Addr != -1)
736 /* valid dotted addr */
737 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
739 return pAddr;
742 /*****************************************************************************/
743 /* osl_setAddrOfSocketAddr */
744 /*****************************************************************************/
745 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
747 oslSocketResult res = osl_Socket_Error;
749 OSL_ASSERT( pAddr );
750 OSL_ASSERT( pByteSeq );
752 if( pAddr && pByteSeq )
754 struct sockaddr_in * pSystemInetAddr;
756 OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
757 OSL_ASSERT( pByteSeq->nElements == 4 );
759 pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
760 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
761 res = osl_Socket_Ok;
763 return res;
766 /*****************************************************************************/
767 /* osl_getAddrOfSocketAddr */
768 /*****************************************************************************/
769 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
771 oslSocketResult res = osl_Socket_Error;
773 OSL_ASSERT( pAddr );
774 OSL_ASSERT( ppByteSeq );
776 if( pAddr && ppByteSeq )
778 struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
779 rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
780 res = osl_Socket_Ok;
782 return res;
786 /*****************************************************************************/
787 /* _osl_getFullQualifiedDomainName */
788 /*****************************************************************************/
790 /** try to figure out a full-qualified hostname, by adding the current domain
791 as given by the domainname program to the given hostname.
792 This function MUST NOT call gethostbyname since pHostName allready points
793 to data returned by gethostname and would be garbled: use gethostname_r
794 instead!
797 /* wrap around different interfaces to reentrant gethostbyname */
798 static struct hostent* _osl_gethostbyname_r (
799 const char *name, struct hostent *result,
800 char *buffer, int buflen, int *h_errnop)
803 #ifdef LINUX
804 struct hostent *__result; /* will be the same as result */
805 int __error;
806 __error = gethostbyname_r (name, result, buffer, buflen,
807 &__result, h_errnop);
808 return __error ? NULL : __result ;
809 #elif defined OS2
810 // YD FIXME!!!
811 return 0;
812 #else
813 return gethostbyname_r( name, result, buffer, buflen, h_errnop);
814 #endif
817 static sal_Bool _osl_getDomainName (sal_Char *buffer, sal_Int32 bufsiz)
819 sal_Bool result;
820 int p[2];
822 result = sal_False;
824 #if 0 // YD 17/04/06 libc panic for fork() from thread!=1
826 if (pipe (p) == 0)
828 pid_t pid;
829 int nStatus;
831 pid = fork();
832 if (pid == 0)
834 char *argv[] =
836 "/bin/domainname",
837 NULL
840 close (p[0]);
841 dup2 (p[1], 1);
842 close (p[1]);
844 execv ("/bin/domainname", argv);
845 // arriving here means exec failed
846 _exit(-1);
848 else if (pid > 0)
850 sal_Int32 k = 0, n = bufsiz;
852 close (p[1]);
853 if ((k = read (p[0], buffer, n - 1)) > 0)
855 buffer[k] = 0;
856 if (buffer[k - 1] == '\n')
857 buffer[k - 1] = 0;
858 result = sal_True;
860 close (p[0]);
861 waitpid (pid, &nStatus, 0);
863 else
865 close (p[0]);
866 close (p[1]);
869 #endif // 0
871 return (result);
874 static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
876 # define DOMAINNAME_LENGTH 512
877 sal_uInt32 nLengthOfHostName;
878 static sal_uInt32 nLengthOfDomainName = 0;
879 static sal_Char *pDomainName = NULL;
881 sal_Char *pFullQualifiedName;
882 #if 0 /* OBSOLETE */
883 FILE *pPipeToDomainnameExe;
884 #endif /* OBSOLETE */
886 /* get a '\0' terminated domainname */
888 /* read default domainname default from environment */
889 if (nLengthOfDomainName == 0)
891 sal_Char *pEnvDomain;
893 pEnvDomain = getenv ("STAR_OVERRIDE_DOMAINNAME");
894 if (pEnvDomain)
896 pDomainName = strdup (pEnvDomain);
897 nLengthOfDomainName = strlen (pDomainName);
901 #if 1 /* NEW */
902 if (nLengthOfDomainName == 0)
904 sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
906 pDomainNameBuffer[0] = '\0';
908 if (_osl_getDomainName (pDomainNameBuffer, DOMAINNAME_LENGTH))
910 pDomainName = strdup (pDomainNameBuffer);
911 nLengthOfDomainName = strlen (pDomainName);
915 #endif /* NEW */
916 #if 0 /* OBSOLETE */
917 #ifdef SCO
919 /* call 'domainname > /usr/tmp/some-tmp-file', since
920 popen read pclose do block or core-dump,
921 (even the pipe-stuff that comes with pthreads) */
922 if (nLengthOfDomainName == 0)
924 sal_Char tmp_name[ L_tmpnam ];
925 FILE *tmp_file;
926 sal_Char domain_call [ L_tmpnam + 16 ] = "domainname > ";
928 tmp_name[0] = '\0';
930 tmpnam ( tmp_name );
931 strcat ( domain_call, tmp_name );
932 if ( (system ( domain_call ) == 0)
933 && ((tmp_file = fopen( tmp_name, "r" )) != NULL ) )
935 sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
937 pDomainNameBuffer[0] = '\0';
939 if ( fgets ( pDomainNameBuffer, DOMAINNAME_LENGTH, tmp_file ) )
941 pDomainName = strdup( pDomainNameBuffer );
942 nLengthOfDomainName = strlen( pDomainName );
943 if ( ( nLengthOfDomainName > 0 )
944 && ( pDomainName[ nLengthOfDomainName - 1] == '\n' ) )
945 pDomainName[ --nLengthOfDomainName ] = '\0';
947 fclose ( tmp_file );
949 unlink( tmp_name );
952 #else /* !SCO */
954 /* read the domainname from pipe to the program domainname */
955 if ( (nLengthOfDomainName == 0)
956 && (pPipeToDomainnameExe = popen( "domainname", "r")) )
958 sal_Char c;
959 sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
960 sal_Char *pDomainNamePointer;
962 pDomainNameBuffer[0] = '\0';
964 pDomainNamePointer = pDomainNameBuffer;
965 while ( ((c = getc( pPipeToDomainnameExe )) != EOF)
966 && (nLengthOfDomainName < (DOMAINNAME_LENGTH - 1)) )
968 if (! isspace(c))
970 nLengthOfDomainName++ ;
971 *pDomainNamePointer++ = (sal_Char)c;
974 *pDomainNamePointer = '\0';
975 pDomainName = strdup( pDomainNameBuffer );
977 pclose( pPipeToDomainnameExe );
980 #endif /* !SCO */
981 #endif /* OBSOLETE */
983 /* compose hostname and domainname */
984 nLengthOfHostName = strlen( pHostName );
985 pFullQualifiedName = (sal_Char*) malloc( (nLengthOfHostName + 1
986 + nLengthOfDomainName + 1) * sizeof(sal_Char) );
987 memcpy( pFullQualifiedName, pHostName,
988 (nLengthOfHostName + 1) * sizeof(sal_Char) );
990 if ( nLengthOfDomainName > 0 )
992 /* fqdn = hostname + '.' + domainname + '\0' */
993 pFullQualifiedName[ nLengthOfHostName ] = '.';
994 memcpy( pFullQualifiedName + nLengthOfHostName + 1, pDomainName,
995 nLengthOfDomainName + 1 );
998 /* check whether full-qualified name and hostname point to the same host
999 * should almost always be true */
1000 if ( nLengthOfDomainName > 0 )
1002 struct hostent *pQualifiedHostByName;
1003 struct hostent *pHostByName;
1004 sal_Bool bHostsAreEqual;
1006 /* buffer for calls to reentrant version of gethostbyname */
1007 struct hostent aHostByName, aQualifiedHostByName;
1008 sal_Char pHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1009 sal_Char pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1010 int nErrorNo;
1012 pHostBuffer[0] = '\0';
1013 pQualifiedHostBuffer[0] = '\0';
1015 /* get list of addresses */
1016 pQualifiedHostByName = _osl_gethostbyname_r (
1017 pFullQualifiedName,
1018 &aQualifiedHostByName, pQualifiedHostBuffer,
1019 sizeof(pQualifiedHostBuffer), &nErrorNo );
1020 pHostByName = _osl_gethostbyname_r (
1021 pHostName,
1022 &aHostByName, pHostBuffer,
1023 sizeof(pHostBuffer), &nErrorNo );
1025 /* compare addresses */
1026 bHostsAreEqual = sal_False;
1027 if ( pQualifiedHostByName && pHostByName )
1029 sal_Char **p, **q;
1030 struct in_addr in;
1032 /* lists are expected to be (very) short */
1033 for ( p = pQualifiedHostByName->h_addr_list; *p != NULL; p++ )
1035 for ( q = pHostByName->h_addr_list; *q != NULL; q++ )
1037 /* in.s_addr may be in_addr_t or uint32_t or heaven knows */
1038 if ( memcmp( *p, *q, sizeof(in.s_addr) ) == 0 )
1040 bHostsAreEqual = sal_True;
1041 break;
1044 if ( bHostsAreEqual )
1045 break;
1049 /* very strange case, but have to believe it: reduce the
1050 * full qualified name to the unqualified host name */
1051 if ( !bHostsAreEqual )
1053 OSL_TRACE("_osl_getFullQualifiedDomainName: "
1054 "suspect FQDN: %s\n", pFullQualifiedName);
1056 pFullQualifiedName[ nLengthOfHostName ] = '\0';
1057 pFullQualifiedName = (sal_Char*)realloc ( pFullQualifiedName,
1058 (nLengthOfHostName + 1) * sizeof( sal_Char ));
1062 /* always return a hostname looked up as carefully as possible
1063 * this string must be freed by the caller */
1064 return pFullQualifiedName;
1067 /*****************************************************************************/
1068 /* _osl_isFullQualifiedDomainName */
1069 /*****************************************************************************/
1070 static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
1072 /* a FQDN (aka 'hostname.domain.top_level_domain' )
1073 * is a name which contains a dot '.' in it ( would
1074 * match as well for 'hostname.' but is good enough
1075 * for now )*/
1076 return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
1079 /*****************************************************************************/
1080 /* oslHostAddr */
1081 /*****************************************************************************/
1082 struct oslHostAddrImpl
1084 sal_Char *pHostName;
1085 oslSocketAddr pSockAddr;
1088 static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
1090 oslHostAddr pAddr= NULL;
1091 oslSocketAddr pSockAddr = 0;
1094 if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
1095 return ((oslHostAddr)NULL);
1097 //YD 18/06/2006 win32 does this with unicode, see socket.cxx
1098 sal_Char *cn;
1099 cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1100 OSL_ASSERT(cn);
1101 if (cn == NULL)
1102 return ((oslHostAddr)NULL);
1104 strcpy(cn, he->h_name);
1106 #if 0 // YD 17/04/06 win32 doesn't it.
1107 if (_osl_isFullQualifiedDomainName(he->h_name))
1109 cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1110 OSL_ASSERT(cn);
1111 if (cn == NULL)
1112 return ((oslHostAddr)NULL);
1114 strcpy(cn, he->h_name);
1116 else
1118 cn =_osl_getFullQualifiedDomainName (he->h_name);
1119 OSL_ASSERT(cn);
1120 if (cn == NULL)
1121 return ((oslHostAddr)NULL);
1123 #endif
1125 pSockAddr = __osl_createSocketAddr();
1126 OSL_ASSERT(pSockAddr);
1127 if (pSockAddr == NULL)
1129 free(cn);
1130 return ((oslHostAddr)NULL);
1133 pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
1134 if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1136 struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
1137 memcpy (
1138 &(sin->sin_addr.s_addr),
1139 he->h_addr_list[0],
1140 he->h_length);
1142 else
1144 /* unknown address family */
1145 /* future extensions for new families might be implemented here */
1147 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.\n");
1148 OSL_ASSERT(sal_False);
1150 __osl_destroySocketAddr( pSockAddr );
1151 free (cn);
1152 return ((oslHostAddr)NULL);
1155 pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1156 OSL_ASSERT(pAddr);
1157 if (pAddr == NULL)
1159 __osl_destroySocketAddr( pSockAddr );
1160 free (cn);
1161 return ((oslHostAddr)NULL);
1164 pAddr->pHostName= cn;
1165 pAddr->pSockAddr= pSockAddr;
1167 return pAddr;
1170 /*****************************************************************************/
1171 /* osl_createHostAddr */
1172 /*****************************************************************************/
1173 oslHostAddr SAL_CALL osl_createHostAddr (
1174 rtl_uString *ustrHostname,
1175 const oslSocketAddr Addr)
1177 oslHostAddr HostAddr;
1178 rtl_String* strHostname=0;
1179 sal_Char* pszHostName=0;
1181 if ( ustrHostname != 0 )
1183 rtl_uString2String( &strHostname,
1184 rtl_uString_getStr(ustrHostname),
1185 rtl_uString_getLength(ustrHostname),
1186 RTL_TEXTENCODING_UTF8,
1187 OUSTRING_TO_OSTRING_CVTFLAGS );
1188 pszHostName = rtl_string_getStr(strHostname);
1191 HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
1193 if ( strHostname != 0 )
1195 rtl_string_release(strHostname);
1199 return HostAddr;
1202 oslHostAddr SAL_CALL osl_psz_createHostAddr (
1203 const sal_Char *pszHostname,
1204 const oslSocketAddr pAddr)
1206 oslHostAddr pHostAddr;
1207 sal_Char *cn;
1209 OSL_ASSERT(pszHostname && pAddr);
1210 if ((pszHostname == NULL) || (pAddr == NULL))
1211 return ((oslHostAddr)NULL);
1213 cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
1214 OSL_ASSERT(cn);
1215 if (cn == NULL)
1216 return ((oslHostAddr)NULL);
1218 strcpy (cn, pszHostname);
1220 pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1221 OSL_ASSERT(pHostAddr);
1222 if (pAddr == NULL)
1224 free (cn);
1225 return ((oslHostAddr)NULL);
1228 pHostAddr->pHostName= cn;
1229 pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
1231 return pHostAddr;
1234 /*****************************************************************************/
1235 /* osl_createHostAddrByName */
1236 /*****************************************************************************/
1237 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
1239 oslHostAddr HostAddr;
1240 rtl_String* strHostname=0;
1241 sal_Char* pszHostName=0;
1243 if ( ustrHostname != 0 )
1245 rtl_uString2String( &strHostname,
1246 rtl_uString_getStr(ustrHostname),
1247 rtl_uString_getLength(ustrHostname),
1248 RTL_TEXTENCODING_UTF8,
1249 OUSTRING_TO_OSTRING_CVTFLAGS );
1250 pszHostName=rtl_string_getStr(strHostname);
1253 HostAddr = osl_psz_createHostAddrByName(pszHostName);
1255 if ( strHostname != 0 )
1257 rtl_string_release(strHostname);
1260 return HostAddr;
1263 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
1265 struct hostent *he;
1266 oslHostAddr addr;
1268 static oslMutex mutex = NULL;
1270 if (mutex == NULL)
1271 mutex = osl_createMutex();
1273 osl_acquireMutex(mutex);
1275 he = gethostbyname((sal_Char *)pszHostname);
1276 addr = _osl_hostentToHostAddr (he);
1278 osl_releaseMutex(mutex);
1280 return addr;
1283 /*****************************************************************************/
1284 /* osl_createHostAddrByAddr */
1285 /*****************************************************************************/
1286 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
1288 OSL_ASSERT(pAddr);
1290 if (pAddr == NULL)
1291 return ((oslHostAddr)NULL);
1293 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1295 const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
1296 struct hostent *he;
1298 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
1299 return ((oslHostAddr)NULL);
1301 he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
1302 sizeof (sin->sin_addr),
1303 sin->sin_family);
1304 return _osl_hostentToHostAddr (he);
1307 return ((oslHostAddr)NULL);
1310 /*****************************************************************************/
1311 /* osl_copyHostAddr */
1312 /*****************************************************************************/
1313 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
1315 OSL_ASSERT(pAddr);
1317 if (pAddr)
1318 return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
1319 else
1320 return ((oslHostAddr)NULL);
1323 /*****************************************************************************/
1324 /* osl_getHostnameOfHostAddr */
1325 /*****************************************************************************/
1326 void SAL_CALL osl_getHostnameOfHostAddr (
1327 const oslHostAddr Addr,
1328 rtl_uString **ustrHostname)
1330 const sal_Char* pHostname=0;
1332 pHostname = osl_psz_getHostnameOfHostAddr(Addr);
1334 rtl_uString_newFromAscii (ustrHostname, pHostname);
1336 return;
1339 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1341 OSL_ASSERT(pAddr);
1343 if (pAddr)
1344 return pAddr->pHostName;
1345 else
1346 return NULL;
1349 /*****************************************************************************/
1350 /* osl_getSocketAddrOfHostAddr */
1351 /*****************************************************************************/
1352 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1354 OSL_ASSERT(pAddr);
1356 if (pAddr)
1357 return ((oslSocketAddr)(pAddr->pSockAddr));
1358 else
1359 return NULL;
1362 /*****************************************************************************/
1363 /* osl_destroyHostAddr */
1364 /*****************************************************************************/
1365 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1367 if (pAddr)
1369 if (pAddr->pHostName)
1370 free (pAddr->pHostName);
1371 if (pAddr->pSockAddr)
1372 osl_destroySocketAddr (pAddr->pSockAddr);
1373 free (pAddr);
1377 /*****************************************************************************/
1378 /* osl_getLocalHostname */
1379 /*****************************************************************************/
1380 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1382 oslSocketResult Result;
1383 sal_Char pszHostname[1024];
1385 pszHostname[0] = '\0';
1387 Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1389 rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1391 return Result;
1394 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1395 sal_Char *pBuffer, sal_uInt32 nBufLen)
1397 static sal_Char LocalHostname[256] = "";
1399 if (strlen(LocalHostname) == 0)
1401 const sal_Char *pStr;
1403 #ifdef SYSV
1404 struct utsname uts;
1406 if (uname(&uts) < 0)
1407 return osl_Socket_Error;
1409 if ((strlen(uts.nodename) + 1) > nBufLen)
1410 return osl_Socket_Error;
1412 strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1413 #else /* BSD compatible */
1415 if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1416 return osl_Socket_Error;
1417 LocalHostname[sizeof(LocalHostname)-1] = 0;
1418 #endif /* SYSV */
1420 /* check if we have an FQDN */
1421 if (strchr(LocalHostname, '.') == NULL)
1423 oslHostAddr Addr;
1425 /* no, determine it via dns */
1426 Addr = osl_psz_createHostAddrByName(LocalHostname);
1428 if (Addr && (pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1430 #if 0 /* OBSOLETE */
1431 sal_Char* pChr;
1432 #endif /* OBSOLETE */
1433 strcpy(LocalHostname, pStr);
1435 #if 0 /* OBSOLETE */
1436 /* already done by _osl_getFullQualifiedDomainName() with
1437 much better heuristics, so this may be contraproductive */
1439 /* no FQDN, last try append domain name */
1440 if ((pChr = strchr(LocalHostname, '.')) == NULL)
1442 FILE *fp;
1444 pChr = &LocalHostname[strlen(LocalHostname)];
1446 if ( (fp = popen("domainname", "r")) != 0 )
1448 int c;
1450 *pChr++ = '.';
1452 while ((c = getc(fp)) != EOF)
1454 if (! isspace(c))
1455 *pChr++ = (sal_Char)c;
1458 *pChr = '\0';
1460 fclose(fp);
1462 else
1463 LocalHostname[0] = '\0';
1465 #endif /* OBSOLETE */
1468 if (Addr)
1469 osl_destroyHostAddr(Addr);
1473 if (strlen(LocalHostname) > 0)
1475 strncpy(pBuffer, LocalHostname, nBufLen);
1476 pBuffer[nBufLen - 1] = '\0';
1478 return osl_Socket_Ok;
1481 return osl_Socket_Error;
1484 /*****************************************************************************/
1485 /* osl_resolveHostname */
1486 /*****************************************************************************/
1487 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1489 oslSocketAddr Addr;
1490 rtl_String* strHostname=0;
1491 sal_Char* pszHostName=0;
1493 if ( ustrHostname != 0 )
1495 rtl_uString2String( &strHostname,
1496 rtl_uString_getStr(ustrHostname),
1497 rtl_uString_getLength(ustrHostname),
1498 RTL_TEXTENCODING_UTF8,
1499 OUSTRING_TO_OSTRING_CVTFLAGS );
1500 pszHostName = rtl_string_getStr(strHostname);
1504 Addr = osl_psz_resolveHostname(pszHostName);
1506 if ( strHostname != 0 )
1508 rtl_string_release(strHostname);
1512 return Addr;
1516 oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1518 struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1520 if (pAddr)
1522 oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1524 osl_destroyHostAddr(pAddr);
1526 return (SockAddr);
1529 return ((oslSocketAddr)NULL);
1532 /*****************************************************************************/
1533 /* osl_getServicePort */
1534 /*****************************************************************************/
1535 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1537 sal_Int32 nPort;
1538 rtl_String* strServicename=0;
1539 rtl_String* strProtocol=0;
1540 sal_Char* pszServiceName=0;
1541 sal_Char* pszProtocol=0;
1543 if ( ustrServicename != 0 )
1545 rtl_uString2String( &strServicename,
1546 rtl_uString_getStr(ustrServicename),
1547 rtl_uString_getLength(ustrServicename),
1548 RTL_TEXTENCODING_UTF8,
1549 OUSTRING_TO_OSTRING_CVTFLAGS );
1550 pszServiceName = rtl_string_getStr(strServicename);
1553 if ( ustrProtocol != 0 )
1555 rtl_uString2String( &strProtocol,
1556 rtl_uString_getStr(ustrProtocol),
1557 rtl_uString_getLength(ustrProtocol),
1558 RTL_TEXTENCODING_UTF8,
1559 OUSTRING_TO_OSTRING_CVTFLAGS );
1560 pszProtocol = rtl_string_getStr(strProtocol);
1563 nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1565 if ( strServicename != 0 )
1567 rtl_string_release(strServicename);
1570 if ( strProtocol != 0 )
1572 rtl_string_release(strProtocol);
1576 return nPort;
1580 sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1581 const sal_Char* pszProtocol)
1583 struct servent* ps;
1585 ps= getservbyname(pszServicename, pszProtocol);
1587 if (ps != 0)
1588 return ntohs(ps->s_port);
1590 return OSL_INVALID_PORT;
1593 /*****************************************************************************/
1594 /* osl_destroySocketAddr */
1595 /*****************************************************************************/
1596 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1598 __osl_destroySocketAddr( pAddr );
1601 /*****************************************************************************/
1602 /* osl_getFamilyOfSocketAddr */
1603 /*****************************************************************************/
1604 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1606 OSL_ASSERT(pAddr);
1608 if (pAddr)
1609 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1610 else
1611 return osl_Socket_FamilyInvalid;
1614 /*****************************************************************************/
1615 /* osl_getInetPortOfSocketAddr */
1616 /*****************************************************************************/
1617 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1619 OSL_ASSERT(pAddr);
1620 if( pAddr )
1622 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1624 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1625 return ntohs(pSystemInetAddr->sin_port);
1627 return OSL_INVALID_PORT;
1630 /*****************************************************************************/
1631 /* osl_setInetPortOfSocketAddr */
1632 /*****************************************************************************/
1633 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1635 OSL_ASSERT(pAddr);
1636 if( pAddr )
1638 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1639 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1641 pSystemInetAddr->sin_port= htons((short)Port);
1642 return sal_True;
1646 /* this is not a inet-addr => can't set port */
1647 return sal_False;
1650 /*****************************************************************************/
1651 /* osl_getHostnameOfSocketAddr */
1652 /*****************************************************************************/
1653 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1655 oslSocketResult Result;
1656 sal_Char pszHostname[1024];
1658 pszHostname[0] = '\0';
1660 Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1662 rtl_uString_newFromAscii(ustrHostname,pszHostname);
1664 return Result;
1668 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1669 sal_Char *pBuffer, sal_uInt32 BufferSize)
1671 oslHostAddr pHostAddr= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1673 if (pHostAddr)
1675 strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1677 pBuffer[BufferSize - 1] = '\0';
1679 osl_destroyHostAddr(pHostAddr);
1681 return osl_Socket_Ok;
1684 return osl_Socket_Error;
1687 /*****************************************************************************/
1688 /* osl_getDottedInetAddrOfSocketAddr */
1689 /*****************************************************************************/
1690 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1692 oslSocketResult Result;
1693 sal_Char pszDottedInetAddr[1024];
1695 pszDottedInetAddr[0] = '\0';
1697 Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1699 rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1701 return Result;
1705 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1706 sal_Char *pBuffer, sal_uInt32 BufferSize)
1708 OSL_ASSERT(pAddr);
1710 if( pAddr )
1712 struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1714 if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1716 strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1717 pBuffer[BufferSize - 1] = '\0';
1719 return osl_Socket_Ok;
1723 return osl_Socket_Error;
1726 #if 0 /* OBSOLETE */
1727 /*****************************************************************************/
1728 /* osl_getIpxNetNumber */
1729 /*****************************************************************************/
1730 oslSocketResult SAL_CALL osl_getIpxNetNumber(oslSocketAddr Addr,
1731 oslSocketIpxNetNumber NetNumber)
1734 struct sockaddr_ipx* pAddr;
1736 pAddr= (struct sockaddr_ipx*)Addr;
1738 OSL_ASSERT(pAddr);
1740 if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1742 memcpy(NetNumber, pAddr->sa_netnum, sizeof(NetNumber));
1744 return osl_Socket_Ok;
1746 else
1747 return osl_Socket_Error;
1751 /*****************************************************************************/
1752 /* osl_getIpxNodeNumber */
1753 /*****************************************************************************/
1754 oslSocketResult SAL_CALL osl_getIpxNodeNumber(oslSocketAddr Addr,
1755 oslSocketIpxNodeNumber NodeNumber)
1758 struct sockaddr_ipx* pAddr;
1760 pAddr= (struct sockaddr_ipx*)Addr;
1762 OSL_ASSERT(pAddr);
1764 if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1766 memcpy(NodeNumber, pAddr->sa_nodenum, sizeof(NodeNumber));
1768 return osl_Socket_Ok;
1770 else
1771 return osl_Socket_Error;
1775 /*****************************************************************************/
1776 /* osl_getIpxSocketNumber */
1777 /*****************************************************************************/
1778 sal_Int32 SAL_CALL osl_getIpxSocketNumber(oslSocketAddr Addr)
1780 struct sockaddr_ipx* pAddr= (struct sockaddr_ipx*)Addr;
1781 OSL_ASSERT(pAddr);
1783 if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1784 return pAddr->sa_socket;
1785 else
1786 return OSL_INVALID_IPX_SOCKET_NO;
1789 #endif /* OBSOLETE */
1791 /*****************************************************************************/
1792 /* osl_createSocket */
1793 /*****************************************************************************/
1794 oslSocket SAL_CALL osl_createSocket(oslAddrFamily Family,
1795 oslSocketType Type,
1796 oslProtocol Protocol)
1798 int Flags;
1799 oslSocket pSocket;
1801 /* alloc memory */
1802 pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1804 /* create socket */
1805 pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1806 TYPE_TO_NATIVE(Type),
1807 PROTOCOL_TO_NATIVE(Protocol));
1809 /* creation failed => free memory */
1810 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1812 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1813 errno,
1814 strerror(errno));
1816 __osl_destroySocketImpl((pSocket));
1817 pSocket= 0;
1819 else
1821 /* set close-on-exec flag */
1822 if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1824 Flags |= FD_CLOEXEC;
1825 if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1827 pSocket->m_nLastError=errno;
1828 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1829 errno,
1830 strerror(errno));
1833 else
1835 pSocket->m_nLastError=errno;
1839 pSocket->m_CloseCallback = NULL;
1840 pSocket->m_CallbackArg = NULL;
1843 return pSocket;
1846 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1848 osl_incrementInterlockedCount( &(pSocket->m_nRefCount ) );
1851 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1853 if( pSocket && 0 == osl_decrementInterlockedCount( &(pSocket->m_nRefCount) ) )
1855 #if defined(LINUX)
1856 if ( pSocket->m_bIsAccepting == sal_True )
1858 OSL_ENSURE(0, "osl_destroySocket : attempt to destroy socket while accepting\n");
1859 return;
1861 #endif /* LINUX */
1862 osl_closeSocket( pSocket );
1863 __osl_destroySocketImpl( pSocket );
1869 /*****************************************************************************/
1870 /* osl_closeSocket */
1871 /*****************************************************************************/
1872 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1874 int nRet;
1875 int nFD;
1877 /* socket already invalid */
1878 if(pSocket==0)
1879 return;
1881 pSocket->m_nLastError=0;
1882 nFD = pSocket->m_Socket;
1884 pSocket->m_Socket = OSL_INVALID_SOCKET;
1886 #if defined(LINUX)
1887 pSocket->m_bIsInShutdown = sal_True;
1889 if ( pSocket->m_bIsAccepting == sal_True )
1891 int nConnFD;
1892 struct sockaddr aSockAddr;
1893 socklen_t nSockLen = sizeof(aSockAddr);
1895 nRet = getsockname(nFD, &aSockAddr, &nSockLen);
1896 #if OSL_DEBUG_LEVEL > 1
1897 if ( nRet < 0 )
1899 perror("getsockname");
1901 #endif /* OSL_DEBUG_LEVEL */
1903 if ( aSockAddr.sa_family == AF_INET )
1905 struct sockaddr_in* pSockAddrIn = (struct sockaddr_in*) &aSockAddr;
1907 if ( pSockAddrIn->sin_addr.s_addr == htonl(INADDR_ANY) )
1909 pSockAddrIn->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1912 nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1913 #if OSL_DEBUG_LEVEL > 1
1914 if ( nConnFD < 0 )
1916 perror("socket");
1918 #endif /* OSL_DEBUG_LEVEL */
1920 nRet = connect(nConnFD, &aSockAddr, sizeof(aSockAddr));
1921 #if OSL_DEBUG_LEVEL > 1
1922 if ( nRet < 0 )
1924 perror("connect");
1926 #endif /* OSL_DEBUG_LEVEL */
1927 close(nConnFD);
1930 #endif /* LINUX */
1932 /* registrierten Callback ausfuehren */
1933 if (pSocket->m_CloseCallback != NULL)
1935 pSocket->m_CloseCallback(pSocket->m_CallbackArg);
1938 nRet=close(nFD);
1939 if ( nRet != 0 )
1941 pSocket->m_nLastError=errno;
1942 OSL_TRACE("closeSocket close error '%s'\n",strerror(errno));
1945 pSocket->m_Socket = OSL_INVALID_SOCKET;
1948 /*****************************************************************************/
1949 /* osl_getLocalAddrOfSocket */
1950 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1951 /* are the same! I don't like it very much but see no other easy way to conceal */
1952 /* the struct sockaddr from the eyes of the user. */
1953 /*****************************************************************************/
1954 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1956 #if defined(LINUX) || defined(FREEBSD)
1957 socklen_t AddrLen;
1958 #else
1959 /* mfe: Solaris 'cc +w' means Addrlen should be signed! */
1960 /* it's really defined as 'int*' in /usr/include/sys/socket.h! */
1961 /* the man page says it expects a 'size_t' */
1962 int AddrLen;
1963 #endif
1964 struct sockaddr Addr;
1965 oslSocketAddr pAddr;
1967 if (pSocket == NULL) /* ENOTSOCK */
1968 return ((oslSocketAddr)NULL);
1970 AddrLen= sizeof(struct sockaddr);
1972 if (getsockname(pSocket->m_Socket, &Addr, PTR_SIZE_T(AddrLen)) == OSL_SOCKET_ERROR)
1973 return ((oslSocketAddr)NULL);
1975 pAddr = __osl_createSocketAddrFromSystem( &Addr );
1976 return pAddr;
1979 /*****************************************************************************/
1980 /* osl_getPeerAddrOfSocket */
1981 /*****************************************************************************/
1982 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1984 sal_uInt32 AddrLen;
1985 struct sockaddr Addr;
1987 OSL_ASSERT(pSocket);
1988 if ( pSocket == 0 )
1990 return 0;
1993 pSocket->m_nLastError=0;
1994 AddrLen= sizeof(struct sockaddr);
1996 if(getpeername(pSocket->m_Socket, &Addr, (int*)PTR_SIZE_T(AddrLen)) == OSL_SOCKET_ERROR)
1998 pSocket->m_nLastError=errno;
1999 return 0;
2001 return __osl_createSocketAddrFromSystem( &Addr );
2004 /*****************************************************************************/
2005 /* osl_bindAddrToSocket */
2006 /*****************************************************************************/
2007 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
2008 oslSocketAddr pAddr)
2010 int nRet;
2012 OSL_ASSERT(pSocket && pAddr );
2013 if ( pSocket == 0 || pAddr == 0 )
2015 return sal_False;
2018 pSocket->m_nLastError=0;
2020 nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
2022 if ( nRet == OSL_SOCKET_ERROR)
2024 pSocket->m_nLastError=errno;
2025 return sal_False;
2028 return sal_True;
2032 /*****************************************************************************/
2033 /* osl_listenOnSocket */
2034 /*****************************************************************************/
2035 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
2036 sal_Int32 MaxPendingConnections)
2038 int nRet;
2040 OSL_ASSERT(pSocket);
2041 if ( pSocket == 0 )
2043 return sal_False;
2046 pSocket->m_nLastError=0;
2048 nRet = listen(pSocket->m_Socket,
2049 MaxPendingConnections == -1 ?
2050 SOMAXCONN :
2051 MaxPendingConnections);
2052 if ( nRet == OSL_SOCKET_ERROR)
2054 pSocket->m_nLastError=errno;
2055 return sal_False;
2058 return sal_True;
2062 /*****************************************************************************/
2063 /* osl_connectSocketTo */
2064 /*****************************************************************************/
2065 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
2066 oslSocketAddr pAddr,
2067 const TimeValue* pTimeout)
2069 fd_set WriteSet;
2070 fd_set ExcptSet;
2071 int ReadyHandles;
2072 struct timeval tv;
2073 oslSocketResult Result= osl_Socket_Ok;
2075 OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
2077 if ( pSocket == 0 )
2079 return osl_Socket_Error;
2082 pSocket->m_nLastError=0;
2084 if (osl_isNonBlockingMode(pSocket))
2086 if (connect(pSocket->m_Socket,
2087 &(pAddr->m_sockaddr),
2088 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2089 return osl_Socket_Ok;
2090 else
2091 if (errno == EWOULDBLOCK || errno == EINPROGRESS)
2093 pSocket->m_nLastError=EINPROGRESS;
2094 return osl_Socket_InProgress;
2098 pSocket->m_nLastError=errno;
2099 OSL_TRACE("can't connect : '%s'",strerror(errno));
2100 return osl_Socket_Error;
2103 /* set socket temporarily to non-blocking */
2104 OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
2106 /* initiate connect */
2107 if(connect(pSocket->m_Socket,
2108 &(pAddr->m_sockaddr),
2109 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2111 /* immediate connection */
2112 osl_enableNonBlockingMode(pSocket, sal_False);
2114 return osl_Socket_Ok;
2116 else
2118 /* really an error or just delayed? */
2119 if (errno != EINPROGRESS)
2121 pSocket->m_nLastError=errno;
2122 OSL_TRACE(
2123 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
2124 errno, strerror(errno));
2126 osl_enableNonBlockingMode(pSocket, sal_False);
2127 return osl_Socket_Error;
2132 /* prepare select set for socket */
2133 FD_ZERO(&WriteSet);
2134 FD_ZERO(&ExcptSet);
2135 FD_SET(pSocket->m_Socket, &WriteSet);
2136 FD_SET(pSocket->m_Socket, &ExcptSet);
2138 /* prepare timeout */
2139 if (pTimeout)
2141 /* divide milliseconds into seconds and microseconds */
2142 tv.tv_sec= pTimeout->Seconds;
2143 tv.tv_usec= pTimeout->Nanosec / 1000L;
2146 /* select */
2147 ReadyHandles= select(pSocket->m_Socket+1,
2149 PTR_FD_SET(WriteSet),
2150 PTR_FD_SET(ExcptSet),
2151 (pTimeout) ? &tv : 0);
2153 if (ReadyHandles > 0) /* connected */
2155 if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
2157 int nErrorCode = 0;
2158 #ifdef SOLARIS
2159 /* mfe: Solaris 'cc +w' means 5th argument should be a 'int*'!
2160 it's really defined as 'int*' in /usr/include/sys/socket.h!
2161 the man page says it expects a 'size_t*'
2163 int nErrorSize = sizeof( nErrorCode );
2164 #else
2165 size_t nErrorSize = sizeof( nErrorCode );
2166 #endif
2168 int nSockOpt;
2170 nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
2171 #ifdef SOLARIS
2172 /* mfe: Solaris 'cc +w' means 4th argument should be a 'char*'!
2173 it's really defined as 'char*' in /usr/include/sys/socket.h!
2174 the man page says it expects a 'void*'
2176 (char*)
2177 #endif
2178 &nErrorCode, (int*)&nErrorSize );
2179 if ( (nSockOpt == 0) && (nErrorCode == 0))
2180 Result = osl_Socket_Ok;
2181 else
2182 Result = osl_Socket_Error;
2184 else
2186 Result= osl_Socket_Error;
2189 else if (ReadyHandles < 0) /* error */
2191 if (errno == EBADF) /* most probably interrupted by close() */
2193 /* do not access pSockImpl because it is about to be or */
2194 /* already destroyed */
2195 return osl_Socket_Interrupted;
2197 else
2199 pSocket->m_nLastError=errno;
2200 Result= osl_Socket_Error;
2203 else /* timeout */
2205 pSocket->m_nLastError=errno;
2206 Result= osl_Socket_TimedOut;
2209 osl_enableNonBlockingMode(pSocket, sal_False);
2211 return Result;
2215 /*****************************************************************************/
2216 /* osl_acceptConnectionOnSocket */
2217 /*****************************************************************************/
2218 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
2219 oslSocketAddr* ppAddr)
2221 struct sockaddr Addr;
2222 int Connection, Flags;
2223 sal_uInt32 AddrLen = sizeof(struct sockaddr);
2224 oslSocket pConnectionSockImpl;
2226 OSL_ASSERT(pSocket);
2227 if ( pSocket == 0 )
2229 return 0;
2232 pSocket->m_nLastError=0;
2233 #if defined(LINUX)
2234 pSocket->m_bIsAccepting = sal_True;
2235 #endif /* LINUX */
2237 if( ppAddr && *ppAddr )
2239 osl_destroySocketAddr( *ppAddr );
2240 *ppAddr = 0;
2243 /* prevent Linux EINTR behaviour */
2246 Connection = accept(pSocket->m_Socket, &Addr, (int*)PTR_SIZE_T(AddrLen));
2247 } while (Connection == -1 && errno == EINTR);
2250 /* accept failed? */
2251 if( Connection == OSL_SOCKET_ERROR )
2253 pSocket->m_nLastError=errno;
2254 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'\n",strerror(errno));
2256 #if defined(LINUX)
2257 pSocket->m_bIsAccepting = sal_False;
2258 #endif /* LINUX */
2259 return 0;
2262 OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
2265 #if defined(LINUX)
2266 if ( pSocket->m_bIsInShutdown == sal_True )
2268 close(Connection);
2269 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept\n");
2270 return 0;
2272 #endif /* LINUX */
2275 if(ppAddr)
2277 *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
2280 /* alloc memory */
2281 pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
2283 /* set close-on-exec flag */
2284 if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
2286 Flags |= FD_CLOEXEC;
2287 if (fcntl(Connection, F_SETFD, Flags) == -1)
2289 pSocket->m_nLastError=errno;
2290 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
2291 errno,
2292 strerror(errno));
2297 pConnectionSockImpl->m_Socket = Connection;
2298 pConnectionSockImpl->m_nLastError = 0;
2299 pConnectionSockImpl->m_CloseCallback = NULL;
2300 pConnectionSockImpl->m_CallbackArg = NULL;
2301 #if defined(LINUX)
2302 pConnectionSockImpl->m_bIsAccepting = sal_False;
2304 pSocket->m_bIsAccepting = sal_False;
2305 #endif /* LINUX */
2306 return pConnectionSockImpl;
2309 /*****************************************************************************/
2310 /* osl_receiveSocket */
2311 /*****************************************************************************/
2312 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
2313 void* pBuffer,
2314 sal_uInt32 BytesToRead,
2315 oslSocketMsgFlag Flag)
2317 int nRead;
2319 OSL_ASSERT(pSocket);
2320 if ( pSocket == 0 )
2322 OSL_TRACE("osl_receiveSocket : Invalid socket");
2323 return -1;
2326 pSocket->m_nLastError=0;
2330 nRead = recv(pSocket->m_Socket,
2331 (sal_Char*)pBuffer,
2332 BytesToRead,
2333 MSG_FLAG_TO_NATIVE(Flag));
2334 } while ( nRead < 0 && errno == EINTR );
2336 if ( nRead < 0 )
2338 pSocket->m_nLastError=errno;
2339 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
2341 else if ( nRead == 0 )
2343 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2346 return nRead;
2350 /*****************************************************************************/
2351 /* osl_receiveFromSocket */
2352 /*****************************************************************************/
2353 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
2354 oslSocketAddr pSenderAddr,
2355 void* pBuffer,
2356 sal_uInt32 BufferSize,
2357 oslSocketMsgFlag Flag)
2359 int nRead;
2360 struct sockaddr *pSystemSockAddr = 0;
2361 int AddrLen = 0;
2362 if( pSenderAddr )
2364 AddrLen = sizeof( struct sockaddr );
2365 pSystemSockAddr = &(pSenderAddr->m_sockaddr);
2368 OSL_ASSERT(pSocket);
2369 if ( pSocket == 0 )
2371 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
2372 return -1;
2375 pSocket->m_nLastError=0;
2377 nRead = recvfrom(pSocket->m_Socket,
2378 (sal_Char*)pBuffer,
2379 BufferSize,
2380 MSG_FLAG_TO_NATIVE(Flag),
2381 pSystemSockAddr,
2382 PTR_SIZE_T(AddrLen));
2384 if ( nRead < 0 )
2386 pSocket->m_nLastError=errno;
2387 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
2389 else if ( nRead == 0 )
2391 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2394 return nRead;
2398 /*****************************************************************************/
2399 /* osl_sendSocket */
2400 /*****************************************************************************/
2401 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
2402 const void* pBuffer,
2403 sal_uInt32 BytesToSend,
2404 oslSocketMsgFlag Flag)
2406 int nWritten;
2408 OSL_ASSERT(pSocket);
2409 if ( pSocket == 0 )
2411 OSL_TRACE("osl_sendSocket : Invalid socket");
2412 return -1;
2415 pSocket->m_nLastError=0;
2419 nWritten = send(pSocket->m_Socket,
2420 (sal_Char*)pBuffer,
2421 BytesToSend,
2422 MSG_FLAG_TO_NATIVE(Flag));
2423 } while ( nWritten < 0 && errno == EINTR );
2426 if ( nWritten < 0 )
2428 pSocket->m_nLastError=errno;
2429 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
2431 else if ( nWritten == 0 )
2433 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
2436 return nWritten;
2439 /*****************************************************************************/
2440 /* osl_sendToSocket */
2441 /*****************************************************************************/
2442 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
2443 oslSocketAddr ReceiverAddr,
2444 const void* pBuffer,
2445 sal_uInt32 BytesToSend,
2446 oslSocketMsgFlag Flag)
2448 int nWritten;
2450 struct sockaddr *pSystemSockAddr = 0;
2451 int AddrLen = 0;
2452 if( ReceiverAddr )
2454 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
2455 AddrLen = sizeof( struct sockaddr );
2458 OSL_ASSERT(pSocket);
2459 if ( pSocket == 0 )
2461 OSL_TRACE("osl_sendToSocket : Invalid socket");
2462 return -1;
2465 pSocket->m_nLastError=0;
2467 /* ReceiverAddr might be 0 when used on a connected socket. */
2468 /* Then sendto should behave like send. */
2470 nWritten = sendto(pSocket->m_Socket,
2471 (sal_Char*)pBuffer,
2472 BytesToSend,
2473 MSG_FLAG_TO_NATIVE(Flag),
2474 pSystemSockAddr,
2475 AddrLen);
2477 if ( nWritten < 0 )
2479 pSocket->m_nLastError=errno;
2480 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
2482 else if ( nWritten == 0 )
2484 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
2487 return nWritten;
2490 /*****************************************************************************/
2491 /* osl_readSocket */
2492 /*****************************************************************************/
2493 sal_Int32 SAL_CALL osl_readSocket (
2494 oslSocket pSocket, void *pBuffer, sal_Int32 n )
2496 sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
2497 sal_uInt32 BytesRead= 0;
2498 sal_uInt32 BytesToRead= n;
2500 OSL_ASSERT( pSocket);
2502 /* loop until all desired bytes were read or an error occured */
2503 while (BytesToRead > 0)
2505 sal_Int32 RetVal;
2506 RetVal= osl_receiveSocket(pSocket,
2507 Ptr,
2508 BytesToRead,
2509 osl_Socket_MsgNormal);
2511 /* error occured? */
2512 if(RetVal <= 0)
2514 break;
2517 BytesToRead -= RetVal;
2518 BytesRead += RetVal;
2519 Ptr += RetVal;
2522 return BytesRead;
2525 /*****************************************************************************/
2526 /* osl_writeSocket */
2527 /*****************************************************************************/
2528 sal_Int32 SAL_CALL osl_writeSocket(
2529 oslSocket pSocket, const void *pBuffer, sal_Int32 n )
2531 /* loop until all desired bytes were send or an error occured */
2532 sal_uInt32 BytesSend= 0;
2533 sal_uInt32 BytesToSend= n;
2534 sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
2536 OSL_ASSERT( pSocket );
2538 while (BytesToSend > 0)
2540 sal_Int32 RetVal;
2542 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
2544 /* error occured? */
2545 if(RetVal <= 0)
2547 break;
2550 BytesToSend -= RetVal;
2551 BytesSend += RetVal;
2552 Ptr += RetVal;
2555 return BytesSend;
2558 /*****************************************************************************/
2559 /* __osl_socket_poll */
2560 /*****************************************************************************/
2562 #ifdef HAVE_POLL_H /* poll() */
2564 sal_Bool __osl_socket_poll (
2565 oslSocket pSocket,
2566 const TimeValue* pTimeout,
2567 short nEvent)
2569 struct pollfd fds;
2570 int timeout;
2571 int result;
2573 OSL_ASSERT(pSocket);
2574 pSocket->m_nLastError = 0;
2576 fds.fd = pSocket->m_Socket;
2577 fds.events = nEvent;
2578 fds.revents = 0;
2580 timeout = -1;
2581 if (pTimeout)
2583 /* Convert to [ms] */
2584 timeout = pTimeout->Seconds * 1000;
2585 timeout += pTimeout->Nanosec / (1000 * 1000);
2588 result = poll (&fds, 1, timeout);
2589 if (result < 0)
2591 pSocket->m_nLastError = errno;
2592 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2593 errno, strerror(errno));
2594 return sal_False;
2596 if (result == 0)
2598 /* Timeout */
2599 return sal_False;
2602 return ((fds.revents & nEvent) == nEvent);
2605 #else /* select() */
2607 sal_Bool __osl_socket_poll (
2608 oslSocket pSocket,
2609 const TimeValue* pTimeout,
2610 short nEvent)
2612 fd_set fds;
2613 struct timeval tv;
2614 int result;
2616 OSL_ASSERT(pSocket);
2617 pSocket->m_nLastError = 0;
2619 FD_ZERO(&fds);
2620 FD_SET(pSocket->m_Socket, &fds);
2622 if (pTimeout)
2624 /* Convert to 'timeval' */
2625 tv.tv_sec = pTimeout->Seconds;
2626 tv.tv_usec = pTimeout->Nanosec / 1000;
2629 result = select (
2630 pSocket->m_Socket + 1,
2631 (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2632 (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2633 (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2634 (pTimeout) ? &tv : NULL);
2636 if (result < 0)
2638 pSocket->m_nLastError = errno;
2639 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2640 errno, strerror(errno));
2641 return sal_False;
2643 if (result == 0)
2645 /* Timeout */
2646 return sal_False;
2649 return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2652 #endif /* HAVE_POLL_H */
2654 /*****************************************************************************/
2655 /* osl_isReceiveReady */
2656 /*****************************************************************************/
2657 sal_Bool SAL_CALL osl_isReceiveReady (
2658 oslSocket pSocket, const TimeValue* pTimeout)
2660 OSL_ASSERT(pSocket);
2661 if (pSocket == NULL)
2663 /* ENOTSOCK */
2664 return sal_False;
2667 return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2670 /*****************************************************************************/
2671 /* osl_isSendReady */
2672 /*****************************************************************************/
2673 sal_Bool SAL_CALL osl_isSendReady (
2674 oslSocket pSocket, const TimeValue* pTimeout)
2676 OSL_ASSERT(pSocket);
2677 if (pSocket == NULL)
2679 /* ENOTSOCK */
2680 return sal_False;
2683 return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2686 /*****************************************************************************/
2687 /* osl_isExceptionPending */
2688 /*****************************************************************************/
2689 sal_Bool SAL_CALL osl_isExceptionPending (
2690 oslSocket pSocket, const TimeValue* pTimeout)
2692 OSL_ASSERT(pSocket);
2693 if (pSocket == NULL)
2695 /* ENOTSOCK */
2696 return sal_False;
2699 return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2702 /*****************************************************************************/
2703 /* osl_shutdownSocket */
2704 /*****************************************************************************/
2705 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2706 oslSocketDirection Direction)
2708 int nRet;
2710 OSL_ASSERT(pSocket);
2711 if ( pSocket == 0 )
2713 return sal_False;
2716 pSocket->m_nLastError=0;
2718 nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2719 if (nRet != 0 )
2721 pSocket->m_nLastError=errno;
2722 OSL_TRACE("shutdown error '%s'\n",strerror(errno));
2724 return (nRet==0);
2728 /*****************************************************************************/
2729 /* osl_getSocketOption */
2730 /*****************************************************************************/
2731 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2732 oslSocketOptionLevel Level,
2733 oslSocketOption Option,
2734 void* pBuffer,
2735 sal_uInt32 BufferLen)
2737 OSL_ASSERT(pSocket);
2738 if ( pSocket == 0 )
2740 return -1;
2743 pSocket->m_nLastError=0;
2745 if(getsockopt(pSocket->m_Socket,
2746 OPTION_LEVEL_TO_NATIVE(Level),
2747 OPTION_TO_NATIVE(Option),
2748 (sal_Char*)pBuffer,
2749 (int*)PTR_SIZE_T(BufferLen)) == -1)
2751 pSocket->m_nLastError=errno;
2752 return -1;
2755 return BufferLen;
2758 /*****************************************************************************/
2759 /* osl_setSocketOption */
2760 /*****************************************************************************/
2761 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2762 oslSocketOptionLevel Level,
2763 oslSocketOption Option,
2764 void* pBuffer,
2765 sal_uInt32 BufferLen)
2767 int nRet;
2769 OSL_ASSERT(pSocket);
2770 if ( pSocket == 0 )
2772 return sal_False;
2775 pSocket->m_nLastError=0;
2777 nRet = setsockopt(pSocket->m_Socket,
2778 OPTION_LEVEL_TO_NATIVE(Level),
2779 OPTION_TO_NATIVE(Option),
2780 (sal_Char*)pBuffer,
2781 BufferLen);
2783 if ( nRet < 0 )
2785 pSocket->m_nLastError=errno;
2786 return sal_False;
2789 return sal_True;
2792 /*****************************************************************************/
2793 /* osl_enableNonBlockingMode */
2794 /*****************************************************************************/
2795 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2796 sal_Bool On)
2798 int flags;
2799 int nRet;
2801 OSL_ASSERT(pSocket);
2802 if ( pSocket == 0 )
2804 return sal_False;
2807 pSocket->m_nLastError=0;
2809 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2811 if (On)
2812 flags |= O_NONBLOCK;
2813 else
2814 flags &= ~(O_NONBLOCK);
2816 nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2818 if ( nRet < 0 )
2820 pSocket->m_nLastError=errno;
2821 return sal_False;
2824 return sal_True;
2827 /*****************************************************************************/
2828 /* osl_isNonBlockingMode */
2829 /*****************************************************************************/
2830 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2832 int flags;
2834 OSL_ASSERT(pSocket);
2835 if ( pSocket == 0 )
2837 return sal_False;
2840 pSocket->m_nLastError=0;
2842 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2844 if (flags == -1 || !(flags & O_NONBLOCK))
2845 return sal_False;
2846 else
2847 return sal_True;
2850 /*****************************************************************************/
2851 /* osl_getSocketType */
2852 /*****************************************************************************/
2853 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2855 int Type=0;
2856 sal_uInt32 TypeSize= sizeof(Type);
2858 OSL_ASSERT(pSocket);
2859 if ( pSocket == 0 )
2861 return osl_Socket_TypeInvalid;
2864 pSocket->m_nLastError=0;
2866 if(getsockopt(pSocket->m_Socket,
2867 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2868 OPTION_TO_NATIVE(osl_Socket_OptionType),
2869 (sal_Char*)&Type,
2870 (int*)PTR_SIZE_T(TypeSize)) == -1)
2872 /* error */
2873 pSocket->m_nLastError=errno;
2874 return osl_Socket_TypeInvalid;
2877 return TYPE_FROM_NATIVE(Type);
2881 /*****************************************************************************/
2882 /* osl_getLastSocketErrorDescription */
2883 /*****************************************************************************/
2884 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2886 sal_Char pszError[1024];
2888 pszError[0] = '\0';
2890 osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2892 rtl_uString_newFromAscii(ustrError,pszError);
2894 return;
2898 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2900 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2901 pBuffer[BufferSize-1]= '\0';
2903 if ( pSocket == 0 )
2905 strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2906 return;
2909 strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2910 return;
2913 /*****************************************************************************/
2914 /* osl_getLastSocketError */
2915 /*****************************************************************************/
2916 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2918 if ( pSocket == 0 )
2920 return ERROR_FROM_NATIVE(EINVAL);
2923 return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2926 /*****************************************************************************/
2927 /* SocketSet */
2928 /*****************************************************************************/
2929 typedef struct _TSocketSetImpl
2931 int m_MaxHandle; /* for select(), the largest descriptor in the set */
2932 fd_set m_Set; /* the set of descriptors */
2934 } TSocketSetImpl;
2936 /*****************************************************************************/
2937 /* osl_createSocketSet */
2938 /*****************************************************************************/
2939 oslSocketSet SAL_CALL osl_createSocketSet()
2941 TSocketSetImpl* pSet;
2943 pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2945 OSL_ASSERT(pSet);
2947 if(pSet)
2949 pSet->m_MaxHandle= 0;
2950 FD_ZERO(&pSet->m_Set);
2953 return (oslSocketSet)pSet;
2956 /*****************************************************************************/
2957 /* osl_destroySocketSet */
2958 /*****************************************************************************/
2959 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2961 if(Set)
2962 free(Set);
2965 /*****************************************************************************/
2966 /* osl_clearSocketSet */
2967 /*****************************************************************************/
2968 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2970 TSocketSetImpl* pSet;
2971 OSL_ASSERT(Set);
2972 if ( Set == 0 )
2974 return;
2977 pSet= (TSocketSetImpl*)Set;
2978 pSet->m_MaxHandle= 0;
2980 FD_ZERO(&pSet->m_Set);
2983 /*****************************************************************************/
2984 /* osl_addToSocketSet */
2985 /*****************************************************************************/
2986 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2988 TSocketSetImpl* pSet;
2990 OSL_ASSERT(Set);
2991 OSL_ASSERT(pSocket);
2993 if ( Set == 0 || pSocket == 0)
2995 return;
2998 pSet= (TSocketSetImpl*)Set;
3000 /* correct max handle */
3001 if(pSocket->m_Socket > pSet->m_MaxHandle)
3002 pSet->m_MaxHandle= pSocket->m_Socket;
3003 FD_SET(pSocket->m_Socket, &pSet->m_Set);
3007 /*****************************************************************************/
3008 /* osl_removeFromSocketSet */
3009 /*****************************************************************************/
3010 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
3012 TSocketSetImpl* pSet;
3014 OSL_ASSERT(Set);
3015 OSL_ASSERT(pSocket);
3017 if ( Set == 0 || pSocket == 0)
3019 return;
3022 pSet= (TSocketSetImpl*)Set;
3024 /* correct max handle */
3025 if(pSocket->m_Socket == pSet->m_MaxHandle)
3027 /* not optimal, since the next used descriptor might be */
3028 /* much smaller than m_Socket-1, but it will do */
3029 pSet->m_MaxHandle--;
3030 if(pSet->m_MaxHandle < 0)
3032 pSet->m_MaxHandle= 0; /* avoid underflow */
3036 FD_CLR(pSocket->m_Socket, &pSet->m_Set);
3039 /*****************************************************************************/
3040 /* osl_isInSocketSet */
3041 /*****************************************************************************/
3042 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
3044 TSocketSetImpl* pSet;
3046 OSL_ASSERT(Set);
3047 OSL_ASSERT(pSocket);
3048 if ( Set == 0 || pSocket == 0 )
3050 return sal_False;
3053 pSet= (TSocketSetImpl*)Set;
3055 return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
3058 /*****************************************************************************/
3059 /* osl_demultiplexSocketEvents */
3060 /*****************************************************************************/
3061 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
3062 oslSocketSet OutgoingSet,
3063 oslSocketSet OutOfBandSet,
3064 const TimeValue* pTimeout)
3066 int MaxHandle= 0;
3067 struct timeval tv;
3068 TSocketSetImpl* pInSet;
3069 TSocketSetImpl* pOutSet;
3070 TSocketSetImpl* pOOBSet;
3072 if (pTimeout)
3074 /* non-blocking call */
3075 tv.tv_sec = pTimeout->Seconds;
3076 tv.tv_usec = pTimeout->Nanosec / 1000L;
3079 /* map opaque data to impl-types */
3080 pInSet= (TSocketSetImpl*)IncomingSet;
3081 pOutSet= (TSocketSetImpl*)OutgoingSet;
3082 pOOBSet= (TSocketSetImpl*)OutOfBandSet;
3084 /* get max handle from all sets */
3085 if (pInSet)
3086 MaxHandle= pInSet->m_MaxHandle;
3088 if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
3089 MaxHandle= pOutSet->m_MaxHandle;
3091 if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
3092 MaxHandle= pOOBSet->m_MaxHandle;
3094 return select(MaxHandle+1,
3095 pInSet ? PTR_FD_SET(pInSet->m_Set) : 0,
3096 pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
3097 pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
3098 pTimeout ? &tv : 0);