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.h"
21 :
22 : #include <osl/socket.h>
23 : #include <osl/diagnose.h>
24 : #include <osl/mutex.h>
25 : #include <osl/signal.h>
26 :
27 : #include <rtl/alloc.h>
28 :
29 : #include <ctype.h>
30 : #include <sal/types.h>
31 :
32 : #include "sockimpl.h"
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 = (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 = sal_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((struct oslSocketImpl *) Socket);
464 : #if OSL_DEBUG_LEVEL > 1
465 : g_nSocketImpl --;
466 : #endif
467 0 : }
468 :
469 0 : static oslSocketAddr __osl_createSocketAddr( )
470 : {
471 0 : oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
472 : #if OSL_DEBUG_LEVEL > 1
473 : g_nSocketAddr ++;
474 : #endif
475 0 : 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 : OSL_ASSERT( family == osl_Socket_FamilyInet );
484 :
485 0 : pAddr = __osl_createSocketAddr();
486 0 : switch( family )
487 : {
488 : case osl_Socket_FamilyInet:
489 : {
490 0 : struct sockaddr_in* pInetAddr= (struct 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 0 : static void __osl_destroySocketAddr( oslSocketAddr addr )
511 : {
512 : #if OSL_DEBUG_LEVEL > 1
513 : g_nSocketAddr --;
514 : #endif
515 0 : rtl_freeMemory( addr );
516 0 : }
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 : OSL_ASSERT(Addr1);
556 : OSL_ASSERT(Addr2);
557 0 : pAddr1 = &(Addr1->m_sockaddr);
558 0 : pAddr2 = &(Addr2->m_sockaddr);
559 :
560 0 : if (pAddr1 == pAddr2)
561 : {
562 0 : return (sal_True);
563 : }
564 :
565 0 : if (pAddr1->sa_family == pAddr2->sa_family)
566 : {
567 0 : switch (pAddr1->sa_family)
568 : {
569 : case AF_INET:
570 : {
571 0 : struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
572 0 : struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
573 :
574 0 : if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
575 0 : (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
576 0 : (pInetAddr1->sin_port == pInetAddr2->sin_port))
577 0 : return (sal_True);
578 : }
579 :
580 : default:
581 : {
582 0 : return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
583 : }
584 : }
585 : }
586 :
587 0 : return (sal_False);
588 : }
589 :
590 0 : oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
591 : rtl_uString *strDottedAddr,
592 : sal_Int32 Port)
593 : {
594 0 : sal_uInt32 nAddr = OSL_INADDR_NONE;
595 : oslSocketAddr pAddr;
596 :
597 0 : if (strDottedAddr && strDottedAddr->length)
598 : {
599 : /* Dotted host address for limited broadcast */
600 0 : rtl_String *pDottedAddr = NULL;
601 :
602 0 : rtl_uString2String (
603 0 : &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
604 : RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
605 :
606 0 : nAddr = inet_addr (pDottedAddr->buffer);
607 0 : rtl_string_release (pDottedAddr);
608 : }
609 :
610 0 : if (nAddr != OSL_INADDR_NONE)
611 : {
612 : /* Limited broadcast */
613 0 : nAddr = ntohl(nAddr);
614 0 : if (IN_CLASSA(nAddr))
615 : {
616 0 : nAddr &= IN_CLASSA_NET;
617 0 : nAddr |= IN_CLASSA_HOST;
618 : }
619 0 : else if (IN_CLASSB(nAddr))
620 : {
621 0 : nAddr &= IN_CLASSB_NET;
622 0 : nAddr |= IN_CLASSB_HOST;
623 : }
624 0 : else if (IN_CLASSC(nAddr))
625 : {
626 0 : nAddr &= IN_CLASSC_NET;
627 0 : nAddr |= IN_CLASSC_HOST;
628 : }
629 : else
630 : {
631 : /* No broadcast in class D */
632 0 : return ((oslSocketAddr)NULL);
633 : }
634 0 : nAddr = htonl(nAddr);
635 : }
636 :
637 0 : pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
638 0 : return pAddr;
639 : }
640 :
641 0 : oslSocketAddr SAL_CALL osl_createInetSocketAddr (
642 : rtl_uString *ustrDottedAddr,
643 : sal_Int32 Port)
644 : {
645 0 : rtl_String* strDottedAddr=0;
646 : oslSocketAddr Addr;
647 0 : sal_Char* pszDottedAddr=0;
648 :
649 0 : if ( ustrDottedAddr != 0 )
650 : {
651 0 : rtl_uString2String( &strDottedAddr,
652 0 : rtl_uString_getStr(ustrDottedAddr),
653 : rtl_uString_getLength(ustrDottedAddr),
654 : RTL_TEXTENCODING_UTF8,
655 : OUSTRING_TO_OSTRING_CVTFLAGS);
656 0 : pszDottedAddr = rtl_string_getStr(strDottedAddr);
657 : }
658 :
659 0 : Addr = osl_psz_createInetSocketAddr(pszDottedAddr, Port);
660 :
661 0 : if ( strDottedAddr != 0 )
662 : {
663 0 : rtl_string_release(strDottedAddr);
664 : }
665 :
666 0 : return Addr;
667 : }
668 :
669 0 : oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
670 : const sal_Char* pszDottedAddr,
671 : sal_Int32 Port)
672 : {
673 0 : oslSocketAddr pAddr = 0;
674 0 : sal_Int32 Addr = inet_addr(pszDottedAddr);
675 0 : if(Addr != -1)
676 : {
677 : /* valid dotted addr */
678 0 : pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
679 : }
680 0 : return pAddr;
681 : }
682 :
683 0 : oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
684 : {
685 0 : oslSocketResult res = osl_Socket_Error;
686 :
687 : OSL_ASSERT( pAddr );
688 : OSL_ASSERT( pByteSeq );
689 :
690 0 : if( pAddr && pByteSeq )
691 : {
692 : struct sockaddr_in * pSystemInetAddr;
693 :
694 : OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
695 : OSL_ASSERT( pByteSeq->nElements == 4 );
696 :
697 0 : pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
698 0 : memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
699 0 : res = osl_Socket_Ok;
700 : }
701 0 : return res;
702 : }
703 :
704 0 : oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
705 : {
706 0 : oslSocketResult res = osl_Socket_Error;
707 :
708 : OSL_ASSERT( pAddr );
709 : OSL_ASSERT( ppByteSeq );
710 :
711 0 : if( pAddr && ppByteSeq )
712 : {
713 0 : struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
714 0 : rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
715 0 : res = osl_Socket_Ok;
716 : }
717 0 : return res;
718 : }
719 :
720 : /** try to figure out a full-qualified hostname, by adding the current domain
721 : as given by the domainname program to the given hostname.
722 : This function MUST NOT call gethostbyname since pHostName already points
723 : to data returned by gethostname and would be garbled: use gethostname_r
724 : instead!
725 : */
726 :
727 : /* wrap around different interfaces to reentrant gethostbyname */
728 0 : static struct hostent* _osl_gethostbyname_r (
729 : const char *name, struct hostent *result,
730 : char *buffer, int buflen, int *h_errnop)
731 : {
732 : #if defined(LINUX) || defined(ANDROID) || (defined(FREEBSD) && (__FreeBSD_version >= 601103)) || defined(DRAGONFLY)
733 : struct hostent *__result; /* will be the same as result */
734 : int __error;
735 0 : __error = gethostbyname_r (name, result, buffer, buflen,
736 : &__result, h_errnop);
737 0 : return __error ? NULL : __result ;
738 : #elif defined(AIX)
739 : *h_errnop = gethostbyname_r (name, result, (struct hostent_data *)buffer);
740 : (void)buflen;
741 : return *h_errnop ? NULL : result ;
742 : #else
743 : return gethostbyname_r( name, result, buffer, buflen, h_errnop);
744 : #endif
745 : }
746 :
747 0 : static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
748 : {
749 : struct hostent aHostByName;
750 : struct hostent *pHostByName;
751 : sal_Char pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
752 0 : sal_Char *pFullQualifiedName = NULL;
753 : int nErrorNo;
754 :
755 0 : pHostByName = _osl_gethostbyname_r (
756 : pHostName,
757 : &aHostByName, pQualifiedHostBuffer,
758 : sizeof(pQualifiedHostBuffer), &nErrorNo );
759 0 : if (pHostByName != NULL)
760 : {
761 0 : pFullQualifiedName = strdup(pHostByName->h_name);
762 : }
763 0 : return pFullQualifiedName;
764 : }
765 :
766 0 : static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
767 : {
768 : /* a FQDN (aka 'hostname.domain.top_level_domain' )
769 : * is a name which contains a dot '.' in it ( would
770 : * match as well for 'hostname.' but is good enough
771 : * for now )*/
772 0 : return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
773 : }
774 :
775 : struct oslHostAddrImpl
776 : {
777 : sal_Char *pHostName;
778 : oslSocketAddr pSockAddr;
779 : };
780 :
781 0 : static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
782 : {
783 0 : oslHostAddr pAddr= NULL;
784 0 : oslSocketAddr pSockAddr = 0;
785 :
786 : sal_Char *cn;
787 :
788 0 : if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
789 0 : return ((oslHostAddr)NULL);
790 :
791 0 : if (_osl_isFullQualifiedDomainName(he->h_name))
792 : {
793 0 : cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
794 : OSL_ASSERT(cn);
795 0 : if (cn == NULL)
796 0 : return ((oslHostAddr)NULL);
797 :
798 0 : strcpy(cn, he->h_name);
799 : }
800 : else
801 : {
802 0 : cn =_osl_getFullQualifiedDomainName (he->h_name);
803 : OSL_ASSERT(cn);
804 0 : if (cn == NULL)
805 0 : return ((oslHostAddr)NULL);
806 : }
807 :
808 0 : pSockAddr = __osl_createSocketAddr();
809 : OSL_ASSERT(pSockAddr);
810 0 : if (pSockAddr == NULL)
811 : {
812 0 : free(cn);
813 0 : return ((oslHostAddr)NULL);
814 : }
815 :
816 0 : pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
817 0 : if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
818 : {
819 0 : struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
820 0 : memcpy (
821 0 : &(sin->sin_addr.s_addr),
822 0 : he->h_addr_list[0],
823 0 : he->h_length);
824 : }
825 : else
826 : {
827 : /* unknown address family */
828 : /* future extensions for new families might be implemented here */
829 :
830 : OSL_TRACE("_osl_hostentToHostAddr: unknown address family.");
831 : OSL_ASSERT(sal_False);
832 :
833 0 : __osl_destroySocketAddr( pSockAddr );
834 0 : free (cn);
835 0 : return ((oslHostAddr)NULL);
836 : }
837 :
838 0 : pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
839 : OSL_ASSERT(pAddr);
840 0 : if (pAddr == NULL)
841 : {
842 0 : __osl_destroySocketAddr( pSockAddr );
843 0 : free (cn);
844 0 : return ((oslHostAddr)NULL);
845 : }
846 :
847 0 : pAddr->pHostName= cn;
848 0 : pAddr->pSockAddr= pSockAddr;
849 :
850 0 : return pAddr;
851 : }
852 :
853 0 : oslHostAddr SAL_CALL osl_createHostAddr (
854 : rtl_uString *ustrHostname,
855 : const oslSocketAddr Addr)
856 : {
857 : oslHostAddr HostAddr;
858 0 : rtl_String* strHostname=0;
859 0 : sal_Char* pszHostName=0;
860 :
861 0 : if ( ustrHostname != 0 )
862 : {
863 0 : rtl_uString2String( &strHostname,
864 0 : rtl_uString_getStr(ustrHostname),
865 : rtl_uString_getLength(ustrHostname),
866 : RTL_TEXTENCODING_UTF8,
867 : OUSTRING_TO_OSTRING_CVTFLAGS );
868 0 : pszHostName = rtl_string_getStr(strHostname);
869 : }
870 :
871 0 : HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
872 :
873 0 : if ( strHostname != 0 )
874 : {
875 0 : rtl_string_release(strHostname);
876 : }
877 :
878 0 : return HostAddr;
879 : }
880 :
881 0 : oslHostAddr SAL_CALL osl_psz_createHostAddr (
882 : const sal_Char *pszHostname,
883 : const oslSocketAddr pAddr)
884 : {
885 : oslHostAddr pHostAddr;
886 : sal_Char *cn;
887 :
888 : OSL_ASSERT(pszHostname && pAddr);
889 0 : if ((pszHostname == NULL) || (pAddr == NULL))
890 0 : return ((oslHostAddr)NULL);
891 :
892 0 : cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
893 : OSL_ASSERT(cn);
894 0 : if (cn == NULL)
895 0 : return ((oslHostAddr)NULL);
896 :
897 0 : strcpy (cn, pszHostname);
898 :
899 0 : pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
900 : OSL_ASSERT(pHostAddr);
901 0 : if (pHostAddr == NULL)
902 : {
903 0 : free (cn);
904 0 : return ((oslHostAddr)NULL);
905 : }
906 :
907 0 : pHostAddr->pHostName= cn;
908 0 : pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
909 :
910 0 : return pHostAddr;
911 : }
912 :
913 0 : oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
914 : {
915 : oslHostAddr HostAddr;
916 0 : rtl_String* strHostname=0;
917 0 : sal_Char* pszHostName=0;
918 :
919 0 : if ( ustrHostname != 0 )
920 : {
921 0 : rtl_uString2String( &strHostname,
922 0 : rtl_uString_getStr(ustrHostname),
923 : rtl_uString_getLength(ustrHostname),
924 : RTL_TEXTENCODING_UTF8,
925 : OUSTRING_TO_OSTRING_CVTFLAGS );
926 0 : pszHostName=rtl_string_getStr(strHostname);
927 : }
928 :
929 0 : HostAddr = osl_psz_createHostAddrByName(pszHostName);
930 :
931 0 : if ( strHostname != 0 )
932 : {
933 0 : rtl_string_release(strHostname);
934 : }
935 :
936 0 : return HostAddr;
937 : }
938 :
939 0 : oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
940 : {
941 : struct hostent aHe;
942 : struct hostent *pHe;
943 : sal_Char heBuffer[ MAX_HOSTBUFFER_SIZE ];
944 : int nErrorNo;
945 :
946 0 : pHe = _osl_gethostbyname_r (
947 : pszHostname,
948 : &aHe, heBuffer,
949 : sizeof(heBuffer), &nErrorNo );
950 :
951 0 : return _osl_hostentToHostAddr (pHe);
952 : }
953 :
954 0 : oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
955 : {
956 : OSL_ASSERT(pAddr);
957 :
958 0 : if (pAddr == NULL)
959 0 : return ((oslHostAddr)NULL);
960 :
961 0 : if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
962 : {
963 0 : const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
964 : struct hostent *he;
965 :
966 0 : if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
967 0 : return ((oslHostAddr)NULL);
968 :
969 0 : he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
970 : sizeof (sin->sin_addr),
971 0 : sin->sin_family);
972 0 : return _osl_hostentToHostAddr (he);
973 : }
974 :
975 0 : return ((oslHostAddr)NULL);
976 : }
977 :
978 0 : oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
979 : {
980 : OSL_ASSERT(pAddr);
981 :
982 0 : if (pAddr)
983 0 : return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
984 : else
985 0 : return ((oslHostAddr)NULL);
986 : }
987 :
988 0 : void SAL_CALL osl_getHostnameOfHostAddr (
989 : const oslHostAddr Addr,
990 : rtl_uString **ustrHostname)
991 : {
992 0 : const sal_Char* pHostname=0;
993 :
994 0 : pHostname = osl_psz_getHostnameOfHostAddr(Addr);
995 :
996 0 : rtl_uString_newFromAscii (ustrHostname, pHostname);
997 :
998 0 : return;
999 : }
1000 :
1001 0 : const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1002 : {
1003 0 : if (pAddr)
1004 0 : return pAddr->pHostName;
1005 : else
1006 0 : return NULL;
1007 : }
1008 :
1009 0 : oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1010 : {
1011 : OSL_ASSERT(pAddr);
1012 :
1013 0 : if (pAddr)
1014 0 : return ((oslSocketAddr)(pAddr->pSockAddr));
1015 : else
1016 0 : return NULL;
1017 : }
1018 :
1019 0 : void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1020 : {
1021 0 : if (pAddr)
1022 : {
1023 0 : if (pAddr->pHostName)
1024 0 : free (pAddr->pHostName);
1025 0 : if (pAddr->pSockAddr)
1026 0 : osl_destroySocketAddr (pAddr->pSockAddr);
1027 0 : free (pAddr);
1028 : }
1029 0 : }
1030 :
1031 0 : oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1032 : {
1033 : oslSocketResult Result;
1034 : sal_Char pszHostname[1024];
1035 :
1036 0 : pszHostname[0] = '\0';
1037 :
1038 0 : Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1039 :
1040 0 : rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1041 :
1042 0 : return Result;
1043 : }
1044 :
1045 0 : oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1046 : sal_Char *pBuffer, sal_uInt32 nBufLen)
1047 : {
1048 : static sal_Char LocalHostname[256] = "";
1049 :
1050 0 : if (strlen(LocalHostname) == 0)
1051 : {
1052 : const sal_Char *pStr;
1053 :
1054 : #ifdef SYSV
1055 : struct utsname uts;
1056 :
1057 : if (uname(&uts) < 0)
1058 : return osl_Socket_Error;
1059 :
1060 : if ((strlen(uts.nodename) + 1) > nBufLen)
1061 : return osl_Socket_Error;
1062 :
1063 : strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1064 : #else /* BSD compatible */
1065 :
1066 0 : if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1067 0 : return osl_Socket_Error;
1068 0 : LocalHostname[sizeof(LocalHostname)-1] = 0;
1069 : #endif /* SYSV */
1070 :
1071 : /* check if we have an FQDN */
1072 0 : if (strchr(LocalHostname, '.') == NULL)
1073 : {
1074 : oslHostAddr Addr;
1075 :
1076 : /* no, determine it via dns */
1077 0 : Addr = osl_psz_createHostAddrByName(LocalHostname);
1078 :
1079 0 : if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1080 : {
1081 0 : strcpy(LocalHostname, pStr);
1082 : }
1083 0 : osl_destroyHostAddr(Addr);
1084 : }
1085 : }
1086 :
1087 0 : if (strlen(LocalHostname) > 0)
1088 : {
1089 0 : strncpy(pBuffer, LocalHostname, nBufLen);
1090 0 : pBuffer[nBufLen - 1] = '\0';
1091 :
1092 0 : return osl_Socket_Ok;
1093 : }
1094 :
1095 0 : return osl_Socket_Error;
1096 : }
1097 :
1098 0 : oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1099 : {
1100 : oslSocketAddr Addr;
1101 0 : rtl_String* strHostname=0;
1102 0 : sal_Char* pszHostName=0;
1103 :
1104 0 : if ( ustrHostname != 0 )
1105 : {
1106 0 : rtl_uString2String( &strHostname,
1107 0 : rtl_uString_getStr(ustrHostname),
1108 : rtl_uString_getLength(ustrHostname),
1109 : RTL_TEXTENCODING_UTF8,
1110 : OUSTRING_TO_OSTRING_CVTFLAGS );
1111 0 : pszHostName = rtl_string_getStr(strHostname);
1112 : }
1113 :
1114 0 : Addr = osl_psz_resolveHostname(pszHostName);
1115 :
1116 0 : if ( strHostname != 0 )
1117 : {
1118 0 : rtl_string_release(strHostname);
1119 : }
1120 :
1121 0 : return Addr;
1122 : }
1123 :
1124 0 : oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1125 : {
1126 0 : struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1127 :
1128 0 : if (pAddr)
1129 : {
1130 0 : oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1131 :
1132 0 : osl_destroyHostAddr(pAddr);
1133 :
1134 0 : return (SockAddr);
1135 : }
1136 :
1137 0 : return ((oslSocketAddr)NULL);
1138 : }
1139 :
1140 0 : sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1141 : {
1142 : sal_Int32 nPort;
1143 0 : rtl_String* strServicename=0;
1144 0 : rtl_String* strProtocol=0;
1145 0 : sal_Char* pszServiceName=0;
1146 0 : sal_Char* pszProtocol=0;
1147 :
1148 0 : if ( ustrServicename != 0 )
1149 : {
1150 0 : rtl_uString2String( &strServicename,
1151 0 : rtl_uString_getStr(ustrServicename),
1152 : rtl_uString_getLength(ustrServicename),
1153 : RTL_TEXTENCODING_UTF8,
1154 : OUSTRING_TO_OSTRING_CVTFLAGS );
1155 0 : pszServiceName = rtl_string_getStr(strServicename);
1156 : }
1157 :
1158 0 : if ( ustrProtocol != 0 )
1159 : {
1160 0 : rtl_uString2String( &strProtocol,
1161 0 : rtl_uString_getStr(ustrProtocol),
1162 : rtl_uString_getLength(ustrProtocol),
1163 : RTL_TEXTENCODING_UTF8,
1164 : OUSTRING_TO_OSTRING_CVTFLAGS );
1165 0 : pszProtocol = rtl_string_getStr(strProtocol);
1166 : }
1167 :
1168 0 : nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1169 :
1170 0 : if ( strServicename != 0 )
1171 : {
1172 0 : rtl_string_release(strServicename);
1173 : }
1174 :
1175 0 : if ( strProtocol != 0 )
1176 : {
1177 0 : rtl_string_release(strProtocol);
1178 : }
1179 :
1180 0 : return nPort;
1181 : }
1182 :
1183 0 : sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1184 : const sal_Char* pszProtocol)
1185 : {
1186 : struct servent* ps;
1187 :
1188 0 : ps= getservbyname(pszServicename, pszProtocol);
1189 :
1190 0 : if (ps != 0)
1191 0 : return ntohs(ps->s_port);
1192 :
1193 0 : return OSL_INVALID_PORT;
1194 : }
1195 :
1196 0 : void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1197 : {
1198 0 : __osl_destroySocketAddr( pAddr );
1199 0 : }
1200 :
1201 0 : oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1202 : {
1203 : OSL_ASSERT(pAddr);
1204 :
1205 0 : if (pAddr)
1206 0 : return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1207 : else
1208 0 : return osl_Socket_FamilyInvalid;
1209 : }
1210 :
1211 0 : sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1212 : {
1213 : OSL_ASSERT(pAddr);
1214 0 : if( pAddr )
1215 : {
1216 0 : struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1217 :
1218 0 : if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1219 0 : return ntohs(pSystemInetAddr->sin_port);
1220 : }
1221 0 : return OSL_INVALID_PORT;
1222 : }
1223 :
1224 0 : sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1225 : {
1226 : OSL_ASSERT(pAddr);
1227 0 : if( pAddr )
1228 : {
1229 0 : struct sockaddr_in* pSystemInetAddr= (struct 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= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1259 :
1260 0 : if (pHostAddr)
1261 : {
1262 0 : strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1263 :
1264 0 : pBuffer[BufferSize - 1] = '\0';
1265 :
1266 0 : osl_destroyHostAddr(pHostAddr);
1267 :
1268 0 : return osl_Socket_Ok;
1269 : }
1270 :
1271 0 : return osl_Socket_Error;
1272 : }
1273 :
1274 : /*****************************************************************************/
1275 : /* osl_getDottedInetAddrOfSocketAddr */
1276 : /*****************************************************************************/
1277 0 : oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1278 : {
1279 : oslSocketResult Result;
1280 : sal_Char pszDottedInetAddr[1024];
1281 :
1282 0 : pszDottedInetAddr[0] = '\0';
1283 :
1284 0 : Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1285 :
1286 0 : rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1287 :
1288 0 : return Result;
1289 :
1290 : }
1291 :
1292 0 : oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1293 : sal_Char *pBuffer, sal_uInt32 BufferSize)
1294 : {
1295 : OSL_ASSERT(pAddr);
1296 :
1297 0 : if( pAddr )
1298 : {
1299 0 : struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1300 :
1301 0 : if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1302 : {
1303 0 : strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1304 0 : pBuffer[BufferSize - 1] = '\0';
1305 :
1306 0 : return osl_Socket_Ok;
1307 : }
1308 : }
1309 :
1310 0 : return osl_Socket_Error;
1311 : }
1312 :
1313 0 : oslSocket SAL_CALL osl_createSocket(oslAddrFamily Family,
1314 : oslSocketType Type,
1315 : oslProtocol Protocol)
1316 : {
1317 : int Flags;
1318 : oslSocket pSocket;
1319 :
1320 : /* alloc memory */
1321 0 : pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1322 :
1323 : /* create socket */
1324 0 : pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1325 0 : TYPE_TO_NATIVE(Type),
1326 0 : PROTOCOL_TO_NATIVE(Protocol));
1327 :
1328 : /* creation failed => free memory */
1329 0 : if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1330 : {
1331 : OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1332 : errno,
1333 : strerror(errno));
1334 :
1335 0 : __osl_destroySocketImpl((pSocket));
1336 0 : pSocket= 0;
1337 : }
1338 : else
1339 : {
1340 : /* set close-on-exec flag */
1341 0 : if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1342 : {
1343 0 : Flags |= FD_CLOEXEC;
1344 0 : if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1345 : {
1346 0 : pSocket->m_nLastError=errno;
1347 : OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1348 : errno,
1349 : strerror(errno));
1350 : }
1351 : }
1352 : else
1353 : {
1354 0 : pSocket->m_nLastError=errno;
1355 : }
1356 : }
1357 :
1358 0 : return pSocket;
1359 : }
1360 :
1361 0 : void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1362 : {
1363 0 : osl_atomic_increment( &(pSocket->m_nRefCount ) );
1364 0 : }
1365 :
1366 0 : void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1367 : {
1368 0 : if( pSocket && 0 == osl_atomic_decrement( &(pSocket->m_nRefCount) ) )
1369 : {
1370 : #if defined(LINUX)
1371 0 : if ( pSocket->m_bIsAccepting == sal_True )
1372 : {
1373 : OSL_FAIL("osl_destroySocket : attempt to destroy socket while accepting\n");
1374 0 : return;
1375 : }
1376 : #endif /* LINUX */
1377 0 : osl_closeSocket( pSocket );
1378 0 : __osl_destroySocketImpl( pSocket );
1379 : }
1380 : }
1381 :
1382 0 : void SAL_CALL osl_closeSocket(oslSocket pSocket)
1383 : {
1384 : int nRet;
1385 : int nFD;
1386 :
1387 : /* socket already invalid */
1388 0 : if(pSocket==0)
1389 0 : return;
1390 :
1391 0 : pSocket->m_nLastError=0;
1392 0 : nFD = pSocket->m_Socket;
1393 :
1394 0 : if (nFD == OSL_INVALID_SOCKET)
1395 0 : return;
1396 :
1397 0 : pSocket->m_Socket = OSL_INVALID_SOCKET;
1398 :
1399 : #if defined(LINUX)
1400 0 : pSocket->m_bIsInShutdown = sal_True;
1401 :
1402 0 : if ( pSocket->m_bIsAccepting == sal_True )
1403 : {
1404 : int nConnFD;
1405 : union {
1406 : struct sockaddr aSockAddr;
1407 : struct sockaddr_in aSockAddrIn;
1408 : } s;
1409 0 : socklen_t nSockLen = sizeof(s.aSockAddr);
1410 :
1411 0 : nRet = getsockname(nFD, &s.aSockAddr, &nSockLen);
1412 : if ( nRet < 0 )
1413 : {
1414 : OSL_TRACE("getsockname call failed with error: %s", strerror(errno));
1415 : }
1416 :
1417 0 : if ( s.aSockAddr.sa_family == AF_INET )
1418 : {
1419 0 : if ( s.aSockAddrIn.sin_addr.s_addr == htonl(INADDR_ANY) )
1420 : {
1421 0 : s.aSockAddrIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1422 : }
1423 :
1424 0 : nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1425 0 : if ( nConnFD < 0 )
1426 : {
1427 : OSL_TRACE("socket call failed with error: %s", strerror(errno));
1428 : }
1429 : else
1430 : {
1431 0 : nRet = connect(nConnFD, &s.aSockAddr, sizeof(s.aSockAddr));
1432 : if ( nRet < 0 )
1433 : {
1434 : OSL_TRACE("connect call failed with error: %s", strerror(errno));
1435 : }
1436 0 : close(nConnFD);
1437 : }
1438 : }
1439 0 : pSocket->m_bIsAccepting = sal_False;
1440 : }
1441 : #endif /* LINUX */
1442 :
1443 0 : nRet=close(nFD);
1444 0 : if ( nRet != 0 )
1445 : {
1446 0 : pSocket->m_nLastError=errno;
1447 : OSL_TRACE("closeSocket close error '%s'",strerror(errno));
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 ((oslSocketAddr)NULL);
1467 :
1468 0 : AddrLen= sizeof(struct sockaddr);
1469 :
1470 0 : if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1471 0 : return ((oslSocketAddr)NULL);
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 : OSL_ASSERT(pSocket);
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 : OSL_ASSERT(pSocket && pAddr );
1505 0 : if ( pSocket == 0 || pAddr == 0 )
1506 : {
1507 0 : return sal_False;
1508 : }
1509 :
1510 0 : pSocket->m_nLastError=0;
1511 :
1512 0 : nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1513 :
1514 0 : if ( nRet == OSL_SOCKET_ERROR)
1515 : {
1516 0 : pSocket->m_nLastError=errno;
1517 0 : return sal_False;
1518 : }
1519 :
1520 0 : return sal_True;
1521 : }
1522 :
1523 0 : sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
1524 : sal_Int32 MaxPendingConnections)
1525 : {
1526 : int nRet;
1527 :
1528 : OSL_ASSERT(pSocket);
1529 0 : if ( pSocket == 0 )
1530 : {
1531 0 : return sal_False;
1532 : }
1533 :
1534 0 : pSocket->m_nLastError=0;
1535 :
1536 0 : nRet = listen(pSocket->m_Socket,
1537 : MaxPendingConnections == -1 ?
1538 : SOMAXCONN :
1539 : MaxPendingConnections);
1540 0 : if ( nRet == OSL_SOCKET_ERROR)
1541 : {
1542 0 : pSocket->m_nLastError=errno;
1543 0 : return sal_False;
1544 : }
1545 :
1546 0 : return sal_True;
1547 : }
1548 :
1549 0 : oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
1550 : oslSocketAddr pAddr,
1551 : const TimeValue* pTimeout)
1552 : {
1553 : fd_set WriteSet;
1554 : fd_set ExcptSet;
1555 : int ReadyHandles;
1556 : struct timeval tv;
1557 0 : oslSocketResult Result= osl_Socket_Ok;
1558 :
1559 : OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
1560 :
1561 0 : if ( pSocket == 0 )
1562 : {
1563 0 : return osl_Socket_Error;
1564 : }
1565 :
1566 0 : pSocket->m_nLastError=0;
1567 :
1568 0 : if (osl_isNonBlockingMode(pSocket))
1569 : {
1570 0 : if (connect(pSocket->m_Socket,
1571 0 : &(pAddr->m_sockaddr),
1572 : sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1573 0 : return osl_Socket_Ok;
1574 : else
1575 0 : if (errno == EWOULDBLOCK || errno == EINPROGRESS)
1576 : {
1577 0 : pSocket->m_nLastError=EINPROGRESS;
1578 0 : return osl_Socket_InProgress;
1579 : }
1580 :
1581 0 : pSocket->m_nLastError=errno;
1582 : OSL_TRACE("can't connect : '%s'",strerror(errno));
1583 0 : return osl_Socket_Error;
1584 : }
1585 :
1586 : /* set socket temporarily to non-blocking */
1587 0 : OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
1588 :
1589 : /* initiate connect */
1590 0 : if(connect(pSocket->m_Socket,
1591 0 : &(pAddr->m_sockaddr),
1592 : sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
1593 : {
1594 : /* immediate connection */
1595 0 : osl_enableNonBlockingMode(pSocket, sal_False);
1596 :
1597 0 : return osl_Socket_Ok;
1598 : }
1599 : else
1600 : {
1601 : /* really an error or just delayed? */
1602 0 : if (errno != EINPROGRESS)
1603 : {
1604 0 : pSocket->m_nLastError=errno;
1605 : OSL_TRACE(
1606 : "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
1607 : errno, strerror(errno));
1608 :
1609 0 : osl_enableNonBlockingMode(pSocket, sal_False);
1610 0 : return osl_Socket_Error;
1611 : }
1612 : }
1613 :
1614 : /* prepare select set for socket */
1615 0 : FD_ZERO(&WriteSet);
1616 0 : FD_ZERO(&ExcptSet);
1617 0 : FD_SET(pSocket->m_Socket, &WriteSet);
1618 0 : FD_SET(pSocket->m_Socket, &ExcptSet);
1619 :
1620 : /* prepare timeout */
1621 0 : if (pTimeout)
1622 : {
1623 : /* divide milliseconds into seconds and microseconds */
1624 0 : tv.tv_sec= pTimeout->Seconds;
1625 0 : tv.tv_usec= pTimeout->Nanosec / 1000L;
1626 : }
1627 :
1628 : /* select */
1629 0 : ReadyHandles= select(pSocket->m_Socket+1,
1630 : 0,
1631 : PTR_FD_SET(WriteSet),
1632 : PTR_FD_SET(ExcptSet),
1633 : (pTimeout) ? &tv : 0);
1634 :
1635 0 : if (ReadyHandles > 0) /* connected */
1636 : {
1637 0 : if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
1638 : {
1639 0 : int nErrorCode = 0;
1640 0 : socklen_t nErrorSize = sizeof( nErrorCode );
1641 :
1642 : int nSockOpt;
1643 :
1644 0 : nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
1645 : &nErrorCode, &nErrorSize );
1646 0 : if ( (nSockOpt == 0) && (nErrorCode == 0))
1647 0 : Result = osl_Socket_Ok;
1648 : else
1649 0 : Result = osl_Socket_Error;
1650 : }
1651 : else
1652 : {
1653 0 : Result= osl_Socket_Error;
1654 : }
1655 : }
1656 0 : else if (ReadyHandles < 0) /* error */
1657 : {
1658 0 : if (errno == EBADF) /* most probably interrupted by close() */
1659 : {
1660 : /* do not access pSockImpl because it is about to be or */
1661 : /* already destroyed */
1662 0 : return osl_Socket_Interrupted;
1663 : }
1664 : else
1665 : {
1666 0 : pSocket->m_nLastError=errno;
1667 0 : Result= osl_Socket_Error;
1668 : }
1669 : }
1670 : else /* timeout */
1671 : {
1672 0 : pSocket->m_nLastError=errno;
1673 0 : Result= osl_Socket_TimedOut;
1674 : }
1675 :
1676 0 : osl_enableNonBlockingMode(pSocket, sal_False);
1677 :
1678 0 : return Result;
1679 : }
1680 :
1681 0 : oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
1682 : oslSocketAddr* ppAddr)
1683 : {
1684 : struct sockaddr Addr;
1685 : int Connection, Flags;
1686 : oslSocket pConnectionSockImpl;
1687 :
1688 0 : socklen_t AddrLen = sizeof(struct sockaddr);
1689 : OSL_ASSERT(pSocket);
1690 0 : if ( pSocket == 0 )
1691 : {
1692 0 : return 0;
1693 : }
1694 :
1695 0 : pSocket->m_nLastError=0;
1696 : #if defined(LINUX)
1697 0 : pSocket->m_bIsAccepting = sal_True;
1698 : #endif /* LINUX */
1699 :
1700 0 : if( ppAddr && *ppAddr )
1701 : {
1702 0 : osl_destroySocketAddr( *ppAddr );
1703 0 : *ppAddr = 0;
1704 : }
1705 :
1706 : /* prevent Linux EINTR behaviour */
1707 : do
1708 : {
1709 0 : Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
1710 0 : } while (Connection == -1 && errno == EINTR);
1711 :
1712 : /* accept failed? */
1713 0 : if( Connection == OSL_SOCKET_ERROR )
1714 : {
1715 0 : pSocket->m_nLastError=errno;
1716 : OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'",strerror(errno));
1717 :
1718 : #if defined(LINUX)
1719 0 : pSocket->m_bIsAccepting = sal_False;
1720 : #endif /* LINUX */
1721 0 : return 0;
1722 : }
1723 :
1724 : OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
1725 :
1726 : #if defined(LINUX)
1727 0 : if ( pSocket->m_bIsInShutdown == sal_True )
1728 : {
1729 0 : close(Connection);
1730 : OSL_TRACE("osl_acceptConnectionOnSocket : close while accept");
1731 0 : return 0;
1732 : }
1733 : #endif /* LINUX */
1734 :
1735 0 : if(ppAddr)
1736 : {
1737 0 : *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
1738 : }
1739 :
1740 : /* alloc memory */
1741 0 : pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1742 :
1743 : /* set close-on-exec flag */
1744 0 : if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
1745 : {
1746 0 : Flags |= FD_CLOEXEC;
1747 0 : if (fcntl(Connection, F_SETFD, Flags) == -1)
1748 : {
1749 0 : pSocket->m_nLastError=errno;
1750 : OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
1751 : errno,
1752 : strerror(errno));
1753 : }
1754 :
1755 : }
1756 :
1757 0 : pConnectionSockImpl->m_Socket = Connection;
1758 0 : pConnectionSockImpl->m_nLastError = 0;
1759 : #if defined(LINUX)
1760 0 : pConnectionSockImpl->m_bIsAccepting = sal_False;
1761 :
1762 0 : pSocket->m_bIsAccepting = sal_False;
1763 : #endif /* LINUX */
1764 0 : return pConnectionSockImpl;
1765 : }
1766 :
1767 0 : sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
1768 : void* pBuffer,
1769 : sal_uInt32 BytesToRead,
1770 : oslSocketMsgFlag Flag)
1771 : {
1772 : int nRead;
1773 :
1774 : OSL_ASSERT(pSocket);
1775 0 : if ( pSocket == 0 )
1776 : {
1777 : OSL_TRACE("osl_receiveSocket : Invalid socket");
1778 0 : return -1;
1779 : }
1780 :
1781 0 : pSocket->m_nLastError=0;
1782 :
1783 : do
1784 : {
1785 0 : nRead = recv(pSocket->m_Socket,
1786 : (sal_Char*)pBuffer,
1787 : BytesToRead,
1788 0 : MSG_FLAG_TO_NATIVE(Flag));
1789 0 : } while ( nRead < 0 && errno == EINTR );
1790 :
1791 0 : if ( nRead < 0 )
1792 : {
1793 0 : pSocket->m_nLastError=errno;
1794 : OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
1795 : }
1796 : else if ( nRead == 0 )
1797 : {
1798 : OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
1799 : }
1800 :
1801 0 : return nRead;
1802 : }
1803 :
1804 0 : sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
1805 : oslSocketAddr pSenderAddr,
1806 : void* pBuffer,
1807 : sal_uInt32 BufferSize,
1808 : oslSocketMsgFlag Flag)
1809 : {
1810 : int nRead;
1811 0 : struct sockaddr *pSystemSockAddr = 0;
1812 0 : socklen_t AddrLen = 0;
1813 0 : if( pSenderAddr )
1814 : {
1815 0 : AddrLen = sizeof( struct sockaddr );
1816 0 : pSystemSockAddr = &(pSenderAddr->m_sockaddr);
1817 : }
1818 :
1819 : OSL_ASSERT(pSocket);
1820 0 : if ( pSocket == 0 )
1821 : {
1822 : OSL_TRACE("osl_receiveFromSocket : Invalid socket");
1823 0 : return -1;
1824 : }
1825 :
1826 0 : pSocket->m_nLastError=0;
1827 :
1828 0 : nRead = recvfrom(pSocket->m_Socket,
1829 : (sal_Char*)pBuffer,
1830 : BufferSize,
1831 0 : MSG_FLAG_TO_NATIVE(Flag),
1832 : pSystemSockAddr,
1833 : &AddrLen);
1834 :
1835 0 : if ( nRead < 0 )
1836 : {
1837 0 : pSocket->m_nLastError=errno;
1838 : OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
1839 : }
1840 : else if ( nRead == 0 )
1841 : {
1842 : OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
1843 : }
1844 :
1845 0 : return nRead;
1846 : }
1847 :
1848 0 : sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
1849 : const void* pBuffer,
1850 : sal_uInt32 BytesToSend,
1851 : oslSocketMsgFlag Flag)
1852 : {
1853 : int nWritten;
1854 :
1855 : OSL_ASSERT(pSocket);
1856 0 : if ( pSocket == 0 )
1857 : {
1858 : OSL_TRACE("osl_sendSocket : Invalid socket");
1859 0 : return -1;
1860 : }
1861 :
1862 0 : pSocket->m_nLastError=0;
1863 :
1864 : do
1865 : {
1866 0 : nWritten = send(pSocket->m_Socket,
1867 : (sal_Char*)pBuffer,
1868 : BytesToSend,
1869 0 : MSG_FLAG_TO_NATIVE(Flag));
1870 0 : } while ( nWritten < 0 && errno == EINTR );
1871 :
1872 0 : if ( nWritten < 0 )
1873 : {
1874 0 : pSocket->m_nLastError=errno;
1875 : OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
1876 : }
1877 : else if ( nWritten == 0 )
1878 : {
1879 : OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
1880 : }
1881 :
1882 0 : return nWritten;
1883 : }
1884 :
1885 0 : sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
1886 : oslSocketAddr ReceiverAddr,
1887 : const void* pBuffer,
1888 : sal_uInt32 BytesToSend,
1889 : oslSocketMsgFlag Flag)
1890 : {
1891 : int nWritten;
1892 :
1893 0 : struct sockaddr *pSystemSockAddr = 0;
1894 0 : int AddrLen = 0;
1895 0 : if( ReceiverAddr )
1896 : {
1897 0 : pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
1898 0 : AddrLen = sizeof( struct sockaddr );
1899 : }
1900 :
1901 : OSL_ASSERT(pSocket);
1902 0 : if ( pSocket == 0 )
1903 : {
1904 : OSL_TRACE("osl_sendToSocket : Invalid socket");
1905 0 : return -1;
1906 : }
1907 :
1908 0 : pSocket->m_nLastError=0;
1909 :
1910 : /* ReceiverAddr might be 0 when used on a connected socket. */
1911 : /* Then sendto should behave like send. */
1912 :
1913 0 : nWritten = sendto(pSocket->m_Socket,
1914 : (sal_Char*)pBuffer,
1915 : BytesToSend,
1916 0 : MSG_FLAG_TO_NATIVE(Flag),
1917 : pSystemSockAddr,
1918 : AddrLen);
1919 :
1920 0 : if ( nWritten < 0 )
1921 : {
1922 0 : pSocket->m_nLastError=errno;
1923 : OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
1924 : }
1925 : else if ( nWritten == 0 )
1926 : {
1927 : OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
1928 : }
1929 :
1930 0 : return nWritten;
1931 : }
1932 :
1933 0 : sal_Int32 SAL_CALL osl_readSocket (
1934 : oslSocket pSocket, void *pBuffer, sal_Int32 n )
1935 : {
1936 0 : sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
1937 0 : sal_uInt32 BytesRead= 0;
1938 0 : sal_uInt32 BytesToRead= n;
1939 :
1940 : OSL_ASSERT( pSocket);
1941 :
1942 : /* loop until all desired bytes were read or an error occurred */
1943 0 : while (BytesToRead > 0)
1944 : {
1945 : sal_Int32 RetVal;
1946 0 : RetVal= osl_receiveSocket(pSocket,
1947 : Ptr,
1948 : BytesToRead,
1949 : osl_Socket_MsgNormal);
1950 :
1951 : /* error occurred? */
1952 0 : if(RetVal <= 0)
1953 : {
1954 0 : break;
1955 : }
1956 :
1957 0 : BytesToRead -= RetVal;
1958 0 : BytesRead += RetVal;
1959 0 : Ptr += RetVal;
1960 : }
1961 :
1962 0 : return BytesRead;
1963 : }
1964 :
1965 0 : sal_Int32 SAL_CALL osl_writeSocket(
1966 : oslSocket pSocket, const void *pBuffer, sal_Int32 n )
1967 : {
1968 : /* loop until all desired bytes were send or an error occurred */
1969 0 : sal_uInt32 BytesSend= 0;
1970 0 : sal_uInt32 BytesToSend= n;
1971 0 : sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
1972 :
1973 : OSL_ASSERT( pSocket );
1974 :
1975 0 : while (BytesToSend > 0)
1976 : {
1977 : sal_Int32 RetVal;
1978 :
1979 0 : RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
1980 :
1981 : /* error occurred? */
1982 0 : if(RetVal <= 0)
1983 : {
1984 0 : break;
1985 : }
1986 :
1987 0 : BytesToSend -= RetVal;
1988 0 : BytesSend += RetVal;
1989 0 : Ptr += RetVal;
1990 :
1991 : }
1992 0 : return BytesSend;
1993 : }
1994 :
1995 : #ifdef HAVE_POLL_H /* poll() */
1996 :
1997 0 : sal_Bool __osl_socket_poll (
1998 : oslSocket pSocket,
1999 : const TimeValue* pTimeout,
2000 : short nEvent)
2001 : {
2002 : struct pollfd fds;
2003 : int timeout;
2004 : int result;
2005 :
2006 : OSL_ASSERT(0 != pSocket);
2007 0 : if (0 == pSocket)
2008 0 : return sal_False; /* EINVAL */
2009 :
2010 0 : pSocket->m_nLastError = 0;
2011 :
2012 0 : fds.fd = pSocket->m_Socket;
2013 0 : fds.events = nEvent;
2014 0 : fds.revents = 0;
2015 :
2016 0 : timeout = -1;
2017 0 : if (pTimeout)
2018 : {
2019 : /* Convert to [ms] */
2020 0 : timeout = pTimeout->Seconds * 1000;
2021 0 : timeout += pTimeout->Nanosec / (1000 * 1000);
2022 : }
2023 :
2024 0 : result = poll (&fds, 1, timeout);
2025 0 : if (result < 0)
2026 : {
2027 0 : pSocket->m_nLastError = errno;
2028 : OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2029 : errno, strerror(errno));
2030 0 : return sal_False;
2031 : }
2032 0 : if (result == 0)
2033 : {
2034 : /* Timeout */
2035 0 : return sal_False;
2036 : }
2037 :
2038 0 : return ((fds.revents & nEvent) == nEvent);
2039 : }
2040 :
2041 : #else /* select() */
2042 :
2043 : sal_Bool __osl_socket_poll (
2044 : oslSocket pSocket,
2045 : const TimeValue* pTimeout,
2046 : short nEvent)
2047 : {
2048 : fd_set fds;
2049 : struct timeval tv;
2050 : int result;
2051 :
2052 : OSL_ASSERT(0 != pSocket);
2053 : if (0 == pSocket)
2054 : return sal_False; /* EINVAL */
2055 :
2056 : pSocket->m_nLastError = 0;
2057 :
2058 : FD_ZERO(&fds);
2059 : FD_SET(pSocket->m_Socket, &fds);
2060 :
2061 : if (pTimeout)
2062 : {
2063 : /* Convert to 'timeval' */
2064 : tv.tv_sec = pTimeout->Seconds;
2065 : tv.tv_usec = pTimeout->Nanosec / 1000;
2066 : }
2067 :
2068 : result = select (
2069 : pSocket->m_Socket + 1,
2070 : (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2071 : (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2072 : (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2073 : (pTimeout) ? &tv : NULL);
2074 :
2075 : if (result < 0)
2076 : {
2077 : pSocket->m_nLastError = errno;
2078 : OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2079 : errno, strerror(errno));
2080 : return sal_False;
2081 : }
2082 : if (result == 0)
2083 : {
2084 : /* Timeout */
2085 : return sal_False;
2086 : }
2087 :
2088 : return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2089 : }
2090 :
2091 : #endif /* HAVE_POLL_H */
2092 :
2093 0 : sal_Bool SAL_CALL osl_isReceiveReady (
2094 : oslSocket pSocket, const TimeValue* pTimeout)
2095 : {
2096 : OSL_ASSERT(pSocket);
2097 0 : if (pSocket == NULL)
2098 : {
2099 : /* ENOTSOCK */
2100 0 : return sal_False;
2101 : }
2102 :
2103 0 : return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2104 : }
2105 :
2106 0 : sal_Bool SAL_CALL osl_isSendReady (
2107 : oslSocket pSocket, const TimeValue* pTimeout)
2108 : {
2109 : OSL_ASSERT(pSocket);
2110 0 : if (pSocket == NULL)
2111 : {
2112 : /* ENOTSOCK */
2113 0 : return sal_False;
2114 : }
2115 :
2116 0 : return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2117 : }
2118 :
2119 0 : sal_Bool SAL_CALL osl_isExceptionPending (
2120 : oslSocket pSocket, const TimeValue* pTimeout)
2121 : {
2122 : OSL_ASSERT(pSocket);
2123 0 : if (pSocket == NULL)
2124 : {
2125 : /* ENOTSOCK */
2126 0 : return sal_False;
2127 : }
2128 :
2129 0 : return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2130 : }
2131 :
2132 0 : sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2133 : oslSocketDirection Direction)
2134 : {
2135 : int nRet;
2136 :
2137 : OSL_ASSERT(pSocket);
2138 0 : if ( pSocket == 0 )
2139 : {
2140 0 : return sal_False;
2141 : }
2142 :
2143 0 : pSocket->m_nLastError=0;
2144 :
2145 0 : nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2146 0 : if (nRet != 0 )
2147 : {
2148 0 : pSocket->m_nLastError=errno;
2149 : OSL_TRACE("shutdown error '%s'",strerror(errno));
2150 : }
2151 0 : return (nRet==0);
2152 : }
2153 :
2154 0 : sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2155 : oslSocketOptionLevel Level,
2156 : oslSocketOption Option,
2157 : void* pBuffer,
2158 : sal_uInt32 BufferLen)
2159 : {
2160 0 : socklen_t nOptLen = (socklen_t) BufferLen;
2161 :
2162 : OSL_ASSERT(pSocket);
2163 0 : if ( pSocket == 0 )
2164 : {
2165 0 : return -1;
2166 : }
2167 :
2168 0 : pSocket->m_nLastError=0;
2169 :
2170 0 : if(getsockopt(pSocket->m_Socket,
2171 0 : OPTION_LEVEL_TO_NATIVE(Level),
2172 0 : OPTION_TO_NATIVE(Option),
2173 : (sal_Char*)pBuffer,
2174 : &nOptLen) == -1)
2175 : {
2176 0 : pSocket->m_nLastError=errno;
2177 0 : return -1;
2178 : }
2179 :
2180 0 : return BufferLen;
2181 : }
2182 :
2183 0 : sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2184 : oslSocketOptionLevel Level,
2185 : oslSocketOption Option,
2186 : void* pBuffer,
2187 : sal_uInt32 BufferLen)
2188 : {
2189 : int nRet;
2190 :
2191 : OSL_ASSERT(pSocket);
2192 0 : if ( pSocket == 0 )
2193 : {
2194 0 : return sal_False;
2195 : }
2196 :
2197 0 : pSocket->m_nLastError=0;
2198 :
2199 0 : nRet = setsockopt(pSocket->m_Socket,
2200 0 : OPTION_LEVEL_TO_NATIVE(Level),
2201 0 : OPTION_TO_NATIVE(Option),
2202 : (sal_Char*)pBuffer,
2203 : BufferLen);
2204 :
2205 0 : if ( nRet < 0 )
2206 : {
2207 0 : pSocket->m_nLastError=errno;
2208 0 : return sal_False;
2209 : }
2210 :
2211 0 : return sal_True;
2212 : }
2213 :
2214 0 : sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2215 : sal_Bool On)
2216 : {
2217 : int flags;
2218 : int nRet;
2219 :
2220 : OSL_ASSERT(pSocket);
2221 0 : if ( pSocket == 0 )
2222 : {
2223 0 : return sal_False;
2224 : }
2225 :
2226 0 : pSocket->m_nLastError=0;
2227 :
2228 0 : flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2229 :
2230 0 : if (On)
2231 0 : flags |= O_NONBLOCK;
2232 : else
2233 0 : flags &= ~(O_NONBLOCK);
2234 :
2235 0 : nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2236 :
2237 0 : if ( nRet < 0 )
2238 : {
2239 0 : pSocket->m_nLastError=errno;
2240 0 : return sal_False;
2241 : }
2242 :
2243 0 : return sal_True;
2244 : }
2245 :
2246 0 : sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2247 : {
2248 : int flags;
2249 :
2250 : OSL_ASSERT(pSocket);
2251 0 : if ( pSocket == 0 )
2252 : {
2253 0 : return sal_False;
2254 : }
2255 :
2256 0 : pSocket->m_nLastError=0;
2257 :
2258 0 : flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2259 :
2260 0 : if (flags == -1 || !(flags & O_NONBLOCK))
2261 0 : return sal_False;
2262 : else
2263 0 : return sal_True;
2264 : }
2265 :
2266 0 : oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2267 : {
2268 0 : int Type=0;
2269 0 : socklen_t TypeSize= sizeof(Type);
2270 :
2271 : OSL_ASSERT(pSocket);
2272 0 : if ( pSocket == 0 )
2273 : {
2274 0 : return osl_Socket_TypeInvalid;
2275 : }
2276 :
2277 0 : pSocket->m_nLastError=0;
2278 :
2279 0 : if(getsockopt(pSocket->m_Socket,
2280 0 : OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2281 0 : OPTION_TO_NATIVE(osl_Socket_OptionType),
2282 : (sal_Char*)&Type,
2283 : &TypeSize) == -1)
2284 : {
2285 : /* error */
2286 0 : pSocket->m_nLastError=errno;
2287 0 : return osl_Socket_TypeInvalid;
2288 : }
2289 :
2290 0 : return TYPE_FROM_NATIVE(Type);
2291 :
2292 : }
2293 :
2294 0 : void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2295 : {
2296 : sal_Char pszError[1024];
2297 :
2298 0 : pszError[0] = '\0';
2299 :
2300 0 : osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2301 :
2302 0 : rtl_uString_newFromAscii(ustrError,pszError);
2303 :
2304 0 : return;
2305 : }
2306 :
2307 0 : void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2308 : {
2309 : /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2310 0 : pBuffer[BufferSize-1]= '\0';
2311 :
2312 0 : if ( pSocket == 0 )
2313 : {
2314 0 : strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2315 0 : return;
2316 : }
2317 :
2318 0 : strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2319 0 : return;
2320 : }
2321 :
2322 0 : oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2323 : {
2324 0 : if ( pSocket == 0 )
2325 : {
2326 0 : return ERROR_FROM_NATIVE(EINVAL);
2327 : }
2328 :
2329 0 : return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2330 : }
2331 :
2332 : typedef struct _TSocketSetImpl
2333 : {
2334 : int m_MaxHandle; /* for select(), the largest descriptor in the set */
2335 : fd_set m_Set; /* the set of descriptors */
2336 :
2337 : } TSocketSetImpl;
2338 :
2339 0 : oslSocketSet SAL_CALL osl_createSocketSet()
2340 : {
2341 : TSocketSetImpl* pSet;
2342 :
2343 0 : pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2344 :
2345 : OSL_ASSERT(pSet);
2346 :
2347 0 : if(pSet)
2348 : {
2349 0 : pSet->m_MaxHandle= 0;
2350 0 : FD_ZERO(&pSet->m_Set);
2351 : }
2352 :
2353 0 : return (oslSocketSet)pSet;
2354 : }
2355 :
2356 0 : void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2357 : {
2358 0 : if(Set)
2359 0 : free(Set);
2360 0 : }
2361 :
2362 0 : void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2363 : {
2364 : TSocketSetImpl* pSet;
2365 : OSL_ASSERT(Set);
2366 0 : if ( Set == 0 )
2367 : {
2368 0 : return;
2369 : }
2370 :
2371 0 : pSet= (TSocketSetImpl*)Set;
2372 0 : pSet->m_MaxHandle= 0;
2373 :
2374 0 : FD_ZERO(&pSet->m_Set);
2375 : }
2376 :
2377 0 : void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2378 : {
2379 : TSocketSetImpl* pSet;
2380 :
2381 : OSL_ASSERT(Set);
2382 : OSL_ASSERT(pSocket);
2383 :
2384 0 : if ( Set == 0 || pSocket == 0)
2385 : {
2386 0 : return;
2387 : }
2388 :
2389 0 : pSet= (TSocketSetImpl*)Set;
2390 :
2391 : /* correct max handle */
2392 0 : if(pSocket->m_Socket > pSet->m_MaxHandle)
2393 0 : pSet->m_MaxHandle= pSocket->m_Socket;
2394 0 : FD_SET(pSocket->m_Socket, &pSet->m_Set);
2395 :
2396 : }
2397 :
2398 0 : void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
2399 : {
2400 : TSocketSetImpl* pSet;
2401 :
2402 : OSL_ASSERT(Set);
2403 : OSL_ASSERT(pSocket);
2404 :
2405 0 : if ( Set == 0 || pSocket == 0)
2406 : {
2407 0 : return;
2408 : }
2409 :
2410 0 : pSet= (TSocketSetImpl*)Set;
2411 :
2412 : /* correct max handle */
2413 0 : if(pSocket->m_Socket == pSet->m_MaxHandle)
2414 : {
2415 : /* not optimal, since the next used descriptor might be */
2416 : /* much smaller than m_Socket-1, but it will do */
2417 0 : pSet->m_MaxHandle--;
2418 0 : if(pSet->m_MaxHandle < 0)
2419 : {
2420 0 : pSet->m_MaxHandle= 0; /* avoid underflow */
2421 : }
2422 : }
2423 :
2424 0 : FD_CLR(pSocket->m_Socket, &pSet->m_Set);
2425 : }
2426 :
2427 0 : sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
2428 : {
2429 : TSocketSetImpl* pSet;
2430 :
2431 : OSL_ASSERT(Set);
2432 : OSL_ASSERT(pSocket);
2433 0 : if ( Set == 0 || pSocket == 0 )
2434 : {
2435 0 : return sal_False;
2436 : }
2437 :
2438 0 : pSet= (TSocketSetImpl*)Set;
2439 :
2440 0 : return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
2441 : }
2442 :
2443 0 : sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
2444 : oslSocketSet OutgoingSet,
2445 : oslSocketSet OutOfBandSet,
2446 : const TimeValue* pTimeout)
2447 : {
2448 0 : int MaxHandle= 0;
2449 : struct timeval tv;
2450 : TSocketSetImpl* pInSet;
2451 : TSocketSetImpl* pOutSet;
2452 : TSocketSetImpl* pOOBSet;
2453 :
2454 0 : if (pTimeout)
2455 : {
2456 : /* non-blocking call */
2457 0 : tv.tv_sec = pTimeout->Seconds;
2458 0 : tv.tv_usec = pTimeout->Nanosec / 1000L;
2459 : }
2460 :
2461 : /* map opaque data to impl-types */
2462 0 : pInSet= (TSocketSetImpl*)IncomingSet;
2463 0 : pOutSet= (TSocketSetImpl*)OutgoingSet;
2464 0 : pOOBSet= (TSocketSetImpl*)OutOfBandSet;
2465 :
2466 : /* get max handle from all sets */
2467 0 : if (pInSet)
2468 0 : MaxHandle= pInSet->m_MaxHandle;
2469 :
2470 0 : if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
2471 0 : MaxHandle= pOutSet->m_MaxHandle;
2472 :
2473 0 : if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
2474 0 : MaxHandle= pOOBSet->m_MaxHandle;
2475 :
2476 0 : return select(MaxHandle+1,
2477 : pInSet ? PTR_FD_SET(pInSet->m_Set) : 0,
2478 : pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
2479 : pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
2480 : pTimeout ? &tv : 0);
2481 : }
2482 :
2483 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|