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