xref: /trunk/main/sal/osl/os2/socket.c (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "system.h"
29 
30 #include <osl/socket.h>
31 #include <osl/diagnose.h>
32 #include <osl/mutex.h>
33 #include <osl/signal.h>
34 
35 #include <rtl/alloc.h>
36 
37 #include <ctype.h>
38 #include <sal/types.h>
39 
40 #include "sockimpl.h"
41 
42 
43 /* defines for poll */
44 #ifdef HAVE_POLL_H
45 #undef HAVE_POLL_H
46 #endif
47 
48 #if defined(LINUX) || defined(NETBSD) || defined ( FREEBSD ) || defined (MACOSX)
49 #include <sys/poll.h>
50 #define HAVE_POLL_H
51 #endif /* HAVE_POLL_H */
52 
53 #if defined(SOLARIS)
54 #include <poll.h>
55 #define HAVE_POLL_H
56 #endif /* SOLARIS */
57 
58 #ifndef HAVE_POLL_H
59 #define POLLIN  0x0001
60 #define POLLOUT 0x0002
61 #define POLLPRI 0x0004
62 #endif /* HAVE_POLL_H */
63 
64 
65 /* defines for shutdown */
66 #define SD_RECEIVE 0
67 #define SD_SEND 1
68 #define SD_BOTH 2
69 
70 
71 /*
72     oslSocketAddr is a pointer to a Berkeley struct sockaddr.
73     I refrained from using sockaddr_in because of possible further
74     extensions of this socket-interface (IP-NG?).
75     The intention was to hide all Berkeley data-structures from
76     direct access past the osl-interface.
77 
78     The current implementation is internet (IP) centered. All
79     the constructor-functions (osl_create...) take parameters
80     that will probably make sense only in the IP-environment
81     (e.g. because of using the dotted-address-format).
82 
83     If the interface will be extended to host other protocol-
84     families, I expect no externally visible changes in the
85     existing functions. You'll probably need only new
86     constructor-functions who take the different address
87     formats into consideration (maybe a long dotted address
88     or whatever).
89 */
90 
91 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
92 /* are the same! I don't like it very much but see no other easy way to  */
93 /* conceal the struct sockaddr from the eyes of the user. */
94 
95 
96 #define OSL_INVALID_SOCKET      -1
97 #define OSL_SOCKET_ERROR        -1
98 
99 
100 /* Buffer size for gethostbyname */
101 #define MAX_HOSTBUFFER_SIZE 2048
102 
103 /*****************************************************************************/
104 /* enum oslAddrFamily */
105 /*****************************************************************************/
106 
107 /* map */
108 static unsigned long FamilyMap[]= {
109     AF_INET,                    /* osl_Socket_FamilyInet    */
110     AF_IPX,                     /* osl_Socket_FamilyIpx     */
111     0                           /* osl_Socket_FamilyInvalid */
112 };
113 
114 /* reverse map */
115 static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
116 {
117     oslAddrFamily i= (oslAddrFamily)0;
118 
119     while(i != osl_Socket_FamilyInvalid)
120     {
121         if(FamilyMap[i] == nativeType)
122             return i;
123         i = (oslAddrFamily) ( i + 1 );
124     }
125 
126     return i;
127 }
128 
129 /* macros */
130 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
131 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
132 
133 /*****************************************************************************/
134 /* enum oslProtocol */
135 /*****************************************************************************/
136 
137 /* map */
138 static sal_uInt32 ProtocolMap[]= {
139     0,                          /* osl_Socket_ProtocolIp      */
140     NSPROTO_IPX,                /* osl_Socket_ProtocolIpx     */
141     NSPROTO_SPX,                /* osl_Socket_ProtocolSpx     */
142     NSPROTO_SPXII,              /* osl_Socket_ProtocolSpxII   */
143     0                           /* osl_Socket_ProtocolInvalid */
144 };
145 
146 /* reverse map */
147 /* mfe: NOT USED
148 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
149 {
150     oslProtocol i= (oslProtocol)0;
151 
152     while(i != osl_Socket_ProtocolInvalid)
153     {
154         if(ProtocolMap[i] == nativeType)
155             return i;
156         i = (oslProtocol) ( i + 1);
157     }
158 
159     return i;
160 }
161 */
162 
163 /* macros */
164 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
165 #define PROTOCOL_TO_NATIVE(x)   ProtocolMap[x]
166 
167 
168 /*****************************************************************************/
169 /* enum oslSocketType */
170 /*****************************************************************************/
171 
172 /* map */
173 static sal_uInt32 TypeMap[]= {
174     SOCK_STREAM,                /* osl_Socket_TypeStream    */
175     SOCK_DGRAM,                 /* osl_Socket_TypeDgram     */
176     SOCK_RAW,                   /* osl_Socket_TypeRaw       */
177     SOCK_RDM,                   /* osl_Socket_TypeRdm       */
178     SOCK_SEQPACKET,             /* osl_Socket_TypeSeqPacket */
179     0                           /* osl_Socket_TypeInvalid   */
180 };
181 
182 /* reverse map */
183 static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
184 {
185     oslSocketType i= (oslSocketType)0;
186 
187     while(i != osl_Socket_TypeInvalid)
188     {
189         if(TypeMap[i] == nativeType)
190             return i;
191         i = (oslSocketType)(i + 1);
192     }
193 
194     return i;
195 }
196 
197 /* macros */
198 #define TYPE_TO_NATIVE(x)       TypeMap[x]
199 #define TYPE_FROM_NATIVE(y)     osl_SocketTypeFromNative(y)
200 
201 
202 /*****************************************************************************/
203 /* enum oslSocketOption */
204 /*****************************************************************************/
205 
206 /* map */
207 static sal_uInt32 OptionMap[]= {
208     SO_DEBUG,                   /* osl_Socket_OptionDebug       */
209     SO_ACCEPTCONN,              /* osl_Socket_OptionAcceptConn  */
210     SO_REUSEADDR,               /* osl_Socket_OptionReuseAddr   */
211     SO_KEEPALIVE,               /* osl_Socket_OptionKeepAlive   */
212     SO_DONTROUTE,               /* osl_Socket_OptionDontRoute   */
213     SO_BROADCAST,               /* osl_Socket_OptionBroadcast   */
214     SO_USELOOPBACK,             /* osl_Socket_OptionUseLoopback */
215     SO_LINGER,                  /* osl_Socket_OptionLinger      */
216     SO_OOBINLINE,               /* osl_Socket_OptionOOBinLine   */
217     SO_SNDBUF,                  /* osl_Socket_OptionSndBuf      */
218     SO_RCVBUF,                  /* osl_Socket_OptionRcvBuf      */
219     SO_SNDLOWAT,                /* osl_Socket_OptionSndLowat    */
220     SO_RCVLOWAT,                /* osl_Socket_OptionRcvLowat    */
221     SO_SNDTIMEO,                /* osl_Socket_OptionSndTimeo    */
222     SO_RCVTIMEO,                /* osl_Socket_OptionRcvTimeo    */
223     SO_ERROR,                   /* osl_Socket_OptionError       */
224     SO_TYPE,                    /* osl_Socket_OptionType        */
225     TCP_NODELAY,                /* osl_Socket_OptionTcpNoDelay  */
226     0                           /* osl_Socket_OptionInvalid     */
227 };
228 
229 /* reverse map */
230 /* mfe: NOT USED
231 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
232 {
233     oslSocketOption i= (oslSocketOption)0;
234 
235     while(i != osl_Socket_OptionInvalid)
236     {
237         if(OptionMap[i] == nativeType)
238             return i;
239         i = (oslSocketOption) ( i + 1 );
240     }
241 
242     return i;
243 }
244 */
245 /* macros */
246 #define OPTION_TO_NATIVE(x)     OptionMap[x]
247 #define OPTION_FROM_NATIVE(y)       osl_SocketOptionFromNative(y)
248 
249 
250 /*****************************************************************************/
251 /* enum oslSocketOptionLevel */
252 /*****************************************************************************/
253 
254 static sal_uInt32 OptionLevelMap[]= {
255     SOL_SOCKET,                 /* osl_Socket_LevelSocket  */
256     IPPROTO_TCP,                /* osl_Socket_LevelTcp     */
257     0                           /* osl_Socket_LevelInvalid */
258 };
259 
260 /* reverse map */
261 /* mfe: NOT USED
262 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
263 {
264     oslSocketOptionLevel i= (oslSocketOptionLevel)0;
265 
266     while(i != osl_Socket_LevelInvalid)
267     {
268         if(OptionLevelMap[i] == nativeType)
269             return i;
270         i = (oslSocketOptionLevel) ( i + 1 );
271     }
272 
273     return i;
274 }
275 */
276 /* macros */
277 #define OPTION_LEVEL_TO_NATIVE(x)       OptionLevelMap[x]
278 #define OPTION_LEVEL_FROM_NATIVE(y)     osl_SocketOptionLevelFromNative(y)
279 
280 /*****************************************************************************/
281 /* enum oslSocketMsgFlag */
282 /*****************************************************************************/
283 
284 static sal_uInt32 SocketMsgFlagMap[]= {
285     0,                          /* osl_Socket_MsgNormal    */
286     MSG_OOB,                    /* osl_Socket_MsgOOB       */
287     MSG_PEEK,                   /* osl_Socket_MsgPeek      */
288     MSG_DONTROUTE,              /* osl_Socket_MsgDontRoute */
289     MSG_MAXIOVLEN,              /* osl_Socket_MsgMaxIOVLen */
290     0                           /* osl_Socket_MsgInvalid   */
291 };
292 
293 /* reverse map */
294 /* mfe: NOT USED
295 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
296 {
297     oslSocketMsgFlag i= (oslSocketMsgFlag)0;
298 
299     while(i != osl_Socket_MsgInvalid)
300     {
301         if(SocketMsgFlagMap[i] == nativeType)
302             return i;
303         i = (oslSocketMsgFlag) ( i + 1 );
304     }
305 
306     return i;
307 }
308 */
309 
310 /* macros */
311 #define MSG_FLAG_TO_NATIVE(x)       SocketMsgFlagMap[x]
312 #define MSG_FLAG_FROM_NATIVE(y)     osl_SocketMsgFlagFromNative(y)
313 
314 
315 /*****************************************************************************/
316 /* enum oslSocketDirection */
317 /*****************************************************************************/
318 
319 static sal_uInt32 SocketDirection[]= {
320     SD_RECEIVE,                 /* osl_Socket_DirRead      */
321     SD_SEND,                    /* osl_Socket_DirWrite     */
322     SD_BOTH,                    /* osl_Socket_DirReadWrite */
323     0                           /* osl_Socket_DirInvalid   */
324 };
325 
326 /* reverse map */
327 /* mfe: NOT USED
328 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
329 {
330     oslSocketDirection i= (oslSocketDirection)0;
331 
332     while(i != osl_Socket_DirInvalid)
333     {
334         if(SocketDirection[i] == nativeType)
335             return i;
336         i = (oslSocketDirection) ( i + 1 );
337     }
338 
339     return i;
340 }
341 */
342 
343 /* macros */
344 #define DIRECTION_TO_NATIVE(x)      SocketDirection[x]
345 #define DIRECTION_FROM_NATIVE(y)    osl_SocketDirectionFromNative(y)
346 
347 /*****************************************************************************/
348 /* enum oslSocketError */
349 /*****************************************************************************/
350 
351 static struct
352 {
353     int            errcode;
354     oslSocketError error;
355 } SocketError[]= {
356     { 0,               osl_Socket_E_None              }, /* no error */
357     { ENOTSOCK,        osl_Socket_E_NotSocket         }, /* Socket operation on non-socket */
358     { EDESTADDRREQ,    osl_Socket_E_DestAddrReq       }, /* Destination address required */
359     { EMSGSIZE,        osl_Socket_E_MsgSize           }, /* Message too long */
360     { EPROTOTYPE,      osl_Socket_E_Prototype         }, /* Protocol wrong type for socket */
361     { ENOPROTOOPT,     osl_Socket_E_NoProtocol        }, /* Protocol not available */
362     { EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
363     { ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport     }, /* Socket type not supported */
364     { EOPNOTSUPP,      osl_Socket_E_OpNotSupport      }, /* Operation not supported on socket */
365     { EPFNOSUPPORT,    osl_Socket_E_PfNoSupport       }, /* Protocol family not supported */
366     { EAFNOSUPPORT,    osl_Socket_E_AfNoSupport       }, /* Address family not supported by */
367                                                          /* protocol family */
368     { EADDRINUSE,      osl_Socket_E_AddrInUse         }, /* Address already in use */
369     { EADDRNOTAVAIL,   osl_Socket_E_AddrNotAvail      }, /* Can't assign requested address */
370     { ENETDOWN,        osl_Socket_E_NetDown           }, /* Network is down */
371     { ENETUNREACH,     osl_Socket_E_NetUnreachable    }, /* Network is unreachable */
372     { ENETRESET,       osl_Socket_E_NetReset          }, /* Network dropped connection because */
373                                                          /* of reset */
374     { ECONNABORTED,    osl_Socket_E_ConnAborted       }, /* Software caused connection abort */
375     { ECONNRESET,      osl_Socket_E_ConnReset         }, /* Connection reset by peer */
376     { ENOBUFS,         osl_Socket_E_NoBufferSpace     }, /* No buffer space available */
377     { EISCONN,         osl_Socket_E_IsConnected       }, /* Socket is already connected */
378     { ENOTCONN,        osl_Socket_E_NotConnected      }, /* Socket is not connected */
379     { ESHUTDOWN,       osl_Socket_E_Shutdown          }, /* Can't send after socket shutdown */
380     { ETOOMANYREFS,    osl_Socket_E_TooManyRefs       }, /* Too many references: can't splice */
381     { ETIMEDOUT,       osl_Socket_E_TimedOut          }, /* Connection timed out */
382     { ECONNREFUSED,    osl_Socket_E_ConnRefused       }, /* Connection refused */
383     { EHOSTDOWN,       osl_Socket_E_HostDown          }, /* Host is down */
384     { EHOSTUNREACH,    osl_Socket_E_HostUnreachable   }, /* No route to host */
385     { EWOULDBLOCK,     osl_Socket_E_WouldBlock        }, /* call would block on non-blocking socket */
386     { EALREADY,        osl_Socket_E_Already           }, /* operation already in progress */
387     { EINPROGRESS,     osl_Socket_E_InProgress        }, /* operation now in progress */
388     { EAGAIN,          osl_Socket_E_WouldBlock        }, /* same as EWOULDBLOCK */
389     { -1,              osl_Socket_E_InvalidError      }
390 };
391 
392 /* map */
393 /* mfe: NOT USED
394 static int osl_NativeFromSocketError(oslSocketError errorCode)
395 {
396     int i = 0;
397 
398     while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
399            (SocketError[i].error != errorCode)) i++;
400 
401     return SocketError[i].errcode;
402 }
403 */
404 
405 /* reverse map */
406 static oslSocketError osl_SocketErrorFromNative(int nativeType)
407 {
408     int i = 0;
409 
410     while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
411            (SocketError[i].errcode != nativeType)) i++;
412 
413     return SocketError[i].error;
414 }
415 
416 /* macros */
417 #define ERROR_TO_NATIVE(x)      osl_NativeFromSocketError(x)
418 #define ERROR_FROM_NATIVE(y)    osl_SocketErrorFromNative(y)
419 
420 /*****************************************************************************/
421 /* local function prototypes */
422 /*****************************************************************************/
423 
424 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
425     const sal_Char* pszDottedAddr, sal_Int32 Port);
426 
427 oslSocketAddr SAL_CALL osl_psz_createIpxSocketAddr (
428     const sal_Char NetNumber[4],
429     const sal_Char NodeNumber[6],
430     sal_uInt32 SocketNumber);
431 
432 oslHostAddr SAL_CALL osl_psz_createHostAddr (
433     const sal_Char *pszHostname, const oslSocketAddr Addr);
434 
435 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (
436     const sal_Char *pszHostname);
437 
438 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (
439     const oslHostAddr Addr);
440 
441 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
442     sal_Char *pBuffer, sal_uInt32 nBufLen);
443 
444 oslSocketAddr SAL_CALL osl_psz_resolveHostname (
445     const sal_Char* pszHostname);
446 
447 sal_Int32 SAL_CALL osl_psz_getServicePort (
448     const sal_Char* pszServicename, const sal_Char* pszProtocol);
449 
450 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr (
451     oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
452 
453 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr (
454     oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
455 
456 void SAL_CALL osl_psz_getLastSocketErrorDescription (
457     oslSocket Socket, sal_Char* pBuffer, sal_uInt32 BufferSize);
458 
459 /*****************************************************************************/
460 /* osl_create/destroy-SocketImpl */
461 /*****************************************************************************/
462 
463 #if OSL_DEBUG_LEVEL > 1
464 static sal_uInt32 g_nSocketImpl = 0;
465 static sal_uInt32 g_nSocketAddr = 0;
466 
467 /* sorry, must be implemented otherwise */
468 #if 0
469 struct LeakWarning
470 {
471     ~LeakWarning()
472     {
473         if( g_nSocketImpl )
474             OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl );
475         if( g_nSocketAddr )
476             OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr );
477     }
478 };
479 LeakWarning socketWarning;
480 #endif
481 
482 #endif /* OSL_DEBUG_LEVEL */
483 
484 
485 oslSocket __osl_createSocketImpl(int Socket)
486 {
487     oslSocket pSocket;
488 
489     pSocket = (oslSocket)calloc(1, sizeof(struct oslSocketImpl));
490 
491     pSocket->m_Socket = Socket;
492     pSocket->m_nLastError = 0;
493     pSocket->m_CloseCallback = 0;
494     pSocket->m_CallbackArg = 0;
495     pSocket->m_nRefCount = 1;
496 
497 #if defined(LINUX)
498     pSocket->m_bIsAccepting = sal_False;
499 #endif
500 
501 #if OSL_DEBUG_LEVEL > 1
502     g_nSocketImpl ++;
503 #endif
504     return pSocket;
505 }
506 
507 void __osl_destroySocketImpl(oslSocket Socket)
508 {
509     if ( Socket != NULL)
510         free((struct oslSocketImpl *) Socket);
511 #if OSL_DEBUG_LEVEL > 1
512     g_nSocketImpl --;
513 #endif
514 }
515 
516 static oslSocketAddr __osl_createSocketAddr(  )
517 {
518     oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
519 #if OSL_DEBUG_LEVEL > 1
520     g_nSocketAddr ++;
521 #endif
522     return pAddr;
523 }
524 
525 static oslSocketAddr __osl_createSocketAddrWithFamily(
526     oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
527 {
528     oslSocketAddr pAddr;
529 
530     OSL_ASSERT( family == osl_Socket_FamilyInet );
531 
532     pAddr = __osl_createSocketAddr();
533     switch( family )
534     {
535     case osl_Socket_FamilyInet:
536     {
537         struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
538 
539         pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
540         pInetAddr->sin_addr.s_addr = nAddr;
541         pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
542         break;
543     }
544     default:
545         pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
546     }
547     return pAddr;
548 }
549 
550 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
551 {
552     oslSocketAddr pAddr = __osl_createSocketAddr();
553     memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
554     return pAddr;
555 }
556 
557 static void __osl_destroySocketAddr( oslSocketAddr addr )
558 {
559 #if OSL_DEBUG_LEVEL > 1
560     g_nSocketAddr --;
561 #endif
562     rtl_freeMemory( addr );
563 }
564 
565 /*****************************************************************************/
566 /* osl_createEmptySocketAddr */
567 /*****************************************************************************/
568 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
569 {
570     oslSocketAddr pAddr = 0;
571 
572     /* is it an internet-Addr? */
573     if (Family == osl_Socket_FamilyInet)
574     {
575         pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
576     }
577     else
578     {
579         pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
580     }
581 
582     return pAddr;
583 }
584 
585 /*****************************************************************************/
586 /* osl_copySocketAddr */
587 /*****************************************************************************/
588 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
589 {
590     oslSocketAddr pCopy = 0;
591     if (Addr)
592     {
593         pCopy = __osl_createSocketAddr();
594 
595         if (pCopy)
596             memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
597     }
598     return pCopy;
599 }
600 
601 /*****************************************************************************/
602 /* osl_isEqualSocketAddr */
603 /*****************************************************************************/
604 sal_Bool SAL_CALL osl_isEqualSocketAddr (
605     oslSocketAddr Addr1,
606     oslSocketAddr Addr2)
607 {
608     struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
609     struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
610 
611     OSL_ASSERT(pAddr1);
612     OSL_ASSERT(pAddr2);
613 
614     if (pAddr1->sa_family == pAddr2->sa_family)
615     {
616         switch (pAddr1->sa_family)
617         {
618             case AF_INET:
619             {
620                 struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
621                 struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
622 
623                 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
624                     (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
625                     (pInetAddr1->sin_port == pInetAddr2->sin_port))
626                     return (sal_True);
627             }
628 
629             default:
630             {
631                 return (memcmp(pAddr1, Addr2, sizeof(struct sockaddr)) == 0);
632             }
633         }
634     }
635 
636     return (sal_False);
637 }
638 
639 /*****************************************************************************/
640 /* osl_createInetBroadcastAddr */
641 /*****************************************************************************/
642 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
643     rtl_uString *strDottedAddr,
644     sal_Int32    Port)
645 {
646     sal_uInt32    nAddr = OSL_INADDR_NONE;
647     oslSocketAddr pAddr;
648 
649     if (strDottedAddr && strDottedAddr->length)
650     {
651         /* Dotted host address for limited broadcast */
652         rtl_String *pDottedAddr = NULL;
653 
654         rtl_uString2String (
655             &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
656             RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
657 
658         nAddr = inet_addr (pDottedAddr->buffer);
659         rtl_string_release (pDottedAddr);
660     }
661 
662     if (nAddr != OSL_INADDR_NONE)
663     {
664         /* Limited broadcast */
665         nAddr = ntohl(nAddr);
666         if (IN_CLASSA(nAddr))
667         {
668             nAddr &= IN_CLASSA_NET;
669             nAddr |= IN_CLASSA_HOST;
670         }
671         else if (IN_CLASSB(nAddr))
672         {
673             nAddr &= IN_CLASSB_NET;
674             nAddr |= IN_CLASSB_HOST;
675         }
676         else if (IN_CLASSC(nAddr))
677         {
678             nAddr &= IN_CLASSC_NET;
679             nAddr |= IN_CLASSC_HOST;
680         }
681         else
682         {
683             /* No broadcast in class D */
684             return ((oslSocketAddr)NULL);
685         }
686         nAddr = htonl(nAddr);
687     }
688 
689     pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
690     return pAddr;
691 }
692 
693 /*****************************************************************************/
694 /* osl_createInetSocketAddr */
695 /*****************************************************************************/
696 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
697     rtl_uString *ustrDottedAddr,
698     sal_Int32    Port)
699 {
700     rtl_String* strDottedAddr=0;
701     oslSocketAddr Addr;
702     sal_Char* pszDottedAddr=0;
703 
704     if ( ustrDottedAddr != 0 )
705     {
706         rtl_uString2String( &strDottedAddr,
707                             rtl_uString_getStr(ustrDottedAddr),
708                             rtl_uString_getLength(ustrDottedAddr),
709                             RTL_TEXTENCODING_UTF8,
710                             OUSTRING_TO_OSTRING_CVTFLAGS);
711         pszDottedAddr = rtl_string_getStr(strDottedAddr);
712     }
713 
714 
715     Addr = osl_psz_createInetSocketAddr(pszDottedAddr, Port);
716 
717     if ( strDottedAddr != 0 )
718     {
719         rtl_string_release(strDottedAddr);
720     }
721 
722     return Addr;
723 }
724 
725 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
726     const sal_Char* pszDottedAddr,
727     sal_Int32       Port)
728 {
729     oslSocketAddr pAddr = 0;
730     sal_Int32 Addr = inet_addr(pszDottedAddr);
731     if(Addr != -1)
732     {
733         /* valid dotted addr */
734         pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
735     }
736     return pAddr;
737 }
738 
739 /*****************************************************************************/
740 /* osl_setAddrOfSocketAddr */
741 /*****************************************************************************/
742 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
743 {
744     oslSocketResult res = osl_Socket_Error;
745 
746     OSL_ASSERT( pAddr );
747     OSL_ASSERT( pByteSeq );
748 
749     if( pAddr && pByteSeq )
750     {
751         struct sockaddr_in * pSystemInetAddr;
752 
753         OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
754         OSL_ASSERT( pByteSeq->nElements == 4 );
755 
756         pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
757         memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
758         res = osl_Socket_Ok;
759     }
760     return res;
761 }
762 
763 /*****************************************************************************/
764 /* osl_getAddrOfSocketAddr */
765 /*****************************************************************************/
766 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
767 {
768     oslSocketResult res = osl_Socket_Error;
769 
770     OSL_ASSERT( pAddr );
771     OSL_ASSERT( ppByteSeq );
772 
773     if( pAddr && ppByteSeq )
774     {
775         struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
776         rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
777         res = osl_Socket_Ok;
778     }
779     return res;
780 }
781 
782 
783 /*****************************************************************************/
784 /* _osl_getFullQualifiedDomainName */
785 /*****************************************************************************/
786 
787 /** try to figure out a full-qualified hostname, by adding the current domain
788     as given by the domainname program to the given hostname.
789     This function MUST NOT call gethostbyname since pHostName allready points
790     to data returned by gethostname and would be garbled: use gethostname_r
791     instead!
792  */
793 
794 /* wrap around different interfaces to reentrant gethostbyname */
795 static struct hostent* _osl_gethostbyname_r (
796     const char *name, struct hostent *result,
797     char *buffer, int buflen, int *h_errnop)
798 {
799 
800 #ifdef LINUX
801     struct hostent *__result; /* will be the same as result */
802     int __error;
803     __error = gethostbyname_r (name, result, buffer, buflen,
804                  &__result, h_errnop);
805     return __error ? NULL : __result ;
806 #elif defined OS2
807     // YD FIXME!!!
808     return 0;
809 #else
810     return gethostbyname_r( name, result, buffer, buflen, h_errnop);
811 #endif
812 }
813 
814 static sal_Bool  _osl_getDomainName (sal_Char *buffer, sal_Int32 bufsiz)
815 {
816     sal_Bool result;
817     int      p[2];
818 
819     result = sal_False;
820 
821 #if 0 // YD 17/04/06 libc panic for fork() from thread!=1
822 
823     if (pipe (p) == 0)
824     {
825         pid_t pid;
826         int nStatus;
827 
828         pid = fork();
829         if (pid == 0)
830         {
831             char *argv[] =
832             {
833                 "/bin/domainname",
834                 NULL
835             };
836 
837             close (p[0]);
838             dup2  (p[1], 1);
839             close (p[1]);
840 
841             execv ("/bin/domainname", argv);
842             // arriving here means exec failed
843             _exit(-1);
844         }
845         else if (pid > 0)
846         {
847             sal_Int32 k = 0, n = bufsiz;
848 
849             close (p[1]);
850             if ((k = read (p[0], buffer, n - 1)) > 0)
851             {
852                 buffer[k] = 0;
853                 if (buffer[k - 1] == '\n')
854                     buffer[k - 1] = 0;
855                 result = sal_True;
856             }
857             close (p[0]);
858             waitpid (pid, &nStatus, 0);
859         }
860         else
861         {
862             close (p[0]);
863             close (p[1]);
864         }
865     }
866 #endif // 0
867 
868     return (result);
869 }
870 
871 static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
872 {
873 #   define DOMAINNAME_LENGTH 512
874     sal_uInt32          nLengthOfHostName;
875     static sal_uInt32   nLengthOfDomainName = 0;
876     static sal_Char    *pDomainName = NULL;
877 
878     sal_Char  *pFullQualifiedName;
879 #if 0  /* OBSOLETE */
880     FILE      *pPipeToDomainnameExe;
881 #endif /* OBSOLETE */
882 
883     /* get a '\0' terminated domainname */
884 
885     /* read default domainname default from environment */
886     if (nLengthOfDomainName == 0)
887     {
888         sal_Char *pEnvDomain;
889 
890         pEnvDomain = getenv ("STAR_OVERRIDE_DOMAINNAME");
891         if (pEnvDomain)
892         {
893             pDomainName = strdup (pEnvDomain);
894             nLengthOfDomainName = strlen (pDomainName);
895         }
896     }
897 
898 #if 1  /* NEW */
899     if (nLengthOfDomainName == 0)
900     {
901         sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
902 
903         pDomainNameBuffer[0] = '\0';
904 
905         if (_osl_getDomainName (pDomainNameBuffer, DOMAINNAME_LENGTH))
906         {
907             pDomainName = strdup (pDomainNameBuffer);
908             nLengthOfDomainName = strlen (pDomainName);
909         }
910     }
911 
912 #endif /* NEW */
913 #if 0  /* OBSOLETE */
914 #ifdef SCO
915 
916     /* call 'domainname > /usr/tmp/some-tmp-file', since
917        popen read pclose do block or core-dump,
918        (even the pipe-stuff that comes with pthreads) */
919     if (nLengthOfDomainName == 0)
920     {
921         sal_Char  tmp_name[ L_tmpnam ];
922         FILE     *tmp_file;
923         sal_Char  domain_call [ L_tmpnam + 16 ] = "domainname > ";
924 
925         tmp_name[0] = '\0';
926 
927         tmpnam ( tmp_name );
928         strcat ( domain_call, tmp_name );
929         if (   (system ( domain_call ) == 0)
930             && ((tmp_file = fopen( tmp_name, "r" )) != NULL ) )
931         {
932             sal_Char  pDomainNameBuffer[ DOMAINNAME_LENGTH ];
933 
934             pDomainNameBuffer[0] = '\0';
935 
936             if ( fgets ( pDomainNameBuffer, DOMAINNAME_LENGTH, tmp_file ) )
937             {
938                 pDomainName = strdup( pDomainNameBuffer );
939                 nLengthOfDomainName = strlen( pDomainName );
940                 if (   ( nLengthOfDomainName > 0 )
941                     && ( pDomainName[ nLengthOfDomainName - 1] == '\n' ) )
942                     pDomainName[ --nLengthOfDomainName ] = '\0';
943             }
944             fclose ( tmp_file );
945         }
946         unlink( tmp_name );
947     }
948 
949 #else /* !SCO */
950 
951     /* read the domainname from pipe to the program domainname */
952     if (   (nLengthOfDomainName == 0)
953         && (pPipeToDomainnameExe = popen( "domainname", "r")) )
954     {
955         sal_Char  c;
956         sal_Char  pDomainNameBuffer[ DOMAINNAME_LENGTH ];
957         sal_Char *pDomainNamePointer;
958 
959         pDomainNameBuffer[0] = '\0';
960 
961         pDomainNamePointer = pDomainNameBuffer;
962         while (    ((c = getc( pPipeToDomainnameExe )) != EOF)
963                 && (nLengthOfDomainName < (DOMAINNAME_LENGTH - 1)) )
964         {
965             if (! isspace(c))
966             {
967                  nLengthOfDomainName++ ;
968                 *pDomainNamePointer++ = (sal_Char)c;
969             }
970         }
971         *pDomainNamePointer = '\0';
972         pDomainName = strdup( pDomainNameBuffer );
973 
974         pclose( pPipeToDomainnameExe );
975     }
976 
977 #endif /* !SCO */
978 #endif /* OBSOLETE */
979 
980     /* compose hostname and domainname */
981     nLengthOfHostName = strlen( pHostName );
982     pFullQualifiedName = (sal_Char*) malloc( (nLengthOfHostName + 1
983                             + nLengthOfDomainName + 1) * sizeof(sal_Char) );
984     memcpy( pFullQualifiedName, pHostName,
985         (nLengthOfHostName + 1) * sizeof(sal_Char) );
986 
987     if ( nLengthOfDomainName > 0 )
988     {
989         /* fqdn = hostname + '.' + domainname + '\0' */
990         pFullQualifiedName[ nLengthOfHostName ] = '.';
991         memcpy( pFullQualifiedName + nLengthOfHostName + 1, pDomainName,
992             nLengthOfDomainName + 1 );
993     }
994 
995     /* check whether full-qualified name and hostname point to the same host
996      * should almost always be true */
997     if ( nLengthOfDomainName > 0 )
998     {
999         struct hostent *pQualifiedHostByName;
1000         struct hostent *pHostByName;
1001         sal_Bool        bHostsAreEqual;
1002 
1003         /* buffer for calls to reentrant version of gethostbyname */
1004         struct hostent  aHostByName, aQualifiedHostByName;
1005         sal_Char        pHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1006         sal_Char        pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1007         int     nErrorNo;
1008 
1009         pHostBuffer[0] = '\0';
1010         pQualifiedHostBuffer[0] = '\0';
1011 
1012         /* get list of addresses */
1013         pQualifiedHostByName = _osl_gethostbyname_r (
1014             pFullQualifiedName,
1015             &aQualifiedHostByName, pQualifiedHostBuffer,
1016             sizeof(pQualifiedHostBuffer), &nErrorNo );
1017         pHostByName = _osl_gethostbyname_r (
1018             pHostName,
1019             &aHostByName, pHostBuffer,
1020             sizeof(pHostBuffer), &nErrorNo );
1021 
1022         /* compare addresses */
1023         bHostsAreEqual = sal_False;
1024         if ( pQualifiedHostByName && pHostByName )
1025         {
1026             sal_Char **p, **q;
1027             struct in_addr in;
1028 
1029             /* lists are expected to be (very) short */
1030             for ( p = pQualifiedHostByName->h_addr_list; *p != NULL; p++ )
1031             {
1032                 for ( q = pHostByName->h_addr_list; *q != NULL; q++ )
1033                 {
1034                     /* in.s_addr may be in_addr_t or uint32_t or heaven knows */
1035                     if ( memcmp( *p, *q, sizeof(in.s_addr) ) == 0 )
1036                     {
1037                         bHostsAreEqual = sal_True;
1038                         break;
1039                     }
1040                 }
1041                 if ( bHostsAreEqual )
1042                     break;
1043             }
1044         }
1045 
1046         /* very strange case, but have to believe it: reduce the
1047          * full qualified name to the unqualified host name */
1048         if ( !bHostsAreEqual )
1049         {
1050             OSL_TRACE("_osl_getFullQualifiedDomainName: "
1051                       "suspect FQDN: %s\n", pFullQualifiedName);
1052 
1053             pFullQualifiedName[ nLengthOfHostName ] = '\0';
1054             pFullQualifiedName = (sal_Char*)realloc ( pFullQualifiedName,
1055                                 (nLengthOfHostName + 1) * sizeof( sal_Char ));
1056         }
1057     }
1058 
1059     /* always return a hostname looked up as carefully as possible
1060      * this string must be freed by the caller */
1061     return pFullQualifiedName;
1062 }
1063 
1064 /*****************************************************************************/
1065 /* _osl_isFullQualifiedDomainName */
1066 /*****************************************************************************/
1067 static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
1068 {
1069     /* a FQDN (aka 'hostname.domain.top_level_domain' )
1070      * is a name which contains a dot '.' in it ( would
1071      * match as well for 'hostname.' but is good enough
1072      * for now )*/
1073     return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
1074 }
1075 
1076 /*****************************************************************************/
1077 /* oslHostAddr */
1078 /*****************************************************************************/
1079 struct oslHostAddrImpl
1080 {
1081     sal_Char        *pHostName;
1082     oslSocketAddr   pSockAddr;
1083 };
1084 
1085 static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
1086 {
1087     oslHostAddr pAddr= NULL;
1088     oslSocketAddr pSockAddr = 0;
1089 
1090 
1091     if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
1092         return ((oslHostAddr)NULL);
1093 
1094     //YD 18/06/2006 win32 does this with unicode, see socket.cxx
1095     sal_Char        *cn;
1096     cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1097     OSL_ASSERT(cn);
1098     if (cn == NULL)
1099         return ((oslHostAddr)NULL);
1100 
1101     strcpy(cn, he->h_name);
1102 
1103 #if 0 // YD 17/04/06 win32 doesn't it.
1104     if (_osl_isFullQualifiedDomainName(he->h_name))
1105     {
1106         cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1107         OSL_ASSERT(cn);
1108         if (cn == NULL)
1109             return ((oslHostAddr)NULL);
1110 
1111         strcpy(cn, he->h_name);
1112     }
1113     else
1114     {
1115         cn =_osl_getFullQualifiedDomainName (he->h_name);
1116         OSL_ASSERT(cn);
1117         if (cn == NULL)
1118             return ((oslHostAddr)NULL);
1119     }
1120 #endif
1121 
1122     pSockAddr = __osl_createSocketAddr();
1123     OSL_ASSERT(pSockAddr);
1124     if (pSockAddr == NULL)
1125     {
1126         free(cn);
1127         return ((oslHostAddr)NULL);
1128     }
1129 
1130     pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
1131     if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1132     {
1133         struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
1134         memcpy (
1135             &(sin->sin_addr.s_addr),
1136             he->h_addr_list[0],
1137             he->h_length);
1138     }
1139     else
1140     {
1141         /* unknown address family */
1142         /* future extensions for new families might be implemented here */
1143 
1144         OSL_TRACE("_osl_hostentToHostAddr: unknown address family.\n");
1145         OSL_ASSERT(sal_False);
1146 
1147         __osl_destroySocketAddr( pSockAddr );
1148         free (cn);
1149         return ((oslHostAddr)NULL);
1150     }
1151 
1152     pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1153     OSL_ASSERT(pAddr);
1154     if (pAddr == NULL)
1155     {
1156         __osl_destroySocketAddr( pSockAddr );
1157         free (cn);
1158         return ((oslHostAddr)NULL);
1159     }
1160 
1161     pAddr->pHostName= cn;
1162     pAddr->pSockAddr= pSockAddr;
1163 
1164     return pAddr;
1165 }
1166 
1167 /*****************************************************************************/
1168 /* osl_createHostAddr */
1169 /*****************************************************************************/
1170 oslHostAddr SAL_CALL osl_createHostAddr (
1171     rtl_uString        *ustrHostname,
1172     const oslSocketAddr Addr)
1173 {
1174     oslHostAddr HostAddr;
1175     rtl_String* strHostname=0;
1176     sal_Char* pszHostName=0;
1177 
1178     if ( ustrHostname != 0 )
1179     {
1180         rtl_uString2String( &strHostname,
1181                             rtl_uString_getStr(ustrHostname),
1182                             rtl_uString_getLength(ustrHostname),
1183                             RTL_TEXTENCODING_UTF8,
1184                             OUSTRING_TO_OSTRING_CVTFLAGS );
1185         pszHostName = rtl_string_getStr(strHostname);
1186     }
1187 
1188     HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
1189 
1190     if ( strHostname != 0 )
1191     {
1192         rtl_string_release(strHostname);
1193     }
1194 
1195 
1196     return HostAddr;
1197 }
1198 
1199 oslHostAddr SAL_CALL osl_psz_createHostAddr (
1200     const sal_Char     *pszHostname,
1201     const oslSocketAddr pAddr)
1202 {
1203     oslHostAddr pHostAddr;
1204     sal_Char            *cn;
1205 
1206     OSL_ASSERT(pszHostname && pAddr);
1207     if ((pszHostname == NULL) || (pAddr == NULL))
1208         return ((oslHostAddr)NULL);
1209 
1210     cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
1211     OSL_ASSERT(cn);
1212     if (cn == NULL)
1213         return ((oslHostAddr)NULL);
1214 
1215     strcpy (cn, pszHostname);
1216 
1217     pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1218     OSL_ASSERT(pHostAddr);
1219     if (pAddr == NULL)
1220     {
1221         free (cn);
1222         return ((oslHostAddr)NULL);
1223     }
1224 
1225     pHostAddr->pHostName= cn;
1226     pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
1227 
1228     return pHostAddr;
1229 }
1230 
1231 /*****************************************************************************/
1232 /* osl_createHostAddrByName */
1233 /*****************************************************************************/
1234 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
1235 {
1236     oslHostAddr HostAddr;
1237     rtl_String* strHostname=0;
1238     sal_Char* pszHostName=0;
1239 
1240     if ( ustrHostname != 0 )
1241     {
1242         rtl_uString2String( &strHostname,
1243                             rtl_uString_getStr(ustrHostname),
1244                             rtl_uString_getLength(ustrHostname),
1245                             RTL_TEXTENCODING_UTF8,
1246                             OUSTRING_TO_OSTRING_CVTFLAGS );
1247         pszHostName=rtl_string_getStr(strHostname);
1248     }
1249 
1250     HostAddr = osl_psz_createHostAddrByName(pszHostName);
1251 
1252     if ( strHostname != 0 )
1253     {
1254         rtl_string_release(strHostname);
1255     }
1256 
1257     return HostAddr;
1258 }
1259 
1260 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
1261 {
1262     struct hostent *he;
1263         oslHostAddr addr;
1264 
1265     static oslMutex mutex = NULL;
1266 
1267     if (mutex == NULL)
1268         mutex = osl_createMutex();
1269 
1270     osl_acquireMutex(mutex);
1271 
1272     he = gethostbyname((sal_Char *)pszHostname);
1273     addr = _osl_hostentToHostAddr (he);
1274 
1275     osl_releaseMutex(mutex);
1276 
1277     return addr;
1278 }
1279 
1280 /*****************************************************************************/
1281 /* osl_createHostAddrByAddr */
1282 /*****************************************************************************/
1283 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
1284 {
1285     OSL_ASSERT(pAddr);
1286 
1287     if (pAddr == NULL)
1288         return ((oslHostAddr)NULL);
1289 
1290     if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1291     {
1292         const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
1293         struct hostent *he;
1294 
1295         if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
1296             return ((oslHostAddr)NULL);
1297 
1298         he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
1299                           sizeof (sin->sin_addr),
1300                           sin->sin_family);
1301         return _osl_hostentToHostAddr (he);
1302     }
1303 
1304     return ((oslHostAddr)NULL);
1305 }
1306 
1307 /*****************************************************************************/
1308 /* osl_copyHostAddr */
1309 /*****************************************************************************/
1310 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
1311 {
1312     OSL_ASSERT(pAddr);
1313 
1314     if (pAddr)
1315         return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
1316     else
1317         return ((oslHostAddr)NULL);
1318 }
1319 
1320 /*****************************************************************************/
1321 /* osl_getHostnameOfHostAddr */
1322 /*****************************************************************************/
1323 void SAL_CALL osl_getHostnameOfHostAddr (
1324     const oslHostAddr   Addr,
1325     rtl_uString       **ustrHostname)
1326 {
1327     const sal_Char* pHostname=0;
1328 
1329     pHostname = osl_psz_getHostnameOfHostAddr(Addr);
1330 
1331     rtl_uString_newFromAscii (ustrHostname, pHostname);
1332 
1333     return;
1334 }
1335 
1336 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1337 {
1338     OSL_ASSERT(pAddr);
1339 
1340     if (pAddr)
1341         return pAddr->pHostName;
1342     else
1343         return NULL;
1344 }
1345 
1346 /*****************************************************************************/
1347 /* osl_getSocketAddrOfHostAddr */
1348 /*****************************************************************************/
1349 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1350 {
1351     OSL_ASSERT(pAddr);
1352 
1353     if (pAddr)
1354         return ((oslSocketAddr)(pAddr->pSockAddr));
1355     else
1356         return NULL;
1357 }
1358 
1359 /*****************************************************************************/
1360 /* osl_destroyHostAddr */
1361 /*****************************************************************************/
1362 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1363 {
1364     if (pAddr)
1365     {
1366         if (pAddr->pHostName)
1367             free (pAddr->pHostName);
1368         if (pAddr->pSockAddr)
1369             osl_destroySocketAddr (pAddr->pSockAddr);
1370         free (pAddr);
1371     }
1372 }
1373 
1374 /*****************************************************************************/
1375 /* osl_getLocalHostname */
1376 /*****************************************************************************/
1377 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1378 {
1379     oslSocketResult Result;
1380     sal_Char pszHostname[1024];
1381 
1382     pszHostname[0] = '\0';
1383 
1384     Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1385 
1386     rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1387 
1388     return Result;
1389 }
1390 
1391 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1392     sal_Char *pBuffer, sal_uInt32 nBufLen)
1393 {
1394     static sal_Char LocalHostname[256] = "";
1395 
1396     if (strlen(LocalHostname) == 0)
1397     {
1398         const sal_Char *pStr;
1399 
1400 #ifdef SYSV
1401         struct utsname uts;
1402 
1403         if (uname(&uts) < 0)
1404             return osl_Socket_Error;
1405 
1406         if ((strlen(uts.nodename) + 1) > nBufLen)
1407             return osl_Socket_Error;
1408 
1409         strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1410 #else  /* BSD compatible */
1411 
1412         if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1413             return osl_Socket_Error;
1414         LocalHostname[sizeof(LocalHostname)-1] = 0;
1415 #endif /* SYSV */
1416 
1417         /* check if we have an FQDN */
1418         if (strchr(LocalHostname, '.') == NULL)
1419         {
1420             oslHostAddr Addr;
1421 
1422             /* no, determine it via dns */
1423             Addr = osl_psz_createHostAddrByName(LocalHostname);
1424 
1425             if (Addr && (pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1426             {
1427 #if 0  /* OBSOLETE */
1428                 sal_Char* pChr;
1429 #endif /* OBSOLETE */
1430                 strcpy(LocalHostname, pStr);
1431 
1432 #if 0  /* OBSOLETE */
1433                 /* already done by _osl_getFullQualifiedDomainName() with
1434                    much better heuristics, so this may be contraproductive */
1435 
1436                 /* no FQDN, last try append domain name */
1437                 if ((pChr = strchr(LocalHostname, '.')) == NULL)
1438                 {
1439                     FILE *fp;
1440 
1441                     pChr = &LocalHostname[strlen(LocalHostname)];
1442 
1443                     if ( (fp = popen("domainname", "r")) != 0 )
1444                     {
1445                         int c;
1446 
1447                         *pChr++ = '.';
1448 
1449                         while ((c = getc(fp)) != EOF)
1450                         {
1451                             if (! isspace(c))
1452                                 *pChr++ = (sal_Char)c;
1453                         }
1454 
1455                         *pChr = '\0';
1456 
1457                         fclose(fp);
1458                     }
1459                     else
1460                         LocalHostname[0] = '\0';
1461                 }
1462 #endif /* OBSOLETE */
1463 
1464             }
1465             if (Addr)
1466                 osl_destroyHostAddr(Addr);
1467         }
1468     }
1469 
1470     if (strlen(LocalHostname) > 0)
1471     {
1472         strncpy(pBuffer, LocalHostname, nBufLen);
1473         pBuffer[nBufLen - 1] = '\0';
1474 
1475         return osl_Socket_Ok;
1476     }
1477 
1478     return osl_Socket_Error;
1479 }
1480 
1481 /*****************************************************************************/
1482 /* osl_resolveHostname */
1483 /*****************************************************************************/
1484 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1485 {
1486     oslSocketAddr Addr;
1487     rtl_String* strHostname=0;
1488     sal_Char* pszHostName=0;
1489 
1490     if ( ustrHostname != 0 )
1491     {
1492         rtl_uString2String( &strHostname,
1493                             rtl_uString_getStr(ustrHostname),
1494                             rtl_uString_getLength(ustrHostname),
1495                             RTL_TEXTENCODING_UTF8,
1496                             OUSTRING_TO_OSTRING_CVTFLAGS );
1497         pszHostName = rtl_string_getStr(strHostname);
1498     }
1499 
1500 
1501     Addr = osl_psz_resolveHostname(pszHostName);
1502 
1503     if ( strHostname != 0 )
1504     {
1505         rtl_string_release(strHostname);
1506     }
1507 
1508 
1509     return Addr;
1510 }
1511 
1512 
1513 oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1514 {
1515     struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1516 
1517     if (pAddr)
1518     {
1519         oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1520 
1521         osl_destroyHostAddr(pAddr);
1522 
1523         return (SockAddr);
1524     }
1525 
1526     return ((oslSocketAddr)NULL);
1527 }
1528 
1529 /*****************************************************************************/
1530 /* osl_getServicePort */
1531 /*****************************************************************************/
1532 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1533 {
1534     sal_Int32 nPort;
1535     rtl_String* strServicename=0;
1536     rtl_String* strProtocol=0;
1537     sal_Char* pszServiceName=0;
1538     sal_Char* pszProtocol=0;
1539 
1540     if ( ustrServicename != 0 )
1541     {
1542         rtl_uString2String( &strServicename,
1543                             rtl_uString_getStr(ustrServicename),
1544                             rtl_uString_getLength(ustrServicename),
1545                             RTL_TEXTENCODING_UTF8,
1546                             OUSTRING_TO_OSTRING_CVTFLAGS );
1547         pszServiceName = rtl_string_getStr(strServicename);
1548     }
1549 
1550     if ( ustrProtocol != 0 )
1551     {
1552         rtl_uString2String( &strProtocol,
1553                             rtl_uString_getStr(ustrProtocol),
1554                             rtl_uString_getLength(ustrProtocol),
1555                             RTL_TEXTENCODING_UTF8,
1556                             OUSTRING_TO_OSTRING_CVTFLAGS );
1557         pszProtocol = rtl_string_getStr(strProtocol);
1558     }
1559 
1560     nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1561 
1562     if ( strServicename != 0 )
1563     {
1564         rtl_string_release(strServicename);
1565     }
1566 
1567     if ( strProtocol != 0 )
1568     {
1569         rtl_string_release(strProtocol);
1570     }
1571 
1572 
1573     return nPort;
1574 }
1575 
1576 
1577 sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1578                         const sal_Char* pszProtocol)
1579 {
1580     struct servent* ps;
1581 
1582     ps= getservbyname(pszServicename, pszProtocol);
1583 
1584     if (ps != 0)
1585         return ntohs(ps->s_port);
1586 
1587     return OSL_INVALID_PORT;
1588 }
1589 
1590 /*****************************************************************************/
1591 /* osl_destroySocketAddr */
1592 /*****************************************************************************/
1593 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1594 {
1595     __osl_destroySocketAddr( pAddr );
1596 }
1597 
1598 /*****************************************************************************/
1599 /* osl_getFamilyOfSocketAddr */
1600 /*****************************************************************************/
1601 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1602 {
1603     OSL_ASSERT(pAddr);
1604 
1605     if (pAddr)
1606         return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1607     else
1608         return osl_Socket_FamilyInvalid;
1609 }
1610 
1611 /*****************************************************************************/
1612 /* osl_getInetPortOfSocketAddr */
1613 /*****************************************************************************/
1614 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1615 {
1616     OSL_ASSERT(pAddr);
1617     if( pAddr )
1618     {
1619         struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1620 
1621         if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1622             return ntohs(pSystemInetAddr->sin_port);
1623     }
1624     return OSL_INVALID_PORT;
1625 }
1626 
1627 /*****************************************************************************/
1628 /* osl_setInetPortOfSocketAddr */
1629 /*****************************************************************************/
1630 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1631 {
1632     OSL_ASSERT(pAddr);
1633     if( pAddr )
1634     {
1635         struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1636         if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1637         {
1638             pSystemInetAddr->sin_port= htons((short)Port);
1639             return sal_True;
1640         }
1641     }
1642 
1643     /* this is not a inet-addr => can't set port */
1644     return sal_False;
1645 }
1646 
1647 /*****************************************************************************/
1648 /* osl_getHostnameOfSocketAddr */
1649 /*****************************************************************************/
1650 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1651 {
1652     oslSocketResult Result;
1653     sal_Char pszHostname[1024];
1654 
1655     pszHostname[0] = '\0';
1656 
1657     Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1658 
1659     rtl_uString_newFromAscii(ustrHostname,pszHostname);
1660 
1661     return Result;
1662 }
1663 
1664 
1665 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1666                                             sal_Char *pBuffer, sal_uInt32 BufferSize)
1667 {
1668     oslHostAddr pHostAddr= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1669 
1670     if (pHostAddr)
1671     {
1672         strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1673 
1674         pBuffer[BufferSize - 1] = '\0';
1675 
1676         osl_destroyHostAddr(pHostAddr);
1677 
1678         return osl_Socket_Ok;
1679     }
1680 
1681     return osl_Socket_Error;
1682 }
1683 
1684 /*****************************************************************************/
1685 /* osl_getDottedInetAddrOfSocketAddr */
1686 /*****************************************************************************/
1687 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1688 {
1689     oslSocketResult Result;
1690     sal_Char pszDottedInetAddr[1024];
1691 
1692     pszDottedInetAddr[0] = '\0';
1693 
1694     Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1695 
1696     rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1697 
1698     return Result;
1699 
1700 }
1701 
1702 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1703                                                   sal_Char *pBuffer, sal_uInt32 BufferSize)
1704 {
1705     OSL_ASSERT(pAddr);
1706 
1707     if( pAddr )
1708     {
1709         struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1710 
1711         if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1712         {
1713             strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1714             pBuffer[BufferSize - 1] = '\0';
1715 
1716             return osl_Socket_Ok;
1717         }
1718     }
1719 
1720     return osl_Socket_Error;
1721 }
1722 
1723 #if 0  /* OBSOLETE */
1724 /*****************************************************************************/
1725 /* osl_getIpxNetNumber  */
1726 /*****************************************************************************/
1727 oslSocketResult SAL_CALL osl_getIpxNetNumber(oslSocketAddr Addr,
1728                                     oslSocketIpxNetNumber NetNumber)
1729 
1730 {
1731     struct sockaddr_ipx* pAddr;
1732 
1733     pAddr= (struct sockaddr_ipx*)Addr;
1734 
1735     OSL_ASSERT(pAddr);
1736 
1737     if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1738     {
1739         memcpy(NetNumber, pAddr->sa_netnum, sizeof(NetNumber));
1740 
1741         return osl_Socket_Ok;
1742     }
1743     else
1744         return osl_Socket_Error;
1745 }
1746 
1747 
1748 /*****************************************************************************/
1749 /* osl_getIpxNodeNumber  */
1750 /*****************************************************************************/
1751 oslSocketResult SAL_CALL osl_getIpxNodeNumber(oslSocketAddr Addr,
1752                                      oslSocketIpxNodeNumber NodeNumber)
1753 
1754 {
1755     struct sockaddr_ipx* pAddr;
1756 
1757     pAddr= (struct sockaddr_ipx*)Addr;
1758 
1759     OSL_ASSERT(pAddr);
1760 
1761     if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1762     {
1763         memcpy(NodeNumber, pAddr->sa_nodenum, sizeof(NodeNumber));
1764 
1765         return osl_Socket_Ok;
1766     }
1767     else
1768         return osl_Socket_Error;
1769 }
1770 
1771 
1772 /*****************************************************************************/
1773 /* osl_getIpxSocketNumber  */
1774 /*****************************************************************************/
1775 sal_Int32 SAL_CALL osl_getIpxSocketNumber(oslSocketAddr Addr)
1776 {
1777     struct sockaddr_ipx* pAddr= (struct sockaddr_ipx*)Addr;
1778     OSL_ASSERT(pAddr);
1779 
1780     if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1781         return pAddr->sa_socket;
1782     else
1783         return OSL_INVALID_IPX_SOCKET_NO;
1784 }
1785 
1786 #endif /* OBSOLETE */
1787 
1788 /*****************************************************************************/
1789 /* osl_createSocket  */
1790 /*****************************************************************************/
1791 oslSocket SAL_CALL osl_createSocket(oslAddrFamily   Family,
1792                            oslSocketType    Type,
1793                            oslProtocol      Protocol)
1794 {
1795     int            Flags;
1796     oslSocket pSocket;
1797 
1798     /* alloc memory */
1799     pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1800 
1801     /* create socket */
1802     pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1803                                 TYPE_TO_NATIVE(Type),
1804                                 PROTOCOL_TO_NATIVE(Protocol));
1805 
1806     /* creation failed => free memory */
1807     if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1808     {
1809         OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1810                   errno,
1811                   strerror(errno));
1812 
1813         __osl_destroySocketImpl((pSocket));
1814         pSocket= 0;
1815     }
1816     else
1817     {
1818         /* set close-on-exec flag */
1819         if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1820         {
1821             Flags |= FD_CLOEXEC;
1822             if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1823             {
1824                 pSocket->m_nLastError=errno;
1825                 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1826                           errno,
1827                           strerror(errno));
1828             }
1829         }
1830         else
1831         {
1832             pSocket->m_nLastError=errno;
1833         }
1834 
1835 
1836         pSocket->m_CloseCallback    = NULL;
1837         pSocket->m_CallbackArg  = NULL;
1838     }
1839 
1840     return pSocket;
1841 }
1842 
1843 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1844 {
1845     osl_incrementInterlockedCount( &(pSocket->m_nRefCount ) );
1846 }
1847 
1848 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1849 {
1850     if( pSocket && 0 == osl_decrementInterlockedCount( &(pSocket->m_nRefCount) ) )
1851     {
1852 #if defined(LINUX)
1853     if ( pSocket->m_bIsAccepting == sal_True )
1854     {
1855         OSL_ENSURE(0, "osl_destroySocket : attempt to destroy socket while accepting\n");
1856         return;
1857     }
1858 #endif /* LINUX */
1859         osl_closeSocket( pSocket );
1860         __osl_destroySocketImpl( pSocket );
1861     }
1862 }
1863 
1864 
1865 
1866 /*****************************************************************************/
1867 /* osl_closeSocket  */
1868 /*****************************************************************************/
1869 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1870 {
1871     int nRet;
1872     int nFD;
1873 
1874     /* socket already invalid */
1875     if(pSocket==0)
1876         return;
1877 
1878     pSocket->m_nLastError=0;
1879     nFD = pSocket->m_Socket;
1880 
1881     pSocket->m_Socket = OSL_INVALID_SOCKET;
1882 
1883 #if defined(LINUX)
1884     pSocket->m_bIsInShutdown = sal_True;
1885 
1886     if ( pSocket->m_bIsAccepting == sal_True )
1887     {
1888         int nConnFD;
1889         struct sockaddr aSockAddr;
1890         socklen_t nSockLen = sizeof(aSockAddr);
1891 
1892         nRet = getsockname(nFD, &aSockAddr, &nSockLen);
1893 #if OSL_DEBUG_LEVEL > 1
1894         if ( nRet < 0 )
1895         {
1896             perror("getsockname");
1897         }
1898 #endif /* OSL_DEBUG_LEVEL */
1899 
1900         if ( aSockAddr.sa_family == AF_INET )
1901         {
1902             struct sockaddr_in* pSockAddrIn = (struct sockaddr_in*) &aSockAddr;
1903 
1904             if ( pSockAddrIn->sin_addr.s_addr == htonl(INADDR_ANY) )
1905             {
1906                 pSockAddrIn->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1907             }
1908 
1909             nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1910 #if OSL_DEBUG_LEVEL > 1
1911             if ( nConnFD < 0 )
1912             {
1913                 perror("socket");
1914             }
1915 #endif /* OSL_DEBUG_LEVEL */
1916 
1917             nRet = connect(nConnFD, &aSockAddr, sizeof(aSockAddr));
1918 #if OSL_DEBUG_LEVEL > 1
1919             if ( nRet < 0 )
1920             {
1921                 perror("connect");
1922             }
1923 #endif /* OSL_DEBUG_LEVEL */
1924             close(nConnFD);
1925         }
1926     }
1927 #endif /* LINUX */
1928 
1929     /* registrierten Callback ausfuehren */
1930     if (pSocket->m_CloseCallback != NULL)
1931     {
1932         pSocket->m_CloseCallback(pSocket->m_CallbackArg);
1933     }
1934 
1935     nRet=close(nFD);
1936     if ( nRet != 0 )
1937     {
1938         pSocket->m_nLastError=errno;
1939         OSL_TRACE("closeSocket close error '%s'\n",strerror(errno));
1940     }
1941 
1942     pSocket->m_Socket = OSL_INVALID_SOCKET;
1943 }
1944 
1945 /*****************************************************************************/
1946 /* osl_getLocalAddrOfSocket  */
1947 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1948 /* are the same! I don't like it very much but see no other easy way to conceal */
1949 /* the struct sockaddr from the eyes of the user. */
1950 /*****************************************************************************/
1951 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1952 {
1953 #if defined(LINUX) || defined(FREEBSD)
1954     socklen_t AddrLen;
1955 #else
1956     /* mfe: Solaris 'cc +w' means Addrlen should be signed! */
1957     /*      it's really defined as 'int*' in /usr/include/sys/socket.h! */
1958     /*      the man page says it expects a 'size_t' */
1959     int AddrLen;
1960 #endif
1961     struct sockaddr Addr;
1962     oslSocketAddr  pAddr;
1963 
1964     if (pSocket == NULL) /* ENOTSOCK */
1965         return ((oslSocketAddr)NULL);
1966 
1967     AddrLen= sizeof(struct sockaddr);
1968 
1969     if (getsockname(pSocket->m_Socket, &Addr, PTR_SIZE_T(AddrLen)) == OSL_SOCKET_ERROR)
1970         return ((oslSocketAddr)NULL);
1971 
1972     pAddr = __osl_createSocketAddrFromSystem( &Addr );
1973     return pAddr;
1974 }
1975 
1976 /*****************************************************************************/
1977 /* osl_getPeerAddrOfSocket  */
1978 /*****************************************************************************/
1979 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1980 {
1981     sal_uInt32 AddrLen;
1982     struct sockaddr Addr;
1983 
1984     OSL_ASSERT(pSocket);
1985     if ( pSocket == 0 )
1986     {
1987         return 0;
1988     }
1989 
1990     pSocket->m_nLastError=0;
1991     AddrLen= sizeof(struct sockaddr);
1992 
1993     if(getpeername(pSocket->m_Socket, &Addr, (int*)PTR_SIZE_T(AddrLen)) == OSL_SOCKET_ERROR)
1994     {
1995         pSocket->m_nLastError=errno;
1996         return 0;
1997     }
1998     return __osl_createSocketAddrFromSystem( &Addr );
1999 }
2000 
2001 /*****************************************************************************/
2002 /* osl_bindAddrToSocket  */
2003 /*****************************************************************************/
2004 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
2005                              oslSocketAddr pAddr)
2006 {
2007     int nRet;
2008 
2009     OSL_ASSERT(pSocket && pAddr );
2010     if ( pSocket == 0 || pAddr == 0 )
2011     {
2012         return sal_False;
2013     }
2014 
2015     pSocket->m_nLastError=0;
2016 
2017     nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
2018 
2019     if ( nRet == OSL_SOCKET_ERROR)
2020     {
2021         pSocket->m_nLastError=errno;
2022         return sal_False;
2023     }
2024 
2025     return sal_True;
2026 }
2027 
2028 
2029 /*****************************************************************************/
2030 /* osl_listenOnSocket  */
2031 /*****************************************************************************/
2032 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
2033                            sal_Int32 MaxPendingConnections)
2034 {
2035     int nRet;
2036 
2037     OSL_ASSERT(pSocket);
2038     if ( pSocket == 0 )
2039     {
2040         return sal_False;
2041     }
2042 
2043     pSocket->m_nLastError=0;
2044 
2045     nRet = listen(pSocket->m_Socket,
2046                   MaxPendingConnections == -1 ?
2047                   SOMAXCONN :
2048                   MaxPendingConnections);
2049     if ( nRet == OSL_SOCKET_ERROR)
2050     {
2051         pSocket->m_nLastError=errno;
2052         return sal_False;
2053     }
2054 
2055     return sal_True;
2056 }
2057 
2058 
2059 /*****************************************************************************/
2060 /* osl_connectSocketTo  */
2061 /*****************************************************************************/
2062 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
2063                                     oslSocketAddr pAddr,
2064                                     const TimeValue* pTimeout)
2065 {
2066     fd_set   WriteSet;
2067     fd_set   ExcptSet;
2068     int      ReadyHandles;
2069     struct timeval  tv;
2070     oslSocketResult Result= osl_Socket_Ok;
2071 
2072     OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
2073 
2074     if ( pSocket == 0 )
2075     {
2076         return osl_Socket_Error;
2077     }
2078 
2079     pSocket->m_nLastError=0;
2080 
2081     if (osl_isNonBlockingMode(pSocket))
2082     {
2083         if (connect(pSocket->m_Socket,
2084                     &(pAddr->m_sockaddr),
2085                     sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2086             return osl_Socket_Ok;
2087         else
2088             if (errno == EWOULDBLOCK || errno == EINPROGRESS)
2089             {
2090                 pSocket->m_nLastError=EINPROGRESS;
2091                 return osl_Socket_InProgress;
2092             }
2093 
2094 
2095         pSocket->m_nLastError=errno;
2096         OSL_TRACE("can't connect : '%s'",strerror(errno));
2097         return osl_Socket_Error;
2098     }
2099 
2100     /* set socket temporarily to non-blocking */
2101     OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
2102 
2103     /* initiate connect */
2104     if(connect(pSocket->m_Socket,
2105                &(pAddr->m_sockaddr),
2106                sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2107     {
2108        /* immediate connection */
2109         osl_enableNonBlockingMode(pSocket, sal_False);
2110 
2111         return osl_Socket_Ok;
2112     }
2113     else
2114     {
2115         /* really an error or just delayed? */
2116         if (errno != EINPROGRESS)
2117         {
2118             pSocket->m_nLastError=errno;
2119             OSL_TRACE(
2120                 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
2121                 errno, strerror(errno));
2122 
2123             osl_enableNonBlockingMode(pSocket, sal_False);
2124             return osl_Socket_Error;
2125         }
2126     }
2127 
2128 
2129     /* prepare select set for socket  */
2130     FD_ZERO(&WriteSet);
2131     FD_ZERO(&ExcptSet);
2132     FD_SET(pSocket->m_Socket, &WriteSet);
2133     FD_SET(pSocket->m_Socket, &ExcptSet);
2134 
2135     /* prepare timeout */
2136     if (pTimeout)
2137     {
2138         /* divide milliseconds into seconds and microseconds */
2139         tv.tv_sec=  pTimeout->Seconds;
2140         tv.tv_usec= pTimeout->Nanosec / 1000L;
2141     }
2142 
2143     /* select */
2144     ReadyHandles= select(pSocket->m_Socket+1,
2145                          0,
2146                          PTR_FD_SET(WriteSet),
2147                          PTR_FD_SET(ExcptSet),
2148                          (pTimeout) ? &tv : 0);
2149 
2150     if (ReadyHandles > 0)  /* connected */
2151     {
2152         if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
2153         {
2154             int nErrorCode = 0;
2155 #ifdef SOLARIS
2156 /*  mfe: Solaris 'cc +w' means 5th argument should be a 'int*'!
2157          it's really defined as 'int*' in /usr/include/sys/socket.h!
2158          the man page says it expects a 'size_t*'
2159 */
2160             int nErrorSize = sizeof( nErrorCode );
2161 #else
2162             size_t nErrorSize = sizeof( nErrorCode );
2163 #endif
2164 
2165             int nSockOpt;
2166 
2167             nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
2168 #ifdef SOLARIS
2169 /*  mfe: Solaris 'cc +w' means 4th argument should be a 'char*'!
2170          it's really defined as 'char*' in /usr/include/sys/socket.h!
2171          the man page says it expects a 'void*'
2172 */
2173                                     (char*)
2174 #endif
2175                                     &nErrorCode, (int*)&nErrorSize );
2176             if ( (nSockOpt == 0) && (nErrorCode == 0))
2177                 Result = osl_Socket_Ok;
2178             else
2179                 Result = osl_Socket_Error;
2180         }
2181         else
2182         {
2183             Result= osl_Socket_Error;
2184         }
2185     }
2186     else if (ReadyHandles < 0)  /* error */
2187     {
2188         if (errno == EBADF) /* most probably interrupted by close() */
2189         {
2190             /* do not access pSockImpl because it is about to be or */
2191             /* already destroyed */
2192             return osl_Socket_Interrupted;
2193         }
2194         else
2195         {
2196             pSocket->m_nLastError=errno;
2197             Result= osl_Socket_Error;
2198         }
2199     }
2200     else    /* timeout */
2201     {
2202         pSocket->m_nLastError=errno;
2203         Result= osl_Socket_TimedOut;
2204     }
2205 
2206     osl_enableNonBlockingMode(pSocket, sal_False);
2207 
2208     return Result;
2209 }
2210 
2211 
2212 /*****************************************************************************/
2213 /* osl_acceptConnectionOnSocket  */
2214 /*****************************************************************************/
2215 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
2216                         oslSocketAddr* ppAddr)
2217 {
2218     struct sockaddr Addr;
2219     int Connection, Flags;
2220     sal_uInt32 AddrLen = sizeof(struct sockaddr);
2221     oslSocket pConnectionSockImpl;
2222 
2223     OSL_ASSERT(pSocket);
2224     if ( pSocket == 0 )
2225     {
2226         return 0;
2227     }
2228 
2229     pSocket->m_nLastError=0;
2230 #if defined(LINUX)
2231     pSocket->m_bIsAccepting = sal_True;
2232 #endif /* LINUX */
2233 
2234     if( ppAddr && *ppAddr )
2235     {
2236         osl_destroySocketAddr( *ppAddr );
2237         *ppAddr = 0;
2238     }
2239 
2240     /* prevent Linux EINTR behaviour */
2241     do
2242     {
2243         Connection = accept(pSocket->m_Socket, &Addr, (int*)PTR_SIZE_T(AddrLen));
2244     } while (Connection == -1 && errno == EINTR);
2245 
2246 
2247     /* accept failed? */
2248     if( Connection == OSL_SOCKET_ERROR )
2249     {
2250         pSocket->m_nLastError=errno;
2251         OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'\n",strerror(errno));
2252 
2253 #if defined(LINUX)
2254         pSocket->m_bIsAccepting = sal_False;
2255 #endif /* LINUX */
2256         return 0;
2257     }
2258 
2259     OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
2260 
2261 
2262 #if defined(LINUX)
2263     if ( pSocket->m_bIsInShutdown == sal_True )
2264     {
2265         close(Connection);
2266         OSL_TRACE("osl_acceptConnectionOnSocket : close while accept\n");
2267         return 0;
2268     }
2269 #endif /* LINUX */
2270 
2271 
2272     if(ppAddr)
2273     {
2274         *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
2275     }
2276 
2277     /* alloc memory */
2278     pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
2279 
2280     /* set close-on-exec flag */
2281     if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
2282     {
2283         Flags |= FD_CLOEXEC;
2284         if (fcntl(Connection, F_SETFD, Flags) == -1)
2285         {
2286             pSocket->m_nLastError=errno;
2287             OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
2288                       errno,
2289                       strerror(errno));
2290         }
2291 
2292     }
2293 
2294     pConnectionSockImpl->m_Socket           = Connection;
2295     pConnectionSockImpl->m_nLastError       = 0;
2296     pConnectionSockImpl->m_CloseCallback    = NULL;
2297     pConnectionSockImpl->m_CallbackArg      = NULL;
2298 #if defined(LINUX)
2299     pConnectionSockImpl->m_bIsAccepting     = sal_False;
2300 
2301     pSocket->m_bIsAccepting = sal_False;
2302 #endif /* LINUX */
2303     return pConnectionSockImpl;
2304 }
2305 
2306 /*****************************************************************************/
2307 /* osl_receiveSocket  */
2308 /*****************************************************************************/
2309 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
2310                           void* pBuffer,
2311                           sal_uInt32 BytesToRead,
2312                           oslSocketMsgFlag Flag)
2313 {
2314     int nRead;
2315 
2316     OSL_ASSERT(pSocket);
2317     if ( pSocket == 0 )
2318     {
2319         OSL_TRACE("osl_receiveSocket : Invalid socket");
2320         return -1;
2321     }
2322 
2323     pSocket->m_nLastError=0;
2324 
2325     do
2326     {
2327         nRead =  recv(pSocket->m_Socket,
2328                       (sal_Char*)pBuffer,
2329                       BytesToRead,
2330                       MSG_FLAG_TO_NATIVE(Flag));
2331     } while ( nRead < 0 && errno == EINTR );
2332 
2333     if ( nRead < 0 )
2334     {
2335         pSocket->m_nLastError=errno;
2336         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
2337     }
2338     else if ( nRead == 0 )
2339     {
2340         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2341     }
2342 
2343     return nRead;
2344 }
2345 
2346 
2347 /*****************************************************************************/
2348 /* osl_receiveFromSocket  */
2349 /*****************************************************************************/
2350 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
2351                               oslSocketAddr pSenderAddr,
2352                               void* pBuffer,
2353                               sal_uInt32 BufferSize,
2354                               oslSocketMsgFlag Flag)
2355 {
2356     int nRead;
2357     struct sockaddr *pSystemSockAddr = 0;
2358     int AddrLen = 0;
2359     if( pSenderAddr )
2360     {
2361         AddrLen = sizeof( struct sockaddr );
2362         pSystemSockAddr = &(pSenderAddr->m_sockaddr);
2363     }
2364 
2365     OSL_ASSERT(pSocket);
2366     if ( pSocket == 0 )
2367     {
2368         OSL_TRACE("osl_receiveFromSocket : Invalid socket");
2369         return -1;
2370     }
2371 
2372     pSocket->m_nLastError=0;
2373 
2374     nRead = recvfrom(pSocket->m_Socket,
2375                      (sal_Char*)pBuffer,
2376                      BufferSize,
2377                      MSG_FLAG_TO_NATIVE(Flag),
2378                      pSystemSockAddr,
2379                      PTR_SIZE_T(AddrLen));
2380 
2381     if ( nRead < 0 )
2382     {
2383         pSocket->m_nLastError=errno;
2384         OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
2385     }
2386     else if ( nRead == 0 )
2387     {
2388         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2389     }
2390 
2391     return nRead;
2392 }
2393 
2394 
2395 /*****************************************************************************/
2396 /* osl_sendSocket  */
2397 /*****************************************************************************/
2398 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
2399                        const void* pBuffer,
2400                        sal_uInt32 BytesToSend,
2401                        oslSocketMsgFlag Flag)
2402 {
2403     int nWritten;
2404 
2405     OSL_ASSERT(pSocket);
2406     if ( pSocket == 0 )
2407     {
2408         OSL_TRACE("osl_sendSocket : Invalid socket");
2409         return -1;
2410     }
2411 
2412     pSocket->m_nLastError=0;
2413 
2414     do
2415     {
2416         nWritten = send(pSocket->m_Socket,
2417                         (sal_Char*)pBuffer,
2418                         BytesToSend,
2419                         MSG_FLAG_TO_NATIVE(Flag));
2420     } while ( nWritten < 0 && errno == EINTR );
2421 
2422 
2423     if ( nWritten < 0 )
2424     {
2425         pSocket->m_nLastError=errno;
2426         OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
2427     }
2428     else if ( nWritten == 0 )
2429     {
2430         OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
2431     }
2432 
2433     return nWritten;
2434 }
2435 
2436 /*****************************************************************************/
2437 /* osl_sendToSocket  */
2438 /*****************************************************************************/
2439 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
2440                          oslSocketAddr ReceiverAddr,
2441                          const void* pBuffer,
2442                          sal_uInt32 BytesToSend,
2443                          oslSocketMsgFlag Flag)
2444 {
2445     int nWritten;
2446 
2447     struct sockaddr *pSystemSockAddr = 0;
2448     int AddrLen = 0;
2449     if( ReceiverAddr )
2450     {
2451         pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
2452         AddrLen = sizeof( struct sockaddr );
2453     }
2454 
2455     OSL_ASSERT(pSocket);
2456     if ( pSocket == 0 )
2457     {
2458         OSL_TRACE("osl_sendToSocket : Invalid socket");
2459         return -1;
2460     }
2461 
2462     pSocket->m_nLastError=0;
2463 
2464     /* ReceiverAddr might be 0 when used on a connected socket. */
2465     /* Then sendto should behave like send. */
2466 
2467     nWritten = sendto(pSocket->m_Socket,
2468                       (sal_Char*)pBuffer,
2469                       BytesToSend,
2470                       MSG_FLAG_TO_NATIVE(Flag),
2471                       pSystemSockAddr,
2472                       AddrLen);
2473 
2474     if ( nWritten < 0 )
2475     {
2476         pSocket->m_nLastError=errno;
2477         OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
2478     }
2479     else if ( nWritten == 0 )
2480     {
2481         OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
2482     }
2483 
2484     return nWritten;
2485 }
2486 
2487 /*****************************************************************************/
2488 /* osl_readSocket  */
2489 /*****************************************************************************/
2490 sal_Int32 SAL_CALL osl_readSocket (
2491     oslSocket pSocket, void *pBuffer, sal_Int32 n )
2492 {
2493     sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
2494     sal_uInt32 BytesRead= 0;
2495     sal_uInt32 BytesToRead= n;
2496 
2497     OSL_ASSERT( pSocket);
2498 
2499     /* loop until all desired bytes were read or an error occured */
2500     while (BytesToRead > 0)
2501     {
2502         sal_Int32 RetVal;
2503         RetVal= osl_receiveSocket(pSocket,
2504                                    Ptr,
2505                                    BytesToRead,
2506                                    osl_Socket_MsgNormal);
2507 
2508         /* error occured? */
2509         if(RetVal <= 0)
2510         {
2511             break;
2512         }
2513 
2514         BytesToRead -= RetVal;
2515         BytesRead += RetVal;
2516         Ptr += RetVal;
2517     }
2518 
2519     return BytesRead;
2520 }
2521 
2522 /*****************************************************************************/
2523 /* osl_writeSocket  */
2524 /*****************************************************************************/
2525 sal_Int32 SAL_CALL osl_writeSocket(
2526     oslSocket pSocket, const void *pBuffer, sal_Int32 n )
2527 {
2528     /* loop until all desired bytes were send or an error occured */
2529     sal_uInt32 BytesSend= 0;
2530     sal_uInt32 BytesToSend= n;
2531     sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
2532 
2533     OSL_ASSERT( pSocket );
2534 
2535     while (BytesToSend > 0)
2536     {
2537         sal_Int32 RetVal;
2538 
2539         RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
2540 
2541         /* error occured? */
2542         if(RetVal <= 0)
2543         {
2544             break;
2545         }
2546 
2547         BytesToSend -= RetVal;
2548         BytesSend += RetVal;
2549         Ptr += RetVal;
2550 
2551     }
2552     return BytesSend;
2553 }
2554 
2555 /*****************************************************************************/
2556 /* __osl_socket_poll */
2557 /*****************************************************************************/
2558 
2559 #ifdef HAVE_POLL_H /* poll() */
2560 
2561 sal_Bool __osl_socket_poll (
2562     oslSocket        pSocket,
2563     const TimeValue* pTimeout,
2564     short            nEvent)
2565 {
2566     struct pollfd fds;
2567     int           timeout;
2568     int           result;
2569 
2570     OSL_ASSERT(pSocket);
2571     pSocket->m_nLastError = 0;
2572 
2573     fds.fd      = pSocket->m_Socket;
2574     fds.events  = nEvent;
2575     fds.revents = 0;
2576 
2577     timeout = -1;
2578     if (pTimeout)
2579     {
2580         /* Convert to [ms] */
2581         timeout  = pTimeout->Seconds * 1000;
2582         timeout += pTimeout->Nanosec / (1000 * 1000);
2583     }
2584 
2585     result = poll (&fds, 1, timeout);
2586     if (result < 0)
2587     {
2588         pSocket->m_nLastError = errno;
2589         OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2590                   errno, strerror(errno));
2591         return sal_False;
2592     }
2593     if (result == 0)
2594     {
2595         /* Timeout */
2596         return sal_False;
2597     }
2598 
2599     return ((fds.revents & nEvent) == nEvent);
2600 }
2601 
2602 #else  /* select() */
2603 
2604 sal_Bool __osl_socket_poll (
2605     oslSocket        pSocket,
2606     const TimeValue* pTimeout,
2607     short            nEvent)
2608 {
2609     fd_set         fds;
2610     struct timeval tv;
2611     int            result;
2612 
2613     OSL_ASSERT(pSocket);
2614     pSocket->m_nLastError = 0;
2615 
2616     FD_ZERO(&fds);
2617     FD_SET(pSocket->m_Socket, &fds);
2618 
2619     if (pTimeout)
2620     {
2621         /* Convert to 'timeval' */
2622         tv.tv_sec  = pTimeout->Seconds;
2623         tv.tv_usec = pTimeout->Nanosec / 1000;
2624     }
2625 
2626     result = select (
2627         pSocket->m_Socket + 1,
2628         (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2629         (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2630         (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2631         (pTimeout)          ? &tv             : NULL);
2632 
2633     if (result < 0)
2634     {
2635         pSocket->m_nLastError = errno;
2636         OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2637                   errno, strerror(errno));
2638         return sal_False;
2639     }
2640     if (result == 0)
2641     {
2642         /* Timeout */
2643         return sal_False;
2644     }
2645 
2646     return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2647 }
2648 
2649 #endif /* HAVE_POLL_H */
2650 
2651 /*****************************************************************************/
2652 /* osl_isReceiveReady  */
2653 /*****************************************************************************/
2654 sal_Bool SAL_CALL osl_isReceiveReady (
2655     oslSocket pSocket, const TimeValue* pTimeout)
2656 {
2657     OSL_ASSERT(pSocket);
2658     if (pSocket == NULL)
2659     {
2660         /* ENOTSOCK */
2661         return sal_False;
2662     }
2663 
2664     return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2665 }
2666 
2667 /*****************************************************************************/
2668 /* osl_isSendReady  */
2669 /*****************************************************************************/
2670 sal_Bool SAL_CALL osl_isSendReady (
2671     oslSocket pSocket, const TimeValue* pTimeout)
2672 {
2673     OSL_ASSERT(pSocket);
2674     if (pSocket == NULL)
2675     {
2676         /* ENOTSOCK */
2677         return sal_False;
2678     }
2679 
2680     return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2681 }
2682 
2683 /*****************************************************************************/
2684 /* osl_isExceptionPending  */
2685 /*****************************************************************************/
2686 sal_Bool SAL_CALL osl_isExceptionPending (
2687     oslSocket pSocket, const TimeValue* pTimeout)
2688 {
2689     OSL_ASSERT(pSocket);
2690     if (pSocket == NULL)
2691     {
2692         /* ENOTSOCK */
2693         return sal_False;
2694     }
2695 
2696     return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2697 }
2698 
2699 /*****************************************************************************/
2700 /* osl_shutdownSocket  */
2701 /*****************************************************************************/
2702 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2703                            oslSocketDirection Direction)
2704 {
2705     int nRet;
2706 
2707     OSL_ASSERT(pSocket);
2708     if ( pSocket == 0 )
2709     {
2710         return sal_False;
2711     }
2712 
2713     pSocket->m_nLastError=0;
2714 
2715     nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2716     if (nRet != 0 )
2717     {
2718         pSocket->m_nLastError=errno;
2719         OSL_TRACE("shutdown error '%s'\n",strerror(errno));
2720     }
2721     return (nRet==0);
2722 }
2723 
2724 
2725 /*****************************************************************************/
2726 /* osl_getSocketOption  */
2727 /*****************************************************************************/
2728 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2729                             oslSocketOptionLevel    Level,
2730                             oslSocketOption         Option,
2731                             void*                   pBuffer,
2732                             sal_uInt32                  BufferLen)
2733 {
2734     OSL_ASSERT(pSocket);
2735     if ( pSocket == 0 )
2736     {
2737         return -1;
2738     }
2739 
2740     pSocket->m_nLastError=0;
2741 
2742     if(getsockopt(pSocket->m_Socket,
2743                   OPTION_LEVEL_TO_NATIVE(Level),
2744                   OPTION_TO_NATIVE(Option),
2745                   (sal_Char*)pBuffer,
2746                   (int*)PTR_SIZE_T(BufferLen)) == -1)
2747     {
2748         pSocket->m_nLastError=errno;
2749         return -1;
2750     }
2751 
2752     return BufferLen;
2753 }
2754 
2755 /*****************************************************************************/
2756 /* osl_setSocketOption  */
2757 /*****************************************************************************/
2758 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2759                             oslSocketOptionLevel    Level,
2760                             oslSocketOption         Option,
2761                             void*                   pBuffer,
2762                             sal_uInt32                  BufferLen)
2763 {
2764     int nRet;
2765 
2766     OSL_ASSERT(pSocket);
2767     if ( pSocket == 0 )
2768     {
2769         return sal_False;
2770     }
2771 
2772     pSocket->m_nLastError=0;
2773 
2774     nRet = setsockopt(pSocket->m_Socket,
2775                       OPTION_LEVEL_TO_NATIVE(Level),
2776                       OPTION_TO_NATIVE(Option),
2777                       (sal_Char*)pBuffer,
2778                       BufferLen);
2779 
2780     if ( nRet < 0 )
2781     {
2782         pSocket->m_nLastError=errno;
2783         return sal_False;
2784     }
2785 
2786     return sal_True;
2787 }
2788 
2789 /*****************************************************************************/
2790 /* osl_enableNonBlockingMode  */
2791 /*****************************************************************************/
2792 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2793                                   sal_Bool On)
2794 {
2795     int flags;
2796     int nRet;
2797 
2798     OSL_ASSERT(pSocket);
2799     if ( pSocket == 0 )
2800     {
2801         return sal_False;
2802     }
2803 
2804     pSocket->m_nLastError=0;
2805 
2806     flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2807 
2808     if (On)
2809         flags |= O_NONBLOCK;
2810     else
2811         flags &= ~(O_NONBLOCK);
2812 
2813     nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2814 
2815     if  ( nRet < 0 )
2816     {
2817         pSocket->m_nLastError=errno;
2818         return sal_False;
2819     }
2820 
2821     return sal_True;
2822 }
2823 
2824 /*****************************************************************************/
2825 /* osl_isNonBlockingMode  */
2826 /*****************************************************************************/
2827 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2828 {
2829     int flags;
2830 
2831     OSL_ASSERT(pSocket);
2832     if ( pSocket == 0 )
2833     {
2834         return sal_False;
2835     }
2836 
2837     pSocket->m_nLastError=0;
2838 
2839     flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2840 
2841     if (flags == -1 || !(flags & O_NONBLOCK))
2842         return sal_False;
2843     else
2844         return sal_True;
2845 }
2846 
2847 /*****************************************************************************/
2848 /* osl_getSocketType  */
2849 /*****************************************************************************/
2850 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2851 {
2852     int Type=0;
2853     sal_uInt32 TypeSize= sizeof(Type);
2854 
2855     OSL_ASSERT(pSocket);
2856     if ( pSocket == 0 )
2857     {
2858         return osl_Socket_TypeInvalid;
2859     }
2860 
2861     pSocket->m_nLastError=0;
2862 
2863     if(getsockopt(pSocket->m_Socket,
2864                   OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2865                   OPTION_TO_NATIVE(osl_Socket_OptionType),
2866                   (sal_Char*)&Type,
2867                   (int*)PTR_SIZE_T(TypeSize)) == -1)
2868     {
2869         /* error */
2870         pSocket->m_nLastError=errno;
2871         return osl_Socket_TypeInvalid;
2872     }
2873 
2874     return TYPE_FROM_NATIVE(Type);
2875 
2876 }
2877 
2878 /*****************************************************************************/
2879 /* osl_getLastSocketErrorDescription  */
2880 /*****************************************************************************/
2881 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2882 {
2883     sal_Char pszError[1024];
2884 
2885     pszError[0] = '\0';
2886 
2887     osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2888 
2889     rtl_uString_newFromAscii(ustrError,pszError);
2890 
2891     return;
2892 }
2893 
2894 
2895 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2896 {
2897     /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2898     pBuffer[BufferSize-1]= '\0';
2899 
2900     if ( pSocket == 0 )
2901     {
2902         strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2903         return;
2904     }
2905 
2906     strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2907     return;
2908 }
2909 
2910 /*****************************************************************************/
2911 /* osl_getLastSocketError  */
2912 /*****************************************************************************/
2913 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2914 {
2915     if ( pSocket == 0 )
2916     {
2917         return ERROR_FROM_NATIVE(EINVAL);
2918     }
2919 
2920     return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2921 }
2922 
2923 /*****************************************************************************/
2924 /* SocketSet                                                                 */
2925 /*****************************************************************************/
2926 typedef struct _TSocketSetImpl
2927 {
2928     int     m_MaxHandle;    /* for select(), the largest descriptor in the set */
2929     fd_set  m_Set;          /* the set of descriptors */
2930 
2931 } TSocketSetImpl;
2932 
2933 /*****************************************************************************/
2934 /* osl_createSocketSet  */
2935 /*****************************************************************************/
2936 oslSocketSet SAL_CALL osl_createSocketSet()
2937 {
2938     TSocketSetImpl* pSet;
2939 
2940     pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2941 
2942     OSL_ASSERT(pSet);
2943 
2944     if(pSet)
2945     {
2946         pSet->m_MaxHandle= 0;
2947         FD_ZERO(&pSet->m_Set);
2948     }
2949 
2950     return (oslSocketSet)pSet;
2951 }
2952 
2953 /*****************************************************************************/
2954 /* osl_destroySocketSet  */
2955 /*****************************************************************************/
2956 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2957 {
2958     if(Set)
2959         free(Set);
2960 }
2961 
2962 /*****************************************************************************/
2963 /* osl_clearSocketSet  */
2964 /*****************************************************************************/
2965 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2966 {
2967     TSocketSetImpl* pSet;
2968     OSL_ASSERT(Set);
2969     if ( Set == 0 )
2970     {
2971         return;
2972     }
2973 
2974     pSet= (TSocketSetImpl*)Set;
2975     pSet->m_MaxHandle= 0;
2976 
2977     FD_ZERO(&pSet->m_Set);
2978 }
2979 
2980 /*****************************************************************************/
2981 /* osl_addToSocketSet  */
2982 /*****************************************************************************/
2983 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2984 {
2985     TSocketSetImpl* pSet;
2986 
2987     OSL_ASSERT(Set);
2988     OSL_ASSERT(pSocket);
2989 
2990     if ( Set == 0 || pSocket == 0)
2991     {
2992         return;
2993     }
2994 
2995     pSet= (TSocketSetImpl*)Set;
2996 
2997     /* correct max handle */
2998     if(pSocket->m_Socket > pSet->m_MaxHandle)
2999         pSet->m_MaxHandle= pSocket->m_Socket;
3000     FD_SET(pSocket->m_Socket, &pSet->m_Set);
3001 
3002 }
3003 
3004 /*****************************************************************************/
3005 /* osl_removeFromSocketSet  */
3006 /*****************************************************************************/
3007 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
3008 {
3009     TSocketSetImpl* pSet;
3010 
3011     OSL_ASSERT(Set);
3012     OSL_ASSERT(pSocket);
3013 
3014     if ( Set == 0 || pSocket == 0)
3015     {
3016         return;
3017     }
3018 
3019     pSet= (TSocketSetImpl*)Set;
3020 
3021     /* correct max handle */
3022     if(pSocket->m_Socket == pSet->m_MaxHandle)
3023     {
3024         /* not optimal, since the next used descriptor might be */
3025         /* much smaller than m_Socket-1, but it will do */
3026         pSet->m_MaxHandle--;
3027         if(pSet->m_MaxHandle < 0)
3028         {
3029             pSet->m_MaxHandle= 0;   /* avoid underflow */
3030         }
3031     }
3032 
3033     FD_CLR(pSocket->m_Socket, &pSet->m_Set);
3034 }
3035 
3036 /*****************************************************************************/
3037 /* osl_isInSocketSet  */
3038 /*****************************************************************************/
3039 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
3040 {
3041     TSocketSetImpl* pSet;
3042 
3043     OSL_ASSERT(Set);
3044     OSL_ASSERT(pSocket);
3045     if ( Set == 0 || pSocket == 0 )
3046     {
3047         return sal_False;
3048     }
3049 
3050     pSet= (TSocketSetImpl*)Set;
3051 
3052     return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
3053 }
3054 
3055 /*****************************************************************************/
3056 /* osl_demultiplexSocketEvents  */
3057 /*****************************************************************************/
3058 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
3059                                     oslSocketSet OutgoingSet,
3060                                     oslSocketSet OutOfBandSet,
3061                                     const TimeValue* pTimeout)
3062 {
3063     int MaxHandle= 0;
3064     struct timeval  tv;
3065     TSocketSetImpl* pInSet;
3066     TSocketSetImpl* pOutSet;
3067     TSocketSetImpl* pOOBSet;
3068 
3069     if (pTimeout)
3070     {
3071         /* non-blocking call */
3072         tv.tv_sec  = pTimeout->Seconds;
3073         tv.tv_usec = pTimeout->Nanosec / 1000L;
3074     }
3075 
3076     /* map opaque data to impl-types */
3077     pInSet=  (TSocketSetImpl*)IncomingSet;
3078     pOutSet= (TSocketSetImpl*)OutgoingSet;
3079     pOOBSet= (TSocketSetImpl*)OutOfBandSet;
3080 
3081     /* get max handle from all sets */
3082     if (pInSet)
3083         MaxHandle= pInSet->m_MaxHandle;
3084 
3085     if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
3086         MaxHandle= pOutSet->m_MaxHandle;
3087 
3088     if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
3089         MaxHandle= pOOBSet->m_MaxHandle;
3090 
3091     return select(MaxHandle+1,
3092                   pInSet  ? PTR_FD_SET(pInSet->m_Set)  : 0,
3093                   pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
3094                   pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
3095                   pTimeout ? &tv : 0);
3096 }
3097 
3098