Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "system.hxx"
21 :
22 : #include <osl/socket.h>
23 : #include <osl/mutex.h>
24 : #include <osl/signal.h>
25 :
26 : #include <rtl/alloc.h>
27 : #include <assert.h>
28 : #include <ctype.h>
29 : #include <sal/types.h>
30 : #include <sal/log.hxx>
31 :
32 : #include "sockimpl.hxx"
33 :
34 : /* defines for poll */
35 : #ifdef HAVE_POLL_H
36 : #undef HAVE_POLL_H
37 : #endif
38 :
39 : #if defined(LINUX) || defined(NETBSD) || defined ( FREEBSD ) || \
40 : defined (MACOSX) || defined (OPENBSD) || defined(DRAGONFLY)
41 : #include <sys/poll.h>
42 : #define HAVE_POLL_H
43 : #endif /* HAVE_POLL_H */
44 :
45 : #if defined(SOLARIS)
46 : #include <poll.h>
47 : #define HAVE_POLL_H
48 : #endif /* SOLARIS */
49 :
50 : #ifndef HAVE_POLL_H
51 : #define POLLIN 0x0001
52 : #define POLLOUT 0x0002
53 : #define POLLPRI 0x0004
54 : #endif /* HAVE_POLL_H */
55 :
56 : /* defines for shutdown */
57 : #define SD_RECEIVE 0
58 : #define SD_SEND 1
59 : #define SD_BOTH 2
60 :
61 : /*
62 : oslSocketAddr is a pointer to a Berkeley struct sockaddr.
63 : I refrained from using sockaddr_in because of possible further
64 : extensions of this socket-interface (IP-NG?).
65 : The intention was to hide all Berkeley data-structures from
66 : direct access past the osl-interface.
67 :
68 : The current implementation is internet (IP) centered. All
69 : the constructor-functions (osl_create...) take parameters
70 : that will probably make sense only in the IP-environment
71 : (e.g. because of using the dotted-address-format).
72 :
73 : If the interface will be extended to host other protocol-
74 : families, I expect no externally visible changes in the
75 : existing functions. You'll probably need only new
76 : constructor-functions who take the different address
77 : formats into consideration (maybe a long dotted address
78 : or whatever).
79 : */
80 :
81 : /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
82 : /* are the same! I don't like it very much but see no other easy way to */
83 : /* conceal the struct sockaddr from the eyes of the user. */
84 :
85 : #define OSL_INVALID_SOCKET -1
86 : #define OSL_SOCKET_ERROR -1
87 :
88 : /* Buffer size for gethostbyname */
89 : #define MAX_HOSTBUFFER_SIZE 2048
90 :
91 : /*****************************************************************************/
92 : /* enum oslAddrFamily */
93 : /*****************************************************************************/
94 :
95 : /* map */
96 : static const unsigned long FamilyMap[]= {
97 : AF_INET, /* osl_Socket_FamilyInet */
98 : AF_IPX, /* osl_Socket_FamilyIpx */
99 : 0 /* osl_Socket_FamilyInvalid */
100 : };
101 :
102 : /* reverse map */
103 0 : static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
104 : {
105 0 : oslAddrFamily i= (oslAddrFamily)0;
106 :
107 0 : while(i != osl_Socket_FamilyInvalid)
108 : {
109 0 : if(FamilyMap[i] == nativeType)
110 0 : return i;
111 0 : i = (oslAddrFamily) ( i + 1 );
112 : }
113 :
114 0 : return i;
115 : }
116 :
117 : /* macros */
118 : #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
119 : #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
120 :
121 : /*****************************************************************************/
122 : /* enum oslProtocol */
123 : /*****************************************************************************/
124 :
125 : /* map */
126 : static const sal_uInt32 ProtocolMap[]= {
127 : 0, /* osl_Socket_ProtocolIp */
128 : NSPROTO_IPX, /* osl_Socket_ProtocolIpx */
129 : NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
130 : NSPROTO_SPXII, /* osl_Socket_ProtocolSpxII */
131 : 0 /* osl_Socket_ProtocolInvalid */
132 : };
133 :
134 : /* reverse map */
135 : /* mfe: NOT USED
136 : static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
137 : {
138 : oslProtocol i= (oslProtocol)0;
139 :
140 : while(i != osl_Socket_ProtocolInvalid)
141 : {
142 : if(ProtocolMap[i] == nativeType)
143 : return i;
144 : i = (oslProtocol) ( i + 1);
145 : }
146 :
147 : return i;
148 : }
149 : */
150 :
151 : /* macros */
152 : #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
153 :
154 : /*****************************************************************************/
155 : /* enum oslSocketType */
156 : /*****************************************************************************/
157 :
158 : /* map */
159 : static const sal_uInt32 TypeMap[]= {
160 : SOCK_STREAM, /* osl_Socket_TypeStream */
161 : SOCK_DGRAM, /* osl_Socket_TypeDgram */
162 : SOCK_RAW, /* osl_Socket_TypeRaw */
163 : SOCK_RDM, /* osl_Socket_TypeRdm */
164 : SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
165 : 0 /* osl_Socket_TypeInvalid */
166 : };
167 :
168 : /* reverse map */
169 0 : static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
170 : {
171 0 : oslSocketType i= (oslSocketType)0;
172 :
173 0 : while(i != osl_Socket_TypeInvalid)
174 : {
175 0 : if(TypeMap[i] == nativeType)
176 0 : return i;
177 0 : i = (oslSocketType)(i + 1);
178 : }
179 :
180 0 : return i;
181 : }
182 :
183 : /* macros */
184 : #define TYPE_TO_NATIVE(x) TypeMap[x]
185 : #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
186 :
187 : /*****************************************************************************/
188 : /* enum oslSocketOption */
189 : /*****************************************************************************/
190 :
191 : /* map */
192 : static const sal_uInt32 OptionMap[]= {
193 : SO_DEBUG, /* osl_Socket_OptionDebug */
194 : SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
195 : SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
196 : SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
197 : SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
198 : SO_BROADCAST, /* osl_Socket_OptionBroadcast */
199 : SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
200 : SO_LINGER, /* osl_Socket_OptionLinger */
201 : SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
202 : SO_SNDBUF, /* osl_Socket_OptionSndBuf */
203 : SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
204 : SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
205 : SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
206 : SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
207 : SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
208 : SO_ERROR, /* osl_Socket_OptionError */
209 : SO_TYPE, /* osl_Socket_OptionType */
210 : TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
211 : 0 /* osl_Socket_OptionInvalid */
212 : };
213 :
214 : /* reverse map */
215 : /* mfe: NOT USED
216 : static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
217 : {
218 : oslSocketOption i= (oslSocketOption)0;
219 :
220 : while(i != osl_Socket_OptionInvalid)
221 : {
222 : if(OptionMap[i] == nativeType)
223 : return i;
224 : i = (oslSocketOption) ( i + 1 );
225 : }
226 :
227 : return i;
228 : }
229 : */
230 : /* macros */
231 : #define OPTION_TO_NATIVE(x) OptionMap[x]
232 :
233 : /*****************************************************************************/
234 : /* enum oslSocketOptionLevel */
235 : /*****************************************************************************/
236 :
237 : static const sal_uInt32 OptionLevelMap[]= {
238 : SOL_SOCKET, /* osl_Socket_LevelSocket */
239 : IPPROTO_TCP, /* osl_Socket_LevelTcp */
240 : 0 /* osl_Socket_LevelInvalid */
241 : };
242 :
243 : /* reverse map */
244 : /* mfe: NOT USED
245 : static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
246 : {
247 : oslSocketOptionLevel i= (oslSocketOptionLevel)0;
248 :
249 : while(i != osl_Socket_LevelInvalid)
250 : {
251 : if(OptionLevelMap[i] == nativeType)
252 : return i;
253 : i = (oslSocketOptionLevel) ( i + 1 );
254 : }
255 :
256 : return i;
257 : }
258 : */
259 : /* macros */
260 : #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
261 :
262 : /*****************************************************************************/
263 : /* enum oslSocketMsgFlag */
264 : /*****************************************************************************/
265 :
266 : static const sal_uInt32 SocketMsgFlagMap[]= {
267 : 0, /* osl_Socket_MsgNormal */
268 : MSG_OOB, /* osl_Socket_MsgOOB */
269 : MSG_PEEK, /* osl_Socket_MsgPeek */
270 : MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
271 : MSG_MAXIOVLEN, /* osl_Socket_MsgMaxIOVLen */
272 : 0 /* osl_Socket_MsgInvalid */
273 : };
274 :
275 : /* reverse map */
276 : /* mfe: NOT USED
277 : static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
278 : {
279 : oslSocketMsgFlag i= (oslSocketMsgFlag)0;
280 :
281 : while(i != osl_Socket_MsgInvalid)
282 : {
283 : if(SocketMsgFlagMap[i] == nativeType)
284 : return i;
285 : i = (oslSocketMsgFlag) ( i + 1 );
286 : }
287 :
288 : return i;
289 : }
290 : */
291 :
292 : /* macros */
293 : #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
294 :
295 : /*****************************************************************************/
296 : /* enum oslSocketDirection */
297 : /*****************************************************************************/
298 :
299 : static const sal_uInt32 SocketDirection[]= {
300 : SD_RECEIVE, /* osl_Socket_DirRead */
301 : SD_SEND, /* osl_Socket_DirWrite */
302 : SD_BOTH, /* osl_Socket_DirReadWrite */
303 : 0 /* osl_Socket_DirInvalid */
304 : };
305 :
306 : /* reverse map */
307 : /* mfe: NOT USED
308 : static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
309 : {
310 : oslSocketDirection i= (oslSocketDirection)0;
311 :
312 : while(i != osl_Socket_DirInvalid)
313 : {
314 : if(SocketDirection[i] == nativeType)
315 : return i;
316 : i = (oslSocketDirection) ( i + 1 );
317 : }
318 :
319 : return i;
320 : }
321 : */
322 :
323 : /* macros */
324 : #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
325 :
326 : /*****************************************************************************/
327 : /* enum oslSocketError */
328 : /*****************************************************************************/
329 :
330 : static const struct
331 : {
332 : int errcode;
333 : oslSocketError error;
334 : } SocketError[]= {
335 : { 0, osl_Socket_E_None }, /* no error */
336 : { ENOTSOCK, osl_Socket_E_NotSocket }, /* Socket operation on non-socket */
337 : { EDESTADDRREQ, osl_Socket_E_DestAddrReq }, /* Destination address required */
338 : { EMSGSIZE, osl_Socket_E_MsgSize }, /* Message too long */
339 : { EPROTOTYPE, osl_Socket_E_Prototype }, /* Protocol wrong type for socket */
340 : { ENOPROTOOPT, osl_Socket_E_NoProtocol }, /* Protocol not available */
341 : { EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
342 : { ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport }, /* Socket type not supported */
343 : { EOPNOTSUPP, osl_Socket_E_OpNotSupport }, /* Operation not supported on socket */
344 : { EPFNOSUPPORT, osl_Socket_E_PfNoSupport }, /* Protocol family not supported */
345 : { EAFNOSUPPORT, osl_Socket_E_AfNoSupport }, /* Address family not supported by */
346 : /* protocol family */
347 : { EADDRINUSE, osl_Socket_E_AddrInUse }, /* Address already in use */
348 : { EADDRNOTAVAIL, osl_Socket_E_AddrNotAvail }, /* Can't assign requested address */
349 : { ENETDOWN, osl_Socket_E_NetDown }, /* Network is down */
350 : { ENETUNREACH, osl_Socket_E_NetUnreachable }, /* Network is unreachable */
351 : { ENETRESET, osl_Socket_E_NetReset }, /* Network dropped connection because */
352 : /* of reset */
353 : { ECONNABORTED, osl_Socket_E_ConnAborted }, /* Software caused connection abort */
354 : { ECONNRESET, osl_Socket_E_ConnReset }, /* Connection reset by peer */
355 : { ENOBUFS, osl_Socket_E_NoBufferSpace }, /* No buffer space available */
356 : { EISCONN, osl_Socket_E_IsConnected }, /* Socket is already connected */
357 : { ENOTCONN, osl_Socket_E_NotConnected }, /* Socket is not connected */
358 : { ESHUTDOWN, osl_Socket_E_Shutdown }, /* Can't send after socket shutdown */
359 : { ETOOMANYREFS, osl_Socket_E_TooManyRefs }, /* Too many references: can't splice */
360 : { ETIMEDOUT, osl_Socket_E_TimedOut }, /* Connection timed out */
361 : { ECONNREFUSED, osl_Socket_E_ConnRefused }, /* Connection refused */
362 : { EHOSTDOWN, osl_Socket_E_HostDown }, /* Host is down */
363 : { EHOSTUNREACH, osl_Socket_E_HostUnreachable }, /* No route to host */
364 : { EWOULDBLOCK, osl_Socket_E_WouldBlock }, /* call would block on non-blocking socket */
365 : { EALREADY, osl_Socket_E_Already }, /* operation already in progress */
366 : { EINPROGRESS, osl_Socket_E_InProgress }, /* operation now in progress */
367 : { EAGAIN, osl_Socket_E_WouldBlock }, /* same as EWOULDBLOCK */
368 : { -1, osl_Socket_E_InvalidError }
369 : };
370 :
371 : /* map */
372 : /* mfe: NOT USED
373 : static int osl_NativeFromSocketError(oslSocketError errorCode)
374 : {
375 : int i = 0;
376 :
377 : while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
378 : (SocketError[i].error != errorCode)) i++;
379 :
380 : return SocketError[i].errcode;
381 : }
382 : */
383 :
384 : /* reverse map */
385 0 : static oslSocketError osl_SocketErrorFromNative(int nativeType)
386 : {
387 0 : int i = 0;
388 :
389 0 : while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
390 0 : (SocketError[i].errcode != nativeType)) i++;
391 :
392 0 : return SocketError[i].error;
393 : }
394 :
395 : /* macros */
396 : #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
397 :
398 : /*****************************************************************************/
399 : /* local function prototypes */
400 : /*****************************************************************************/
401 :
402 : oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
403 : const sal_Char* pszDottedAddr, sal_Int32 Port);
404 :
405 : oslHostAddr SAL_CALL osl_psz_createHostAddr (
406 : const sal_Char *pszHostname, const oslSocketAddr Addr);
407 :
408 : oslHostAddr SAL_CALL osl_psz_createHostAddrByName (
409 : const sal_Char *pszHostname);
410 :
411 : const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (
412 : const oslHostAddr Addr);
413 :
414 : oslSocketResult SAL_CALL osl_psz_getLocalHostname (
415 : sal_Char *pBuffer, sal_uInt32 nBufLen);
416 :
417 : oslSocketAddr SAL_CALL osl_psz_resolveHostname (
418 : const sal_Char* pszHostname);
419 :
420 : sal_Int32 SAL_CALL osl_psz_getServicePort (
421 : const sal_Char* pszServicename, const sal_Char* pszProtocol);
422 :
423 : oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr (
424 : oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
425 :
426 : oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr (
427 : oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
428 :
429 : void SAL_CALL osl_psz_getLastSocketErrorDescription (
430 : oslSocket Socket, sal_Char* pBuffer, sal_uInt32 BufferSize);
431 :
432 : #if OSL_DEBUG_LEVEL > 1
433 : static sal_uInt32 g_nSocketImpl = 0;
434 : static sal_uInt32 g_nSocketAddr = 0;
435 :
436 : /* sorry, must be implemented otherwise */
437 :
438 : #endif /* OSL_DEBUG_LEVEL */
439 :
440 0 : oslSocket __osl_createSocketImpl(int Socket)
441 : {
442 : oslSocket pSocket;
443 :
444 0 : pSocket = static_cast<oslSocket>(calloc(1, sizeof(struct oslSocketImpl)));
445 :
446 0 : pSocket->m_Socket = Socket;
447 0 : pSocket->m_nLastError = 0;
448 0 : pSocket->m_nRefCount = 1;
449 :
450 : #if defined(LINUX)
451 0 : pSocket->m_bIsAccepting = false;
452 : #endif
453 :
454 : #if OSL_DEBUG_LEVEL > 1
455 : g_nSocketImpl ++;
456 : #endif
457 0 : return pSocket;
458 : }
459 :
460 0 : void __osl_destroySocketImpl(oslSocket Socket)
461 : {
462 0 : if ( Socket != NULL)
463 0 : free(Socket);
464 : #if OSL_DEBUG_LEVEL > 1
465 : g_nSocketImpl --;
466 : #endif
467 0 : }
468 :
469 11 : static oslSocketAddr __osl_createSocketAddr()
470 : {
471 11 : oslSocketAddr pAddr = static_cast<oslSocketAddr>(rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl )));
472 : #if OSL_DEBUG_LEVEL > 1
473 : g_nSocketAddr ++;
474 : #endif
475 11 : return pAddr;
476 : }
477 :
478 0 : static oslSocketAddr __osl_createSocketAddrWithFamily(
479 : oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
480 : {
481 : oslSocketAddr pAddr;
482 :
483 : SAL_WARN_IF( family != osl_Socket_FamilyInet, "sal.osl", "creating socket for non-IP address family" );
484 :
485 0 : pAddr = __osl_createSocketAddr();
486 0 : switch( family )
487 : {
488 : case osl_Socket_FamilyInet:
489 : {
490 0 : struct sockaddr_in* pInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
491 :
492 0 : pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
493 0 : pInetAddr->sin_addr.s_addr = nAddr;
494 0 : pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
495 0 : break;
496 : }
497 : default:
498 0 : pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
499 : }
500 0 : return pAddr;
501 : }
502 :
503 0 : static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
504 : {
505 0 : oslSocketAddr pAddr = __osl_createSocketAddr();
506 0 : memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
507 0 : return pAddr;
508 : }
509 :
510 11 : static void __osl_destroySocketAddr( oslSocketAddr addr )
511 : {
512 : #if OSL_DEBUG_LEVEL > 1
513 : g_nSocketAddr --;
514 : #endif
515 11 : rtl_freeMemory( addr );
516 11 : }
517 :
518 0 : oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
519 : {
520 0 : oslSocketAddr pAddr = 0;
521 :
522 : /* is it an internet-Addr? */
523 0 : if (Family == osl_Socket_FamilyInet)
524 : {
525 0 : pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
526 : }
527 : else
528 : {
529 0 : pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
530 : }
531 :
532 0 : return pAddr;
533 : }
534 :
535 0 : oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
536 : {
537 0 : oslSocketAddr pCopy = 0;
538 0 : if (Addr)
539 : {
540 0 : pCopy = __osl_createSocketAddr();
541 :
542 0 : if (pCopy)
543 0 : memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
544 : }
545 0 : return pCopy;
546 : }
547 :
548 0 : sal_Bool SAL_CALL osl_isEqualSocketAddr (
549 : oslSocketAddr Addr1,
550 : oslSocketAddr Addr2)
551 : {
552 0 : struct sockaddr* pAddr1 = NULL;
553 0 : struct sockaddr* pAddr2 = NULL;
554 :
555 : assert(Addr1 && Addr2);
556 0 : pAddr1 = &(Addr1->m_sockaddr);
557 0 : pAddr2 = &(Addr2->m_sockaddr);
558 :
559 0 : if (pAddr1 == pAddr2)
560 : {
561 0 : return sal_True;
562 : }
563 :
564 0 : if (pAddr1->sa_family == pAddr2->sa_family)
565 : {
566 0 : switch (pAddr1->sa_family)
567 : {
568 : case AF_INET:
569 : {
570 0 : struct sockaddr_in* pInetAddr1= reinterpret_cast<sockaddr_in*>(pAddr1);
571 0 : struct sockaddr_in* pInetAddr2= reinterpret_cast<sockaddr_in*>(pAddr2);
572 :
573 0 : if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
574 0 : (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
575 0 : (pInetAddr1->sin_port == pInetAddr2->sin_port))
576 0 : return sal_True;
577 : }
578 :
579 : default:
580 : {
581 0 : return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
582 : }
583 : }
584 : }
585 :
586 0 : return sal_False;
587 : }
588 :
589 0 : oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
590 : rtl_uString *strDottedAddr,
591 : sal_Int32 Port)
592 : {
593 0 : sal_uInt32 nAddr = OSL_INADDR_NONE;
594 : oslSocketAddr pAddr;
595 :
596 0 : if (strDottedAddr && strDottedAddr->length)
597 : {
598 : /* Dotted host address for limited broadcast */
599 0 : rtl_String *pDottedAddr = NULL;
600 :
601 : rtl_uString2String (
602 : &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
603 0 : RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
604 :
605 0 : nAddr = inet_addr (pDottedAddr->buffer);
606 0 : rtl_string_release (pDottedAddr);
607 : }
608 :
609 0 : if (nAddr != OSL_INADDR_NONE)
610 : {
611 : /* Limited broadcast */
612 0 : nAddr = ntohl(nAddr);
613 0 : if (IN_CLASSA(nAddr))
614 : {
615 0 : nAddr &= IN_CLASSA_NET;
616 0 : nAddr |= IN_CLASSA_HOST;
617 : }
618 0 : else if (IN_CLASSB(nAddr))
619 : {
620 0 : nAddr &= IN_CLASSB_NET;
621 0 : nAddr |= IN_CLASSB_HOST;
622 : }
623 0 : else if (IN_CLASSC(nAddr))
624 : {
625 0 : nAddr &= IN_CLASSC_NET;
626 0 : nAddr |= IN_CLASSC_HOST;
627 : }
628 : else
629 : {
630 : /* No broadcast in class D */
631 0 : return nullptr;
632 : }
633 0 : nAddr = htonl(nAddr);
634 : }
635 :
636 0 : pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
637 0 : return pAddr;
638 : }
639 :
640 0 : oslSocketAddr SAL_CALL osl_createInetSocketAddr (
641 : rtl_uString *ustrDottedAddr,
642 : sal_Int32 Port)
643 : {
644 0 : rtl_String* strDottedAddr=0;
645 : oslSocketAddr Addr;
646 0 : sal_Char* pszDottedAddr=0;
647 :
648 0 : if ( ustrDottedAddr != 0 )
649 : {
650 : rtl_uString2String( &strDottedAddr,
651 0 : rtl_uString_getStr(ustrDottedAddr),
652 : rtl_uString_getLength(ustrDottedAddr),
653 : RTL_TEXTENCODING_UTF8,
654 0 : OUSTRING_TO_OSTRING_CVTFLAGS);
655 0 : pszDottedAddr = rtl_string_getStr(strDottedAddr);
656 : }
657 :
658 0 : Addr = pszDottedAddr ? osl_psz_createInetSocketAddr(pszDottedAddr, Port) : 0;
659 :
660 0 : if ( strDottedAddr != 0 )
661 : {
662 0 : rtl_string_release(strDottedAddr);
663 : }
664 :
665 0 : return Addr;
666 : }
667 :
668 0 : oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
669 : const sal_Char* pszDottedAddr,
670 : sal_Int32 Port)
671 : {
672 0 : oslSocketAddr pAddr = 0;
673 0 : sal_Int32 Addr = inet_addr(pszDottedAddr);
674 0 : if(Addr != -1)
675 : {
676 : /* valid dotted addr */
677 0 : pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
678 : }
679 0 : return pAddr;
680 : }
681 :
682 0 : oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
683 : {
684 0 : oslSocketResult res = osl_Socket_Error;
685 :
686 : SAL_WARN_IF( !pAddr, "sal.osl", "setting address of undefined socket address" );
687 : SAL_WARN_IF( !pByteSeq, "sal.osl", "setting undefined address for socket address" );
688 :
689 0 : if( pAddr && pByteSeq )
690 : {
691 : struct sockaddr_in * pSystemInetAddr;
692 :
693 : assert( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
694 : assert( pByteSeq->nElements == 4 );
695 :
696 0 : pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
697 0 : memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
698 0 : res = osl_Socket_Ok;
699 : }
700 0 : return res;
701 : }
702 :
703 0 : oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
704 : {
705 0 : oslSocketResult res = osl_Socket_Error;
706 :
707 : SAL_WARN_IF( !pAddr, "sal.osl", "getting address of undefined socket address" );
708 : SAL_WARN_IF( !ppByteSeq, "sal.osl", "getting address to undefined address pointer" );
709 :
710 0 : if( pAddr && ppByteSeq )
711 : {
712 0 : struct sockaddr_in * pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
713 0 : rtl_byte_sequence_constructFromArray( ppByteSeq, reinterpret_cast<sal_Int8 *>(&pSystemInetAddr->sin_addr), 4);
714 0 : res = osl_Socket_Ok;
715 : }
716 0 : return res;
717 : }
718 :
719 : /** try to figure out a full-qualified hostname, by adding the current domain
720 : as given by the domainname program to the given hostname.
721 : This function MUST NOT call gethostbyname since pHostName already points
722 : to data returned by gethostname and would be garbled: use gethostname_r
723 : instead!
724 : */
725 :
726 : /* wrap around different interfaces to reentrant gethostbyname */
727 22 : static struct hostent* _osl_gethostbyname_r (
728 : const char *name, struct hostent *result,
729 : char *buffer, int buflen, int *h_errnop)
730 : {
731 : #if defined(LINUX) || defined(ANDROID) || defined(FREEBSD) || defined(DRAGONFLY)
732 : struct hostent *__result; /* will be the same as result */
733 : int __error;
734 : __error = gethostbyname_r (name, result, buffer, buflen,
735 22 : &__result, h_errnop);
736 22 : return __error ? NULL : __result ;
737 : #elif defined(AIX)
738 : *h_errnop = gethostbyname_r (name, result, (struct hostent_data *)buffer);
739 : (void)buflen;
740 : return *h_errnop ? NULL : result ;
741 : #else
742 : return gethostbyname_r( name, result, buffer, buflen, h_errnop);
743 : #endif
744 : }
745 :
746 11 : static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
747 : {
748 : struct hostent aHostByName;
749 : struct hostent *pHostByName;
750 : sal_Char pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
751 11 : sal_Char *pFullQualifiedName = NULL;
752 : int nErrorNo;
753 :
754 : pHostByName = _osl_gethostbyname_r (
755 : pHostName,
756 : &aHostByName, pQualifiedHostBuffer,
757 11 : sizeof(pQualifiedHostBuffer), &nErrorNo );
758 11 : if (pHostByName != NULL)
759 : {
760 11 : pFullQualifiedName = strdup(pHostByName->h_name);
761 : }
762 11 : return pFullQualifiedName;
763 : }
764 :
765 11 : static bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
766 : {
767 : /* a FQDN (aka 'hostname.domain.top_level_domain' )
768 : * is a name which contains a dot '.' in it ( would
769 : * match as well for 'hostname.' but is good enough
770 : * for now )*/
771 11 : return strchr( pHostName, (int)'.' ) != NULL;
772 : }
773 :
774 : struct oslHostAddrImpl
775 : {
776 : sal_Char *pHostName;
777 : oslSocketAddr pSockAddr;
778 : };
779 :
780 11 : static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
781 : {
782 11 : oslHostAddr pAddr= NULL;
783 11 : oslSocketAddr pSockAddr = 0;
784 :
785 : sal_Char *cn;
786 :
787 11 : if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
788 0 : return nullptr;
789 :
790 11 : if (_osl_isFullQualifiedDomainName(he->h_name))
791 : {
792 0 : cn= strdup(he->h_name);
793 : SAL_WARN_IF( !cn, "sal.osl", "insufficient memory" );
794 0 : if (cn == NULL)
795 0 : return nullptr;
796 : }
797 : else
798 : {
799 11 : cn =_osl_getFullQualifiedDomainName (he->h_name);
800 : SAL_WARN_IF( !cn, "sal.osl", "couldn't get full qualified domain name" );
801 11 : if (cn == NULL)
802 0 : return nullptr;
803 : }
804 :
805 11 : pSockAddr = __osl_createSocketAddr();
806 : SAL_WARN_IF( !pSockAddr, "sal.osl", "insufficient memory" );
807 11 : if (pSockAddr == NULL)
808 : {
809 0 : free(cn);
810 0 : return nullptr;
811 : }
812 :
813 11 : pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
814 11 : if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
815 : {
816 11 : struct sockaddr_in *sin= reinterpret_cast<sockaddr_in *>(&pSockAddr->m_sockaddr);
817 : memcpy (
818 : &(sin->sin_addr.s_addr),
819 11 : he->h_addr_list[0],
820 22 : he->h_length);
821 : }
822 : else
823 : {
824 : /* unknown address family */
825 : /* future extensions for new families might be implemented here */
826 :
827 : SAL_WARN( "sal.osl", "unknown address family" );
828 :
829 0 : __osl_destroySocketAddr( pSockAddr );
830 0 : free (cn);
831 0 : return nullptr;
832 : }
833 :
834 11 : pAddr= static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
835 : SAL_WARN_IF( !pAddr, "sal.osl", "allocation error" );
836 11 : if (pAddr == NULL)
837 : {
838 0 : __osl_destroySocketAddr( pSockAddr );
839 0 : free (cn);
840 0 : return nullptr;
841 : }
842 :
843 11 : pAddr->pHostName= cn;
844 11 : pAddr->pSockAddr= pSockAddr;
845 :
846 11 : return pAddr;
847 : }
848 :
849 0 : oslHostAddr SAL_CALL osl_createHostAddr (
850 : rtl_uString *ustrHostname,
851 : const oslSocketAddr Addr)
852 : {
853 : oslHostAddr HostAddr;
854 0 : rtl_String* strHostname=0;
855 0 : sal_Char* pszHostName=0;
856 :
857 0 : if ( ustrHostname != 0 )
858 : {
859 : rtl_uString2String( &strHostname,
860 0 : rtl_uString_getStr(ustrHostname),
861 : rtl_uString_getLength(ustrHostname),
862 : RTL_TEXTENCODING_UTF8,
863 0 : OUSTRING_TO_OSTRING_CVTFLAGS );
864 0 : pszHostName = rtl_string_getStr(strHostname);
865 : }
866 :
867 0 : HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
868 :
869 0 : if ( strHostname != 0 )
870 : {
871 0 : rtl_string_release(strHostname);
872 : }
873 :
874 0 : return HostAddr;
875 : }
876 :
877 0 : oslHostAddr SAL_CALL osl_psz_createHostAddr (
878 : const sal_Char *pszHostname,
879 : const oslSocketAddr pAddr)
880 : {
881 : oslHostAddr pHostAddr;
882 : sal_Char *cn;
883 :
884 : SAL_WARN_IF( !pszHostname, "sal.osl", "undefined hostname" );
885 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
886 0 : if ((pszHostname == NULL) || (pAddr == NULL))
887 0 : return nullptr;
888 :
889 0 : cn = strdup(pszHostname);
890 : SAL_WARN_IF( !cn, "sal.osl", "insufficient memory" );
891 0 : if (cn == NULL)
892 0 : return nullptr;
893 :
894 0 : pHostAddr= static_cast<oslHostAddr>(malloc(sizeof(struct oslHostAddrImpl)));
895 : SAL_WARN_IF( !pHostAddr, "sal.osl", "allocation error" );
896 0 : if (pHostAddr == NULL)
897 : {
898 0 : free (cn);
899 0 : return nullptr;
900 : }
901 :
902 0 : pHostAddr->pHostName= cn;
903 0 : pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
904 :
905 0 : return pHostAddr;
906 : }
907 :
908 0 : oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
909 : {
910 : oslHostAddr HostAddr;
911 0 : rtl_String* strHostname=0;
912 0 : sal_Char* pszHostName=0;
913 :
914 0 : if ( ustrHostname != 0 )
915 : {
916 : rtl_uString2String( &strHostname,
917 0 : rtl_uString_getStr(ustrHostname),
918 : rtl_uString_getLength(ustrHostname),
919 : RTL_TEXTENCODING_UTF8,
920 0 : OUSTRING_TO_OSTRING_CVTFLAGS );
921 0 : pszHostName=rtl_string_getStr(strHostname);
922 : }
923 :
924 0 : HostAddr = osl_psz_createHostAddrByName(pszHostName);
925 :
926 0 : if ( strHostname != 0 )
927 : {
928 0 : rtl_string_release(strHostname);
929 : }
930 :
931 0 : return HostAddr;
932 : }
933 :
934 11 : oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
935 : {
936 : struct hostent aHe;
937 : struct hostent *pHe;
938 : sal_Char heBuffer[ MAX_HOSTBUFFER_SIZE ];
939 : int nErrorNo;
940 :
941 : pHe = _osl_gethostbyname_r (
942 : pszHostname,
943 : &aHe, heBuffer,
944 11 : sizeof(heBuffer), &nErrorNo );
945 :
946 11 : return _osl_hostentToHostAddr (pHe);
947 : }
948 :
949 0 : oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
950 : {
951 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
952 :
953 0 : if (pAddr == NULL)
954 0 : return nullptr;
955 :
956 0 : if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
957 : {
958 0 : const struct sockaddr_in *sin= reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
959 : struct hostent *he;
960 :
961 0 : if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
962 0 : return nullptr;
963 :
964 0 : char const * addr = reinterpret_cast<char const *>(&sin->sin_addr);
965 : // at least some Androids apparently have a gethostbyaddr with char*
966 : // instead of void* argument
967 : he= gethostbyaddr(addr,
968 : sizeof (sin->sin_addr),
969 0 : sin->sin_family);
970 0 : return _osl_hostentToHostAddr (he);
971 : }
972 :
973 0 : return nullptr;
974 : }
975 :
976 0 : oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
977 : {
978 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
979 :
980 0 : if (pAddr)
981 0 : return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
982 : else
983 0 : return nullptr;
984 : }
985 :
986 0 : void SAL_CALL osl_getHostnameOfHostAddr (
987 : const oslHostAddr Addr,
988 : rtl_uString **ustrHostname)
989 : {
990 0 : const sal_Char* pHostname=0;
991 :
992 0 : pHostname = osl_psz_getHostnameOfHostAddr(Addr);
993 :
994 0 : rtl_uString_newFromAscii (ustrHostname, pHostname);
995 :
996 0 : return;
997 : }
998 :
999 11 : const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1000 : {
1001 11 : if (pAddr)
1002 11 : return pAddr->pHostName;
1003 : else
1004 0 : return NULL;
1005 : }
1006 :
1007 0 : oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1008 : {
1009 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1010 :
1011 0 : if (pAddr)
1012 0 : return pAddr->pSockAddr;
1013 : else
1014 0 : return NULL;
1015 : }
1016 :
1017 11 : void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1018 : {
1019 11 : if (pAddr)
1020 : {
1021 11 : if (pAddr->pHostName)
1022 11 : free (pAddr->pHostName);
1023 11 : if (pAddr->pSockAddr)
1024 11 : osl_destroySocketAddr (pAddr->pSockAddr);
1025 11 : free (pAddr);
1026 : }
1027 11 : }
1028 :
1029 64 : oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1030 : {
1031 : oslSocketResult Result;
1032 : sal_Char pszHostname[1024];
1033 :
1034 64 : pszHostname[0] = '\0';
1035 :
1036 64 : Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1037 :
1038 64 : rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1039 :
1040 64 : return Result;
1041 : }
1042 :
1043 64 : oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1044 : sal_Char *pBuffer, sal_uInt32 nBufLen)
1045 : {
1046 : static sal_Char LocalHostname[256] = "";
1047 :
1048 64 : if (strlen(LocalHostname) == 0)
1049 : {
1050 :
1051 : #ifdef SYSV
1052 : struct utsname uts;
1053 :
1054 : if (uname(&uts) < 0)
1055 : return osl_Socket_Error;
1056 :
1057 : if ((strlen(uts.nodename) + 1) > nBufLen)
1058 : return osl_Socket_Error;
1059 :
1060 : strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1061 : #else /* BSD compatible */
1062 11 : if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1063 0 : return osl_Socket_Error;
1064 : #endif /* SYSV */
1065 11 : LocalHostname[sizeof(LocalHostname)-1] = 0;
1066 :
1067 : /* check if we have an FQDN */
1068 11 : if (strchr(LocalHostname, '.') == NULL)
1069 : {
1070 : oslHostAddr Addr;
1071 :
1072 : /* no, determine it via dns */
1073 11 : Addr = osl_psz_createHostAddrByName(LocalHostname);
1074 :
1075 : const sal_Char *pStr;
1076 11 : if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1077 : {
1078 11 : strncpy(LocalHostname, pStr, sizeof( LocalHostname ));
1079 11 : LocalHostname[sizeof(LocalHostname)-1] = 0;
1080 : }
1081 11 : osl_destroyHostAddr(Addr);
1082 : }
1083 : }
1084 :
1085 64 : if (strlen(LocalHostname) > 0)
1086 : {
1087 64 : strncpy(pBuffer, LocalHostname, nBufLen);
1088 64 : pBuffer[nBufLen - 1] = '\0';
1089 :
1090 64 : return osl_Socket_Ok;
1091 : }
1092 :
1093 0 : return osl_Socket_Error;
1094 : }
1095 :
1096 0 : oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1097 : {
1098 : oslSocketAddr Addr;
1099 0 : rtl_String* strHostname=0;
1100 0 : sal_Char* pszHostName=0;
1101 :
1102 0 : if ( ustrHostname != 0 )
1103 : {
1104 : rtl_uString2String( &strHostname,
1105 0 : rtl_uString_getStr(ustrHostname),
1106 : rtl_uString_getLength(ustrHostname),
1107 : RTL_TEXTENCODING_UTF8,
1108 0 : OUSTRING_TO_OSTRING_CVTFLAGS );
1109 0 : pszHostName = rtl_string_getStr(strHostname);
1110 : }
1111 :
1112 0 : Addr = osl_psz_resolveHostname(pszHostName);
1113 :
1114 0 : if ( strHostname != 0 )
1115 : {
1116 0 : rtl_string_release(strHostname);
1117 : }
1118 :
1119 0 : return Addr;
1120 : }
1121 :
1122 0 : oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1123 : {
1124 0 : struct oslHostAddrImpl *pAddr = osl_psz_createHostAddrByName(pszHostname);
1125 :
1126 0 : if (pAddr)
1127 : {
1128 0 : oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1129 :
1130 0 : osl_destroyHostAddr(pAddr);
1131 :
1132 0 : return SockAddr;
1133 : }
1134 :
1135 0 : return nullptr;
1136 : }
1137 :
1138 0 : sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1139 : {
1140 : sal_Int32 nPort;
1141 0 : rtl_String* strServicename=0;
1142 0 : rtl_String* strProtocol=0;
1143 0 : sal_Char* pszServiceName=0;
1144 0 : sal_Char* pszProtocol=0;
1145 :
1146 0 : if ( ustrServicename != 0 )
1147 : {
1148 : rtl_uString2String( &strServicename,
1149 0 : rtl_uString_getStr(ustrServicename),
1150 : rtl_uString_getLength(ustrServicename),
1151 : RTL_TEXTENCODING_UTF8,
1152 0 : OUSTRING_TO_OSTRING_CVTFLAGS );
1153 0 : pszServiceName = rtl_string_getStr(strServicename);
1154 : }
1155 :
1156 0 : if ( ustrProtocol != 0 )
1157 : {
1158 : rtl_uString2String( &strProtocol,
1159 0 : rtl_uString_getStr(ustrProtocol),
1160 : rtl_uString_getLength(ustrProtocol),
1161 : RTL_TEXTENCODING_UTF8,
1162 0 : OUSTRING_TO_OSTRING_CVTFLAGS );
1163 0 : pszProtocol = rtl_string_getStr(strProtocol);
1164 : }
1165 :
1166 0 : nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1167 :
1168 0 : if ( strServicename != 0 )
1169 : {
1170 0 : rtl_string_release(strServicename);
1171 : }
1172 :
1173 0 : if ( strProtocol != 0 )
1174 : {
1175 0 : rtl_string_release(strProtocol);
1176 : }
1177 :
1178 0 : return nPort;
1179 : }
1180 :
1181 0 : sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1182 : const sal_Char* pszProtocol)
1183 : {
1184 : struct servent* ps;
1185 :
1186 0 : ps= getservbyname(pszServicename, pszProtocol);
1187 :
1188 0 : if (ps != 0)
1189 0 : return ntohs(ps->s_port);
1190 :
1191 0 : return OSL_INVALID_PORT;
1192 : }
1193 :
1194 11 : void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1195 : {
1196 11 : __osl_destroySocketAddr( pAddr );
1197 11 : }
1198 :
1199 0 : oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1200 : {
1201 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1202 :
1203 0 : if (pAddr)
1204 0 : return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1205 : else
1206 0 : return osl_Socket_FamilyInvalid;
1207 : }
1208 :
1209 0 : sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1210 : {
1211 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1212 :
1213 0 : if( pAddr )
1214 : {
1215 0 : struct sockaddr_in* pSystemInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
1216 :
1217 0 : if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1218 0 : return ntohs(pSystemInetAddr->sin_port);
1219 : }
1220 0 : return OSL_INVALID_PORT;
1221 : }
1222 :
1223 0 : sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1224 : {
1225 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1226 :
1227 0 : if( pAddr )
1228 : {
1229 0 : struct sockaddr_in* pSystemInetAddr= reinterpret_cast<sockaddr_in*>(&pAddr->m_sockaddr);
1230 0 : if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1231 : {
1232 0 : pSystemInetAddr->sin_port= htons((short)Port);
1233 0 : return sal_True;
1234 : }
1235 : }
1236 :
1237 : /* this is not a inet-addr => can't set port */
1238 0 : return sal_False;
1239 : }
1240 :
1241 0 : oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1242 : {
1243 : oslSocketResult Result;
1244 : sal_Char pszHostname[1024];
1245 :
1246 0 : pszHostname[0] = '\0';
1247 :
1248 0 : Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1249 :
1250 0 : rtl_uString_newFromAscii(ustrHostname,pszHostname);
1251 :
1252 0 : return Result;
1253 : }
1254 :
1255 0 : oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1256 : sal_Char *pBuffer, sal_uInt32 BufferSize)
1257 : {
1258 0 : oslHostAddr pHostAddr= osl_createHostAddrByAddr(pAddr);
1259 :
1260 0 : if (pHostAddr)
1261 : {
1262 0 : strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1263 0 : pBuffer[BufferSize - 1] = '\0';
1264 :
1265 0 : osl_destroyHostAddr(pHostAddr);
1266 :
1267 0 : return osl_Socket_Ok;
1268 : }
1269 :
1270 0 : return osl_Socket_Error;
1271 : }
1272 :
1273 : /*****************************************************************************/
1274 : /* osl_getDottedInetAddrOfSocketAddr */
1275 : /*****************************************************************************/
1276 0 : oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1277 : {
1278 : oslSocketResult Result;
1279 : sal_Char pszDottedInetAddr[1024];
1280 :
1281 0 : pszDottedInetAddr[0] = '\0';
1282 :
1283 0 : Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1284 :
1285 0 : rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1286 :
1287 0 : return Result;
1288 :
1289 : }
1290 :
1291 0 : oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1292 : sal_Char *pBuffer, sal_uInt32 BufferSize)
1293 : {
1294 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1295 :
1296 0 : if( pAddr )
1297 : {
1298 0 : struct sockaddr_in* pSystemInetAddr = reinterpret_cast<sockaddr_in *>(&pAddr->m_sockaddr);
1299 :
1300 0 : if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1301 : {
1302 0 : strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1303 0 : pBuffer[BufferSize - 1] = '\0';
1304 :
1305 0 : return osl_Socket_Ok;
1306 : }
1307 : }
1308 :
1309 0 : return osl_Socket_Error;
1310 : }
1311 :
1312 0 : oslSocket SAL_CALL osl_createSocket(oslAddrFamily Family,
1313 : oslSocketType Type,
1314 : oslProtocol Protocol)
1315 : {
1316 : int Flags;
1317 : oslSocket pSocket;
1318 :
1319 : /* alloc memory */
1320 0 : pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1321 :
1322 : /* create socket */
1323 0 : pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1324 0 : TYPE_TO_NATIVE(Type),
1325 0 : PROTOCOL_TO_NATIVE(Protocol));
1326 :
1327 : /* creation failed => free memory */
1328 0 : if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1329 : {
1330 0 : int nErrno = errno;
1331 : SAL_WARN( "sal.osl", "socket creation failed: (" << nErrno << ") " << strerror(nErrno) );
1332 :
1333 0 : __osl_destroySocketImpl((pSocket));
1334 0 : pSocket= 0;
1335 : }
1336 : else
1337 : {
1338 : /* set close-on-exec flag */
1339 0 : if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1340 : {
1341 0 : Flags |= FD_CLOEXEC;
1342 0 : if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1343 : {
1344 0 : pSocket->m_nLastError=errno;
1345 0 : int nErrno = errno;
1346 : SAL_WARN( "sal.osl", "failed changing socket flags: (" << nErrno << ") " << strerror(nErrno) );
1347 : }
1348 : }
1349 : else
1350 : {
1351 0 : pSocket->m_nLastError=errno;
1352 : }
1353 : }
1354 :
1355 0 : return pSocket;
1356 : }
1357 :
1358 0 : void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1359 : {
1360 0 : osl_atomic_increment( &(pSocket->m_nRefCount ) );
1361 0 : }
1362 :
1363 0 : void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1364 : {
1365 0 : if( pSocket && 0 == osl_atomic_decrement( &(pSocket->m_nRefCount) ) )
1366 : {
1367 : #if defined(LINUX)
1368 0 : if ( pSocket->m_bIsAccepting )
1369 : {
1370 : SAL_WARN( "sal.osl", "attempt to destroy socket while accepting" );
1371 0 : return;
1372 : }
1373 : #endif /* LINUX */
1374 0 : osl_closeSocket( pSocket );
1375 0 : __osl_destroySocketImpl( pSocket );
1376 : }
1377 : }
1378 :
1379 0 : void SAL_CALL osl_closeSocket(oslSocket pSocket)
1380 : {
1381 : int nRet;
1382 : int nFD;
1383 :
1384 : /* socket already invalid */
1385 0 : if(pSocket==0)
1386 0 : return;
1387 :
1388 0 : pSocket->m_nLastError=0;
1389 0 : nFD = pSocket->m_Socket;
1390 :
1391 0 : if (nFD == OSL_INVALID_SOCKET)
1392 0 : return;
1393 :
1394 0 : pSocket->m_Socket = OSL_INVALID_SOCKET;
1395 :
1396 : #if defined(LINUX)
1397 0 : pSocket->m_bIsInShutdown = true;
1398 :
1399 0 : if ( pSocket->m_bIsAccepting )
1400 : {
1401 : union {
1402 : struct sockaddr aSockAddr;
1403 : struct sockaddr_in aSockAddrIn;
1404 : } s;
1405 0 : socklen_t nSockLen = sizeof(s.aSockAddr);
1406 :
1407 0 : nRet = getsockname(nFD, &s.aSockAddr, &nSockLen);
1408 0 : if ( nRet < 0 )
1409 : {
1410 0 : int nErrno = errno;
1411 : SAL_WARN( "sal.osl", "getsockname call failed with error: (" << nErrno << ") " << strerror(nErrno) );
1412 : }
1413 :
1414 0 : if ( s.aSockAddr.sa_family == AF_INET )
1415 : {
1416 0 : if ( s.aSockAddrIn.sin_addr.s_addr == htonl(INADDR_ANY) )
1417 : {
1418 0 : s.aSockAddrIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1419 : }
1420 :
1421 0 : int nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1422 0 : if ( nConnFD < 0 )
1423 : {
1424 0 : int nErrno = errno;
1425 : SAL_WARN( "sal.osl", "socket call failed with error: (" << nErrno << ") " << strerror(nErrno) );
1426 : }
1427 : else
1428 : {
1429 0 : nRet = connect(nConnFD, &s.aSockAddr, sizeof(s.aSockAddr));
1430 0 : if ( nRet < 0 )
1431 : {
1432 0 : int nErrno = errno;
1433 : SAL_WARN( "sal.osl", "connect call failed with error: (" << nErrno << ") " << strerror(nErrno) );
1434 : }
1435 0 : close(nConnFD);
1436 : }
1437 : }
1438 0 : pSocket->m_bIsAccepting = false;
1439 : }
1440 : #endif /* LINUX */
1441 :
1442 0 : nRet=close(nFD);
1443 0 : if ( nRet != 0 )
1444 : {
1445 0 : pSocket->m_nLastError=errno;
1446 0 : int nErrno = errno;
1447 : SAL_WARN( "sal.osl", "closeSocket close error: (" << nErrno << ") " << strerror(nErrno) );
1448 : }
1449 :
1450 0 : pSocket->m_Socket = OSL_INVALID_SOCKET;
1451 : }
1452 :
1453 : /*****************************************************************************/
1454 : /* osl_getLocalAddrOfSocket */
1455 : /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1456 : /* are the same! I don't like it very much but see no other easy way to conceal */
1457 : /* the struct sockaddr from the eyes of the user. */
1458 : /*****************************************************************************/
1459 0 : oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1460 : {
1461 : socklen_t AddrLen;
1462 : struct sockaddr Addr;
1463 : oslSocketAddr pAddr;
1464 :
1465 0 : if (pSocket == NULL) /* ENOTSOCK */
1466 0 : return nullptr;
1467 :
1468 0 : AddrLen= sizeof(struct sockaddr);
1469 :
1470 0 : if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1471 0 : return nullptr;
1472 :
1473 0 : pAddr = __osl_createSocketAddrFromSystem( &Addr );
1474 0 : return pAddr;
1475 : }
1476 :
1477 0 : oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1478 : {
1479 : socklen_t AddrLen;
1480 : struct sockaddr Addr;
1481 :
1482 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1483 0 : if ( pSocket == 0 )
1484 : {
1485 0 : return 0;
1486 : }
1487 :
1488 0 : pSocket->m_nLastError=0;
1489 0 : AddrLen= sizeof(struct sockaddr);
1490 :
1491 0 : if(getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1492 : {
1493 0 : pSocket->m_nLastError=errno;
1494 0 : return 0;
1495 : }
1496 0 : return __osl_createSocketAddrFromSystem( &Addr );
1497 : }
1498 :
1499 0 : sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
1500 : oslSocketAddr pAddr)
1501 : {
1502 : int nRet;
1503 :
1504 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1505 : SAL_WARN_IF( !pAddr, "sal.osl", "undefined address" );
1506 0 : if ( pSocket == 0 || pAddr == 0 )
1507 : {
1508 0 : return sal_False;
1509 : }
1510 :
1511 0 : pSocket->m_nLastError=0;
1512 :
1513 0 : nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1514 :
1515 0 : if ( nRet == OSL_SOCKET_ERROR)
1516 : {
1517 0 : pSocket->m_nLastError=errno;
1518 0 : return sal_False;
1519 : }
1520 :
1521 0 : return sal_True;
1522 : }
1523 :
1524 0 : sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
1525 : sal_Int32 MaxPendingConnections)
1526 : {
1527 : int nRet;
1528 :
1529 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1530 0 : if ( pSocket == 0 )
1531 : {
1532 0 : return sal_False;
1533 : }
1534 :
1535 0 : pSocket->m_nLastError=0;
1536 :
1537 : nRet = listen(pSocket->m_Socket,
1538 : MaxPendingConnections == -1 ?
1539 : SOMAXCONN :
1540 0 : MaxPendingConnections);
1541 0 : if ( nRet == OSL_SOCKET_ERROR)
1542 : {
1543 0 : pSocket->m_nLastError=errno;
1544 0 : return sal_False;
1545 : }
1546 :
1547 0 : return sal_True;
1548 : }
1549 :
1550 0 : oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
1551 : oslSocketAddr pAddr,
1552 : const TimeValue* pTimeout)
1553 : {
1554 : fd_set WriteSet;
1555 : fd_set ExcptSet;
1556 : int ReadyHandles;
1557 : struct timeval tv;
1558 0 : oslSocketResult Result= osl_Socket_Ok;
1559 :
1560 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1561 :
1562 0 : if ( pSocket == 0 )
1563 : {
1564 0 : return osl_Socket_Error;
1565 : }
1566 :
1567 0 : pSocket->m_nLastError=0;
1568 :
1569 0 : if (osl_isNonBlockingMode(pSocket))
1570 : {
1571 0 : if (connect(pSocket->m_Socket,
1572 : &(pAddr->m_sockaddr),
1573 0 : sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1574 0 : return osl_Socket_Ok;
1575 : else
1576 0 : if (errno == EWOULDBLOCK || errno == EINPROGRESS)
1577 : {
1578 0 : pSocket->m_nLastError=EINPROGRESS;
1579 0 : return osl_Socket_InProgress;
1580 : }
1581 :
1582 0 : pSocket->m_nLastError=errno;
1583 0 : int nErrno = errno;
1584 : SAL_WARN( "sal.osl", "connection failed: (" << nErrno << ") " << strerror(nErrno) );
1585 0 : return osl_Socket_Error;
1586 : }
1587 :
1588 : /* set socket temporarily to non-blocking */
1589 0 : if( !osl_enableNonBlockingMode(pSocket, sal_True) )
1590 : SAL_WARN( "sal.osl", "failed to enable non-blocking mode" );
1591 :
1592 : /* initiate connect */
1593 0 : if(connect(pSocket->m_Socket,
1594 : &(pAddr->m_sockaddr),
1595 0 : sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1596 : {
1597 : /* immediate connection */
1598 0 : osl_enableNonBlockingMode(pSocket, sal_False);
1599 :
1600 0 : return osl_Socket_Ok;
1601 : }
1602 : else
1603 : {
1604 : /* really an error or just delayed? */
1605 0 : if (errno != EINPROGRESS)
1606 : {
1607 0 : pSocket->m_nLastError=errno;
1608 0 : int nErrno = errno;
1609 : SAL_WARN( "sal.osl", "connection failed: (" << nErrno << ") " << strerror(nErrno) );
1610 :
1611 0 : osl_enableNonBlockingMode(pSocket, sal_False);
1612 0 : return osl_Socket_Error;
1613 : }
1614 : }
1615 :
1616 : /* prepare select set for socket */
1617 0 : FD_ZERO(&WriteSet);
1618 0 : FD_ZERO(&ExcptSet);
1619 0 : FD_SET(pSocket->m_Socket, &WriteSet);
1620 0 : FD_SET(pSocket->m_Socket, &ExcptSet);
1621 :
1622 : /* prepare timeout */
1623 0 : if (pTimeout)
1624 : {
1625 : /* divide milliseconds into seconds and microseconds */
1626 0 : tv.tv_sec= pTimeout->Seconds;
1627 0 : tv.tv_usec= pTimeout->Nanosec / 1000L;
1628 : }
1629 :
1630 : /* select */
1631 : ReadyHandles= select(pSocket->m_Socket+1,
1632 : 0,
1633 : PTR_FD_SET(WriteSet),
1634 : PTR_FD_SET(ExcptSet),
1635 0 : (pTimeout) ? &tv : 0);
1636 :
1637 0 : if (ReadyHandles > 0) /* connected */
1638 : {
1639 0 : if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
1640 : {
1641 0 : int nErrorCode = 0;
1642 0 : socklen_t nErrorSize = sizeof( nErrorCode );
1643 :
1644 : int nSockOpt;
1645 :
1646 : nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
1647 0 : &nErrorCode, &nErrorSize );
1648 0 : if ( (nSockOpt == 0) && (nErrorCode == 0))
1649 0 : Result = osl_Socket_Ok;
1650 : else
1651 0 : Result = osl_Socket_Error;
1652 : }
1653 : else
1654 : {
1655 0 : Result= osl_Socket_Error;
1656 : }
1657 : }
1658 0 : else if (ReadyHandles < 0) /* error */
1659 : {
1660 0 : if (errno == EBADF) /* most probably interrupted by close() */
1661 : {
1662 : /* do not access pSockImpl because it is about to be or */
1663 : /* already destroyed */
1664 0 : return osl_Socket_Interrupted;
1665 : }
1666 : else
1667 : {
1668 0 : pSocket->m_nLastError=errno;
1669 0 : Result= osl_Socket_Error;
1670 : }
1671 : }
1672 : else /* timeout */
1673 : {
1674 0 : pSocket->m_nLastError=errno;
1675 0 : Result= osl_Socket_TimedOut;
1676 : }
1677 :
1678 0 : osl_enableNonBlockingMode(pSocket, sal_False);
1679 :
1680 0 : return Result;
1681 : }
1682 :
1683 0 : oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
1684 : oslSocketAddr* ppAddr)
1685 : {
1686 : struct sockaddr Addr;
1687 : int Connection, Flags;
1688 : oslSocket pConnectionSockImpl;
1689 :
1690 0 : socklen_t AddrLen = sizeof(struct sockaddr);
1691 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1692 0 : if ( pSocket == 0 )
1693 : {
1694 0 : return 0;
1695 : }
1696 :
1697 0 : pSocket->m_nLastError=0;
1698 : #if defined(LINUX)
1699 0 : pSocket->m_bIsAccepting = true;
1700 : #endif /* LINUX */
1701 :
1702 0 : if( ppAddr && *ppAddr )
1703 : {
1704 0 : osl_destroySocketAddr( *ppAddr );
1705 0 : *ppAddr = 0;
1706 : }
1707 :
1708 : /* prevent Linux EINTR behaviour */
1709 0 : do
1710 : {
1711 0 : Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
1712 0 : } while (Connection == -1 && errno == EINTR);
1713 :
1714 : /* accept failed? */
1715 0 : if( Connection == OSL_SOCKET_ERROR )
1716 : {
1717 0 : pSocket->m_nLastError=errno;
1718 0 : int nErrno = errno;
1719 : SAL_WARN( "sal.osl", "accept connection failed: (" << nErrno << ") " << strerror(nErrno) );
1720 :
1721 : #if defined(LINUX)
1722 0 : pSocket->m_bIsAccepting = false;
1723 : #endif /* LINUX */
1724 0 : return 0;
1725 : }
1726 :
1727 : assert(AddrLen == sizeof(struct sockaddr));
1728 :
1729 : #if defined(LINUX)
1730 0 : if ( pSocket->m_bIsInShutdown )
1731 : {
1732 0 : close(Connection);
1733 : SAL_WARN( "sal.osl", "close while accept" );
1734 0 : return 0;
1735 : }
1736 : #endif /* LINUX */
1737 :
1738 0 : if(ppAddr)
1739 : {
1740 0 : *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
1741 : }
1742 :
1743 : /* alloc memory */
1744 0 : pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1745 :
1746 : /* set close-on-exec flag */
1747 0 : if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
1748 : {
1749 0 : Flags |= FD_CLOEXEC;
1750 0 : if (fcntl(Connection, F_SETFD, Flags) == -1)
1751 : {
1752 0 : pSocket->m_nLastError=errno;
1753 0 : int nErrno = errno;
1754 : SAL_WARN( "sal.osl", "failed changing socket flags: (" << nErrno << ") " << strerror(nErrno) );
1755 : }
1756 :
1757 : }
1758 :
1759 0 : pConnectionSockImpl->m_Socket = Connection;
1760 0 : pConnectionSockImpl->m_nLastError = 0;
1761 : #if defined(LINUX)
1762 0 : pConnectionSockImpl->m_bIsAccepting = false;
1763 :
1764 0 : pSocket->m_bIsAccepting = false;
1765 : #endif /* LINUX */
1766 0 : return pConnectionSockImpl;
1767 : }
1768 :
1769 0 : sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
1770 : void* pBuffer,
1771 : sal_uInt32 BytesToRead,
1772 : oslSocketMsgFlag Flag)
1773 : {
1774 : int nRead;
1775 :
1776 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1777 0 : if ( pSocket == 0 )
1778 : {
1779 0 : return -1;
1780 : }
1781 :
1782 0 : pSocket->m_nLastError=0;
1783 :
1784 0 : do
1785 : {
1786 : nRead = recv(pSocket->m_Socket,
1787 : pBuffer,
1788 : BytesToRead,
1789 0 : MSG_FLAG_TO_NATIVE(Flag));
1790 0 : } while ( nRead < 0 && errno == EINTR );
1791 :
1792 0 : if ( nRead < 0 )
1793 : {
1794 0 : pSocket->m_nLastError=errno;
1795 0 : int nErrno = errno;
1796 : SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: (" << nErrno << ") " << strerror(nErrno) );
1797 : }
1798 0 : else if ( nRead == 0 )
1799 : {
1800 : SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: EOL" );
1801 : }
1802 :
1803 0 : return nRead;
1804 : }
1805 :
1806 0 : sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
1807 : oslSocketAddr pSenderAddr,
1808 : void* pBuffer,
1809 : sal_uInt32 BufferSize,
1810 : oslSocketMsgFlag Flag)
1811 : {
1812 : int nRead;
1813 0 : struct sockaddr *pSystemSockAddr = 0;
1814 0 : socklen_t AddrLen = 0;
1815 0 : if( pSenderAddr )
1816 : {
1817 0 : AddrLen = sizeof( struct sockaddr );
1818 0 : pSystemSockAddr = &(pSenderAddr->m_sockaddr);
1819 : }
1820 :
1821 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1822 0 : if ( pSocket == 0 )
1823 : {
1824 0 : return -1;
1825 : }
1826 :
1827 0 : pSocket->m_nLastError=0;
1828 :
1829 : nRead = recvfrom(pSocket->m_Socket,
1830 : pBuffer,
1831 : BufferSize,
1832 0 : MSG_FLAG_TO_NATIVE(Flag),
1833 : pSystemSockAddr,
1834 0 : &AddrLen);
1835 :
1836 0 : if ( nRead < 0 )
1837 : {
1838 0 : pSocket->m_nLastError=errno;
1839 0 : int nErrno = errno;
1840 : SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: (" << nErrno << ") " << strerror(nErrno) );
1841 : }
1842 0 : else if ( nRead == 0 )
1843 : {
1844 : SAL_WARN( "sal.osl", "receive socket [" << nRead << "] failed: EOL" );
1845 : }
1846 :
1847 0 : return nRead;
1848 : }
1849 :
1850 0 : sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
1851 : const void* pBuffer,
1852 : sal_uInt32 BytesToSend,
1853 : oslSocketMsgFlag Flag)
1854 : {
1855 : int nWritten;
1856 :
1857 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1858 0 : if ( pSocket == 0 )
1859 : {
1860 0 : return -1;
1861 : }
1862 :
1863 0 : pSocket->m_nLastError=0;
1864 :
1865 0 : do
1866 : {
1867 : nWritten = send(pSocket->m_Socket,
1868 : pBuffer,
1869 : BytesToSend,
1870 0 : MSG_FLAG_TO_NATIVE(Flag));
1871 0 : } while ( nWritten < 0 && errno == EINTR );
1872 :
1873 0 : if ( nWritten < 0 )
1874 : {
1875 0 : pSocket->m_nLastError=errno;
1876 0 : int nErrno = errno;
1877 : SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: (" << nErrno << ") " << strerror(nErrno) );
1878 : }
1879 0 : else if ( nWritten == 0 )
1880 : {
1881 : SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: EOL" );
1882 : }
1883 :
1884 0 : return nWritten;
1885 : }
1886 :
1887 0 : sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
1888 : oslSocketAddr ReceiverAddr,
1889 : const void* pBuffer,
1890 : sal_uInt32 BytesToSend,
1891 : oslSocketMsgFlag Flag)
1892 : {
1893 : int nWritten;
1894 :
1895 0 : struct sockaddr *pSystemSockAddr = 0;
1896 0 : int AddrLen = 0;
1897 0 : if( ReceiverAddr )
1898 : {
1899 0 : pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1900 0 : AddrLen = sizeof( struct sockaddr );
1901 : }
1902 :
1903 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1904 0 : if ( pSocket == 0 )
1905 : {
1906 0 : return -1;
1907 : }
1908 :
1909 0 : pSocket->m_nLastError=0;
1910 :
1911 : /* ReceiverAddr might be 0 when used on a connected socket. */
1912 : /* Then sendto should behave like send. */
1913 :
1914 : nWritten = sendto(pSocket->m_Socket,
1915 : pBuffer,
1916 : BytesToSend,
1917 0 : MSG_FLAG_TO_NATIVE(Flag),
1918 : pSystemSockAddr,
1919 0 : AddrLen);
1920 :
1921 0 : if ( nWritten < 0 )
1922 : {
1923 0 : pSocket->m_nLastError=errno;
1924 0 : int nErrno = errno;
1925 : SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: (" << nErrno << ") " << strerror(nErrno) );
1926 : }
1927 0 : else if ( nWritten == 0 )
1928 : {
1929 : SAL_WARN( "sal.osl", "send socket [" << nWritten << "] failed: EOL" );
1930 : }
1931 :
1932 0 : return nWritten;
1933 : }
1934 :
1935 0 : sal_Int32 SAL_CALL osl_readSocket (
1936 : oslSocket pSocket, void *pBuffer, sal_Int32 n )
1937 : {
1938 0 : sal_uInt8 * Ptr = static_cast<sal_uInt8 *>(pBuffer);
1939 0 : sal_uInt32 BytesRead= 0;
1940 0 : sal_uInt32 BytesToRead= n;
1941 :
1942 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1943 :
1944 : /* loop until all desired bytes were read or an error occurred */
1945 0 : while (BytesToRead > 0)
1946 : {
1947 : sal_Int32 RetVal;
1948 : RetVal= osl_receiveSocket(pSocket,
1949 : Ptr,
1950 : BytesToRead,
1951 0 : osl_Socket_MsgNormal);
1952 :
1953 : /* error occurred? */
1954 0 : if(RetVal <= 0)
1955 : {
1956 0 : break;
1957 : }
1958 :
1959 0 : BytesToRead -= RetVal;
1960 0 : BytesRead += RetVal;
1961 0 : Ptr += RetVal;
1962 : }
1963 :
1964 0 : return BytesRead;
1965 : }
1966 :
1967 0 : sal_Int32 SAL_CALL osl_writeSocket(
1968 : oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1969 : {
1970 : /* loop until all desired bytes were send or an error occurred */
1971 0 : sal_uInt32 BytesSend= 0;
1972 0 : sal_uInt32 BytesToSend= n;
1973 0 : sal_uInt8 const *Ptr = static_cast<sal_uInt8 const *>(pBuffer);
1974 :
1975 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
1976 :
1977 0 : while (BytesToSend > 0)
1978 : {
1979 : sal_Int32 RetVal;
1980 :
1981 0 : RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1982 :
1983 : /* error occurred? */
1984 0 : if(RetVal <= 0)
1985 : {
1986 0 : break;
1987 : }
1988 :
1989 0 : BytesToSend -= RetVal;
1990 0 : BytesSend += RetVal;
1991 0 : Ptr += RetVal;
1992 :
1993 : }
1994 0 : return BytesSend;
1995 : }
1996 :
1997 : #ifdef HAVE_POLL_H /* poll() */
1998 :
1999 0 : bool __osl_socket_poll (
2000 : oslSocket pSocket,
2001 : const TimeValue* pTimeout,
2002 : short nEvent)
2003 : {
2004 : struct pollfd fds;
2005 : int timeout;
2006 : int result;
2007 :
2008 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2009 0 : if (0 == pSocket)
2010 0 : return false; /* EINVAL */
2011 :
2012 0 : pSocket->m_nLastError = 0;
2013 :
2014 0 : fds.fd = pSocket->m_Socket;
2015 0 : fds.events = nEvent;
2016 0 : fds.revents = 0;
2017 :
2018 0 : timeout = -1;
2019 0 : if (pTimeout)
2020 : {
2021 : /* Convert to [ms] */
2022 0 : timeout = pTimeout->Seconds * 1000;
2023 0 : timeout += pTimeout->Nanosec / (1000 * 1000);
2024 : }
2025 :
2026 0 : result = poll (&fds, 1, timeout);
2027 0 : if (result < 0)
2028 : {
2029 0 : pSocket->m_nLastError = errno;
2030 0 : int nErrno = errno;
2031 : SAL_WARN( "sal.osl", "poll error: (" << nErrno << ") " << strerror(nErrno) );
2032 0 : return false;
2033 : }
2034 0 : if (result == 0)
2035 : {
2036 : /* Timeout */
2037 0 : return false;
2038 : }
2039 :
2040 0 : return ((fds.revents & nEvent) == nEvent);
2041 : }
2042 :
2043 : #else /* select() */
2044 :
2045 : sal_Bool __osl_socket_poll (
2046 : oslSocket pSocket,
2047 : const TimeValue* pTimeout,
2048 : short nEvent)
2049 : {
2050 : fd_set fds;
2051 : struct timeval tv;
2052 : int result;
2053 :
2054 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2055 : if (0 == pSocket)
2056 : return sal_False; /* EINVAL */
2057 :
2058 : pSocket->m_nLastError = 0;
2059 :
2060 : FD_ZERO(&fds);
2061 : FD_SET(pSocket->m_Socket, &fds);
2062 :
2063 : if (pTimeout)
2064 : {
2065 : /* Convert to 'timeval' */
2066 : tv.tv_sec = pTimeout->Seconds;
2067 : tv.tv_usec = pTimeout->Nanosec / 1000;
2068 : }
2069 :
2070 : result = select (
2071 : pSocket->m_Socket + 1,
2072 : (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2073 : (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2074 : (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2075 : (pTimeout) ? &tv : NULL);
2076 :
2077 : if (result < 0)
2078 : {
2079 : pSocket->m_nLastError = errno;
2080 : int nErrno = errno;
2081 : SAL_WARN( "sal.osl", "select error: (" << nErrno << ") " << strerror(nErrno) );
2082 : return sal_False;
2083 : }
2084 : if (result == 0)
2085 : {
2086 : /* Timeout */
2087 : return sal_False;
2088 : }
2089 :
2090 : return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2091 : }
2092 :
2093 : #endif /* HAVE_POLL_H */
2094 :
2095 0 : sal_Bool SAL_CALL osl_isReceiveReady (
2096 : oslSocket pSocket, const TimeValue* pTimeout)
2097 : {
2098 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2099 0 : if (pSocket == NULL)
2100 : {
2101 : /* ENOTSOCK */
2102 0 : return sal_False;
2103 : }
2104 :
2105 0 : return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2106 : }
2107 :
2108 0 : sal_Bool SAL_CALL osl_isSendReady (
2109 : oslSocket pSocket, const TimeValue* pTimeout)
2110 : {
2111 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2112 0 : if (pSocket == NULL)
2113 : {
2114 : /* ENOTSOCK */
2115 0 : return sal_False;
2116 : }
2117 :
2118 0 : return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2119 : }
2120 :
2121 0 : sal_Bool SAL_CALL osl_isExceptionPending (
2122 : oslSocket pSocket, const TimeValue* pTimeout)
2123 : {
2124 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2125 0 : if (pSocket == NULL)
2126 : {
2127 : /* ENOTSOCK */
2128 0 : return sal_False;
2129 : }
2130 :
2131 0 : return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2132 : }
2133 :
2134 0 : sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2135 : oslSocketDirection Direction)
2136 : {
2137 : int nRet;
2138 :
2139 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2140 0 : if ( pSocket == 0 )
2141 : {
2142 0 : return sal_False;
2143 : }
2144 :
2145 0 : pSocket->m_nLastError=0;
2146 :
2147 0 : nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2148 0 : if (nRet != 0 )
2149 : {
2150 0 : pSocket->m_nLastError=errno;
2151 0 : int nErrno = errno;
2152 : SAL_WARN( "sal.osl", "socket shutdown error: (" << nErrno << ") " << strerror(nErrno) );
2153 : }
2154 0 : return (nRet==0);
2155 : }
2156 :
2157 0 : sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2158 : oslSocketOptionLevel Level,
2159 : oslSocketOption Option,
2160 : void* pBuffer,
2161 : sal_uInt32 BufferLen)
2162 : {
2163 0 : socklen_t nOptLen = (socklen_t) BufferLen;
2164 :
2165 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2166 0 : if ( pSocket == 0 )
2167 : {
2168 0 : return -1;
2169 : }
2170 :
2171 0 : pSocket->m_nLastError=0;
2172 :
2173 0 : if(getsockopt(pSocket->m_Socket,
2174 0 : OPTION_LEVEL_TO_NATIVE(Level),
2175 0 : OPTION_TO_NATIVE(Option),
2176 : pBuffer,
2177 0 : &nOptLen) == -1)
2178 : {
2179 0 : pSocket->m_nLastError=errno;
2180 0 : return -1;
2181 : }
2182 :
2183 0 : return BufferLen;
2184 : }
2185 :
2186 0 : sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2187 : oslSocketOptionLevel Level,
2188 : oslSocketOption Option,
2189 : void* pBuffer,
2190 : sal_uInt32 BufferLen)
2191 : {
2192 : int nRet;
2193 :
2194 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2195 0 : if ( pSocket == 0 )
2196 : {
2197 0 : return sal_False;
2198 : }
2199 :
2200 0 : pSocket->m_nLastError=0;
2201 :
2202 : nRet = setsockopt(pSocket->m_Socket,
2203 0 : OPTION_LEVEL_TO_NATIVE(Level),
2204 0 : OPTION_TO_NATIVE(Option),
2205 : pBuffer,
2206 0 : BufferLen);
2207 :
2208 0 : if ( nRet < 0 )
2209 : {
2210 0 : pSocket->m_nLastError=errno;
2211 0 : return sal_False;
2212 : }
2213 :
2214 0 : return sal_True;
2215 : }
2216 :
2217 0 : sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2218 : sal_Bool On)
2219 : {
2220 : int flags;
2221 : int nRet;
2222 :
2223 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2224 0 : if ( pSocket == 0 )
2225 : {
2226 0 : return sal_False;
2227 : }
2228 :
2229 0 : pSocket->m_nLastError=0;
2230 :
2231 0 : flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2232 :
2233 0 : if (On)
2234 0 : flags |= O_NONBLOCK;
2235 : else
2236 0 : flags &= ~(O_NONBLOCK);
2237 :
2238 0 : nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2239 :
2240 0 : if ( nRet < 0 )
2241 : {
2242 0 : pSocket->m_nLastError=errno;
2243 0 : return sal_False;
2244 : }
2245 :
2246 0 : return sal_True;
2247 : }
2248 :
2249 0 : sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2250 : {
2251 : int flags;
2252 :
2253 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2254 0 : if ( pSocket == 0 )
2255 : {
2256 0 : return sal_False;
2257 : }
2258 :
2259 0 : pSocket->m_nLastError=0;
2260 :
2261 0 : flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2262 :
2263 0 : if (flags == -1 || !(flags & O_NONBLOCK))
2264 0 : return sal_False;
2265 : else
2266 0 : return sal_True;
2267 : }
2268 :
2269 0 : oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2270 : {
2271 0 : int Type=0;
2272 0 : socklen_t TypeSize= sizeof(Type);
2273 :
2274 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2275 0 : if ( pSocket == 0 )
2276 : {
2277 0 : return osl_Socket_TypeInvalid;
2278 : }
2279 :
2280 0 : pSocket->m_nLastError=0;
2281 :
2282 0 : if(getsockopt(pSocket->m_Socket,
2283 0 : OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2284 0 : OPTION_TO_NATIVE(osl_Socket_OptionType),
2285 : &Type,
2286 0 : &TypeSize) == -1)
2287 : {
2288 : /* error */
2289 0 : pSocket->m_nLastError=errno;
2290 0 : return osl_Socket_TypeInvalid;
2291 : }
2292 :
2293 0 : return TYPE_FROM_NATIVE(Type);
2294 :
2295 : }
2296 :
2297 0 : void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2298 : {
2299 : sal_Char pszError[1024];
2300 :
2301 0 : pszError[0] = '\0';
2302 :
2303 0 : osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2304 :
2305 0 : rtl_uString_newFromAscii(ustrError,pszError);
2306 :
2307 0 : return;
2308 : }
2309 :
2310 0 : void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2311 : {
2312 : /* make sure pBuffer will be a zero-terminated string even when strncpy has to cut */
2313 0 : pBuffer[BufferSize-1]= '\0';
2314 :
2315 0 : if ( pSocket == 0 )
2316 : {
2317 0 : strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2318 0 : return;
2319 : }
2320 :
2321 0 : strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2322 0 : return;
2323 : }
2324 :
2325 0 : oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2326 : {
2327 0 : if ( pSocket == 0 )
2328 : {
2329 0 : return ERROR_FROM_NATIVE(EINVAL);
2330 : }
2331 :
2332 0 : return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2333 : }
2334 :
2335 : struct oslSocketSetImpl
2336 : {
2337 : int m_MaxHandle; /* for select(), the largest descriptor in the set */
2338 : fd_set m_Set; /* the set of descriptors */
2339 :
2340 : };
2341 :
2342 0 : oslSocketSet SAL_CALL osl_createSocketSet()
2343 : {
2344 : oslSocketSetImpl* pSet;
2345 :
2346 0 : pSet= static_cast<oslSocketSetImpl*>(malloc(sizeof(oslSocketSetImpl)));
2347 :
2348 : SAL_WARN_IF( !pSet, "sal.osl", "allocation error" );
2349 :
2350 0 : if(pSet)
2351 : {
2352 0 : pSet->m_MaxHandle= 0;
2353 0 : FD_ZERO(&pSet->m_Set);
2354 : }
2355 :
2356 0 : return pSet;
2357 : }
2358 :
2359 0 : void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2360 : {
2361 0 : if(Set)
2362 0 : free(Set);
2363 0 : }
2364 :
2365 0 : void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2366 : {
2367 : SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2368 0 : if ( Set == 0 )
2369 : {
2370 0 : return;
2371 : }
2372 :
2373 0 : Set->m_MaxHandle= 0;
2374 :
2375 0 : FD_ZERO(&Set->m_Set);
2376 : }
2377 :
2378 0 : void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2379 : {
2380 : SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2381 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2382 :
2383 0 : if ( Set == 0 || pSocket == 0)
2384 : {
2385 0 : return;
2386 : }
2387 :
2388 : /* correct max handle */
2389 0 : if(pSocket->m_Socket > Set->m_MaxHandle)
2390 0 : Set->m_MaxHandle= pSocket->m_Socket;
2391 0 : FD_SET(pSocket->m_Socket, &Set->m_Set);
2392 :
2393 : }
2394 :
2395 0 : void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
2396 : {
2397 : SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2398 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2399 :
2400 0 : if ( Set == 0 || pSocket == 0)
2401 : {
2402 0 : return;
2403 : }
2404 :
2405 : /* correct max handle */
2406 0 : if(pSocket->m_Socket == Set->m_MaxHandle)
2407 : {
2408 : /* not optimal, since the next used descriptor might be */
2409 : /* much smaller than m_Socket-1, but it will do */
2410 0 : Set->m_MaxHandle--;
2411 0 : if(Set->m_MaxHandle < 0)
2412 : {
2413 0 : Set->m_MaxHandle= 0; /* avoid underflow */
2414 : }
2415 : }
2416 :
2417 0 : FD_CLR(pSocket->m_Socket, &Set->m_Set);
2418 : }
2419 :
2420 0 : sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
2421 : {
2422 : SAL_WARN_IF( !Set, "sal.osl", "undefined socket set" );
2423 : SAL_WARN_IF( !pSocket, "sal.osl", "undefined socket" );
2424 0 : if ( Set == 0 || pSocket == 0 )
2425 : {
2426 0 : return sal_False;
2427 : }
2428 :
2429 0 : return bool(FD_ISSET(pSocket->m_Socket, &Set->m_Set));
2430 : }
2431 :
2432 0 : sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
2433 : oslSocketSet OutgoingSet,
2434 : oslSocketSet OutOfBandSet,
2435 : const TimeValue* pTimeout)
2436 : {
2437 0 : int MaxHandle= 0;
2438 : struct timeval tv;
2439 :
2440 0 : if (pTimeout)
2441 : {
2442 : /* non-blocking call */
2443 0 : tv.tv_sec = pTimeout->Seconds;
2444 0 : tv.tv_usec = pTimeout->Nanosec / 1000L;
2445 : }
2446 :
2447 : /* get max handle from all sets */
2448 0 : if (IncomingSet)
2449 0 : MaxHandle= IncomingSet->m_MaxHandle;
2450 :
2451 0 : if (OutgoingSet && (OutgoingSet->m_MaxHandle > MaxHandle))
2452 0 : MaxHandle= OutgoingSet->m_MaxHandle;
2453 :
2454 0 : if (OutOfBandSet && (OutOfBandSet->m_MaxHandle > MaxHandle))
2455 0 : MaxHandle= OutOfBandSet->m_MaxHandle;
2456 :
2457 : return select(MaxHandle+1,
2458 : IncomingSet ? PTR_FD_SET(IncomingSet->m_Set) : 0,
2459 : OutgoingSet ? PTR_FD_SET(OutgoingSet->m_Set) : 0,
2460 : OutOfBandSet ? PTR_FD_SET(OutOfBandSet->m_Set) : 0,
2461 0 : pTimeout ? &tv : 0);
2462 : }
2463 :
2464 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|