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