Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
ebd00f5c
Kaydet (Commit)
ebd00f5c
authored
Mar 30, 2001
tarafından
Oliver Braun
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
socket.cxx -> socket.c
üst
1db2b85d
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
3112 additions
and
0 deletions
+3112
-0
socket.c
sal/osl/unx/socket.c
+3112
-0
No files found.
sal/osl/unx/socket.c
0 → 100644
Dosyayı görüntüle @
ebd00f5c
/*************************************************************************
*
* $RCSfile: socket.c,v $
*
* $Revision: 1.10 $
*
* last change: $Author: obr $ $Date: 2001-03-30 16:49:12 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#include "system.h"
#include <osl/socket.h>
#include <osl/diagnose.h>
#include <osl/mutex.h>
#include <osl/signal.h>
#include <rtl/alloc.h>
#include <ctype.h>
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#include "sockimpl.h"
/* defines for shutdown */
#define SD_RECEIVE 0
#define SD_SEND 1
#define SD_BOTH 2
/*
oslSocketAddr is a pointer to a Berkeley struct sockaddr.
I refrained from using sockaddr_in because of possible further
extensions of this socket-interface (IP-NG?).
The intention was to hide all Berkeley data-structures from
direct access past the osl-interface.
The current implementation is internet (IP) centered. All
the constructor-functions (osl_create...) take parameters
that will probably make sense only in the IP-environment
(e.g. because of using the dotted-address-format).
If the interface will be extended to host other protocol-
families, I expect no externally visible changes in the
existing functions. You'll probably need only new
constructor-functions who take the different address
formats into consideration (maybe a long dotted address
or whatever).
*/
/* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
/* are the same! I don't like it very much but see no other easy way to */
/* conceal the struct sockaddr from the eyes of the user. */
#define OSL_INVALID_SOCKET -1
#define OSL_SOCKET_ERROR -1
/*****************************************************************************/
/* enum oslAddrFamily */
/*****************************************************************************/
/* map */
static
unsigned
long
FamilyMap
[]
=
{
AF_INET
,
/* osl_Socket_FamilyInet */
AF_IPX
,
/* osl_Socket_FamilyIpx */
0
/* osl_Socket_FamilyInvalid */
};
/* reverse map */
static
oslAddrFamily
osl_AddrFamilyFromNative
(
sal_uInt32
nativeType
)
{
oslAddrFamily
i
=
(
oslAddrFamily
)
0
;
while
(
i
!=
osl_Socket_FamilyInvalid
)
{
if
(
FamilyMap
[
i
]
==
nativeType
)
return
i
;
i
=
(
oslAddrFamily
)
(
i
+
1
);
}
return
i
;
}
/* macros */
#define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
#define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
/*****************************************************************************/
/* enum oslProtocol */
/*****************************************************************************/
/* map */
static
sal_uInt32
ProtocolMap
[]
=
{
0
,
/* osl_Socket_ProtocolIp */
NSPROTO_IPX
,
/* osl_Socket_ProtocolIpx */
NSPROTO_SPX
,
/* osl_Socket_ProtocolSpx */
NSPROTO_SPXII
,
/* osl_Socket_ProtocolSpxII */
0
/* osl_Socket_ProtocolInvalid */
};
/* reverse map */
/* mfe: NOT USED
static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
{
oslProtocol i= (oslProtocol)0;
while(i != osl_Socket_ProtocolInvalid)
{
if(ProtocolMap[i] == nativeType)
return i;
i = (oslProtocol) ( i + 1);
}
return i;
}
*/
/* macros */
#define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
#define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
/*****************************************************************************/
/* enum oslSocketType */
/*****************************************************************************/
/* map */
static
sal_uInt32
TypeMap
[]
=
{
SOCK_STREAM
,
/* osl_Socket_TypeStream */
SOCK_DGRAM
,
/* osl_Socket_TypeDgram */
SOCK_RAW
,
/* osl_Socket_TypeRaw */
SOCK_RDM
,
/* osl_Socket_TypeRdm */
SOCK_SEQPACKET
,
/* osl_Socket_TypeSeqPacket */
0
/* osl_Socket_TypeInvalid */
};
/* reverse map */
static
oslSocketType
osl_SocketTypeFromNative
(
sal_uInt32
nativeType
)
{
oslSocketType
i
=
(
oslSocketType
)
0
;
while
(
i
!=
osl_Socket_TypeInvalid
)
{
if
(
TypeMap
[
i
]
==
nativeType
)
return
i
;
i
=
(
oslSocketType
)(
i
+
1
);
}
return
i
;
}
/* macros */
#define TYPE_TO_NATIVE(x) TypeMap[x]
#define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
/*****************************************************************************/
/* enum oslSocketOption */
/*****************************************************************************/
/* map */
static
sal_uInt32
OptionMap
[]
=
{
SO_DEBUG
,
/* osl_Socket_OptionDebug */
SO_ACCEPTCONN
,
/* osl_Socket_OptionAcceptConn */
SO_REUSEADDR
,
/* osl_Socket_OptionReuseAddr */
SO_KEEPALIVE
,
/* osl_Socket_OptionKeepAlive */
SO_DONTROUTE
,
/* osl_Socket_OptionDontRoute */
SO_BROADCAST
,
/* osl_Socket_OptionBroadcast */
SO_USELOOPBACK
,
/* osl_Socket_OptionUseLoopback */
SO_LINGER
,
/* osl_Socket_OptionLinger */
SO_OOBINLINE
,
/* osl_Socket_OptionOOBinLine */
SO_SNDBUF
,
/* osl_Socket_OptionSndBuf */
SO_RCVBUF
,
/* osl_Socket_OptionRcvBuf */
SO_SNDLOWAT
,
/* osl_Socket_OptionSndLowat */
SO_RCVLOWAT
,
/* osl_Socket_OptionRcvLowat */
SO_SNDTIMEO
,
/* osl_Socket_OptionSndTimeo */
SO_RCVTIMEO
,
/* osl_Socket_OptionRcvTimeo */
SO_ERROR
,
/* osl_Socket_OptionError */
SO_TYPE
,
/* osl_Socket_OptionType */
TCP_NODELAY
,
/* osl_Socket_OptionTcpNoDelay */
0
/* osl_Socket_OptionInvalid */
};
/* reverse map */
/* mfe: NOT USED
static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
{
oslSocketOption i= (oslSocketOption)0;
while(i != osl_Socket_OptionInvalid)
{
if(OptionMap[i] == nativeType)
return i;
i = (oslSocketOption) ( i + 1 );
}
return i;
}
*/
/* macros */
#define OPTION_TO_NATIVE(x) OptionMap[x]
#define OPTION_FROM_NATIVE(y) osl_SocketOptionFromNative(y)
/*****************************************************************************/
/* enum oslSocketOptionLevel */
/*****************************************************************************/
static
sal_uInt32
OptionLevelMap
[]
=
{
SOL_SOCKET
,
/* osl_Socket_LevelSocket */
IPPROTO_TCP
,
/* osl_Socket_LevelTcp */
0
/* osl_Socket_LevelInvalid */
};
/* reverse map */
/* mfe: NOT USED
static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
{
oslSocketOptionLevel i= (oslSocketOptionLevel)0;
while(i != osl_Socket_LevelInvalid)
{
if(OptionLevelMap[i] == nativeType)
return i;
i = (oslSocketOptionLevel) ( i + 1 );
}
return i;
}
*/
/* macros */
#define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
#define OPTION_LEVEL_FROM_NATIVE(y) osl_SocketOptionLevelFromNative(y)
/*****************************************************************************/
/* enum oslSocketMsgFlag */
/*****************************************************************************/
static
sal_uInt32
SocketMsgFlagMap
[]
=
{
0
,
/* osl_Socket_MsgNormal */
MSG_OOB
,
/* osl_Socket_MsgOOB */
MSG_PEEK
,
/* osl_Socket_MsgPeek */
MSG_DONTROUTE
,
/* osl_Socket_MsgDontRoute */
MSG_MAXIOVLEN
,
/* osl_Socket_MsgMaxIOVLen */
0
/* osl_Socket_MsgInvalid */
};
/* reverse map */
/* mfe: NOT USED
static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
{
oslSocketMsgFlag i= (oslSocketMsgFlag)0;
while(i != osl_Socket_MsgInvalid)
{
if(SocketMsgFlagMap[i] == nativeType)
return i;
i = (oslSocketMsgFlag) ( i + 1 );
}
return i;
}
*/
/* macros */
#define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
#define MSG_FLAG_FROM_NATIVE(y) osl_SocketMsgFlagFromNative(y)
/*****************************************************************************/
/* enum oslSocketDirection */
/*****************************************************************************/
static
sal_uInt32
SocketDirection
[]
=
{
SD_RECEIVE
,
/* osl_Socket_DirRead */
SD_SEND
,
/* osl_Socket_DirWrite */
SD_BOTH
,
/* osl_Socket_DirReadWrite */
0
/* osl_Socket_DirInvalid */
};
/* reverse map */
/* mfe: NOT USED
static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
{
oslSocketDirection i= (oslSocketDirection)0;
while(i != osl_Socket_DirInvalid)
{
if(SocketDirection[i] == nativeType)
return i;
i = (oslSocketDirection) ( i + 1 );
}
return i;
}
*/
/* macros */
#define DIRECTION_TO_NATIVE(x) SocketDirection[x]
#define DIRECTION_FROM_NATIVE(y) osl_SocketDirectionFromNative(y)
/*****************************************************************************/
/* enum oslSocketError */
/*****************************************************************************/
static
struct
{
int
errcode
;
oslSocketError
error
;
}
SocketError
[]
=
{
{
0
,
osl_Socket_E_None
},
/* no error */
{
ENOTSOCK
,
osl_Socket_E_NotSocket
},
/* Socket operation on non-socket */
{
EDESTADDRREQ
,
osl_Socket_E_DestAddrReq
},
/* Destination address required */
{
EMSGSIZE
,
osl_Socket_E_MsgSize
},
/* Message too long */
{
EPROTOTYPE
,
osl_Socket_E_Prototype
},
/* Protocol wrong type for socket */
{
ENOPROTOOPT
,
osl_Socket_E_NoProtocol
},
/* Protocol not available */
{
EPROTONOSUPPORT
,
osl_Socket_E_ProtocolNoSupport
},
/* Protocol not supported */
{
ESOCKTNOSUPPORT
,
osl_Socket_E_TypeNoSupport
},
/* Socket type not supported */
{
EOPNOTSUPP
,
osl_Socket_E_OpNotSupport
},
/* Operation not supported on socket */
{
EPFNOSUPPORT
,
osl_Socket_E_PfNoSupport
},
/* Protocol family not supported */
{
EAFNOSUPPORT
,
osl_Socket_E_AfNoSupport
},
/* Address family not supported by */
/* protocol family */
{
EADDRINUSE
,
osl_Socket_E_AddrInUse
},
/* Address already in use */
{
EADDRNOTAVAIL
,
osl_Socket_E_AddrNotAvail
},
/* Can't assign requested address */
{
ENETDOWN
,
osl_Socket_E_NetDown
},
/* Network is down */
{
ENETUNREACH
,
osl_Socket_E_NetUnreachable
},
/* Network is unreachable */
{
ENETRESET
,
osl_Socket_E_NetReset
},
/* Network dropped connection because */
/* of reset */
{
ECONNABORTED
,
osl_Socket_E_ConnAborted
},
/* Software caused connection abort */
{
ECONNRESET
,
osl_Socket_E_ConnReset
},
/* Connection reset by peer */
{
ENOBUFS
,
osl_Socket_E_NoBufferSpace
},
/* No buffer space available */
{
EISCONN
,
osl_Socket_E_IsConnected
},
/* Socket is already connected */
{
ENOTCONN
,
osl_Socket_E_NotConnected
},
/* Socket is not connected */
{
ESHUTDOWN
,
osl_Socket_E_Shutdown
},
/* Can't send after socket shutdown */
{
ETOOMANYREFS
,
osl_Socket_E_TooManyRefs
},
/* Too many references: can't splice */
{
ETIMEDOUT
,
osl_Socket_E_TimedOut
},
/* Connection timed out */
{
ECONNREFUSED
,
osl_Socket_E_ConnRefused
},
/* Connection refused */
{
EHOSTDOWN
,
osl_Socket_E_HostDown
},
/* Host is down */
{
EHOSTUNREACH
,
osl_Socket_E_HostUnreachable
},
/* No route to host */
{
EWOULDBLOCK
,
osl_Socket_E_WouldBlock
},
/* call would block on non-blocking socket */
{
EALREADY
,
osl_Socket_E_Already
},
/* operation already in progress */
{
EINPROGRESS
,
osl_Socket_E_InProgress
},
/* operation now in progress */
{
EAGAIN
,
osl_Socket_E_WouldBlock
},
/* same as EWOULDBLOCK */
{
-
1
,
osl_Socket_E_InvalidError
}
};
/* map */
/* mfe: NOT USED
static int osl_NativeFromSocketError(oslSocketError errorCode)
{
int i = 0;
while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
(SocketError[i].error != errorCode)) i++;
return SocketError[i].errcode;
}
*/
/* reverse map */
static
oslSocketError
osl_SocketErrorFromNative
(
int
nativeType
)
{
int
i
=
0
;
while
((
SocketError
[
i
].
error
!=
osl_Socket_E_InvalidError
)
&&
(
SocketError
[
i
].
errcode
!=
nativeType
))
i
++
;
return
SocketError
[
i
].
error
;
}
/* macros */
#define ERROR_TO_NATIVE(x) osl_NativeFromSocketError(x)
#define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
/*****************************************************************************/
/* local function prototypes */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_psz_createInetSocketAddr
(
const
sal_Char
*
pszDottedAddr
,
sal_Int32
Port
);
oslSocketAddr
SAL_CALL
osl_psz_createIpxSocketAddr
(
const
sal_Char
NetNumber
[
4
],
const
sal_Char
NodeNumber
[
6
],
sal_uInt32
SocketNumber
);
oslHostAddr
SAL_CALL
osl_psz_createHostAddr
(
const
sal_Char
*
pszHostname
,
const
oslSocketAddr
Addr
);
oslHostAddr
SAL_CALL
osl_psz_createHostAddrByName
(
const
sal_Char
*
pszHostname
);
const
sal_Char
*
SAL_CALL
osl_psz_getHostnameOfHostAddr
(
const
oslHostAddr
Addr
);
oslSocketResult
SAL_CALL
osl_psz_getLocalHostname
(
sal_Char
*
pBuffer
,
sal_uInt32
nBufLen
);
oslSocketAddr
SAL_CALL
osl_psz_resolveHostname
(
const
sal_Char
*
pszHostname
);
sal_Int32
SAL_CALL
osl_psz_getServicePort
(
const
sal_Char
*
pszServicename
,
const
sal_Char
*
pszProtocol
);
oslSocketResult
SAL_CALL
osl_psz_getHostnameOfSocketAddr
(
oslSocketAddr
Addr
,
sal_Char
*
pBuffer
,
sal_uInt32
BufferSize
);
oslSocketResult
SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr
(
oslSocketAddr
Addr
,
sal_Char
*
pBuffer
,
sal_uInt32
BufferSize
);
void
SAL_CALL
osl_psz_getLastSocketErrorDescription
(
oslSocket
Socket
,
sal_Char
*
pBuffer
,
sal_uInt32
BufferSize
);
/*****************************************************************************/
/* osl_create/destroy-SocketImpl */
/*****************************************************************************/
#ifdef DEBUG
static
sal_uInt32
g_nSocketImpl
=
0
;
static
sal_uInt32
g_nSocketAddr
=
0
;
/* sorry, must be implemented otherwise */
#if 0
struct LeakWarning
{
~LeakWarning()
{
if( g_nSocketImpl )
OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl );
if( g_nSocketAddr )
OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr );
}
};
LeakWarning socketWarning;
#endif
#endif
oslSocket
__osl_createSocketImpl
(
int
Socket
)
{
oslSocket
pSocket
;
pSocket
=
(
oslSocket
)
calloc
(
1
,
sizeof
(
struct
oslSocketImpl
));
pSocket
->
m_Socket
=
Socket
;
pSocket
->
m_nLastError
=
0
;
pSocket
->
m_CloseCallback
=
0
;
pSocket
->
m_CallbackArg
=
0
;
pSocket
->
m_nRefCount
=
1
;
#if defined(LINUX)
pSocket
->
m_bIsAccepting
=
sal_False
;
#endif
#ifdef DEBUG
g_nSocketImpl
++
;
#endif
return
pSocket
;
}
void
__osl_destroySocketImpl
(
oslSocket
Socket
)
{
if
(
Socket
!=
NULL
)
free
((
struct
oslSocketImpl
*
)
Socket
);
#ifdef DEBUG
g_nSocketImpl
--
;
#endif
}
static
oslSocketAddr
__osl_createSocketAddr
(
)
{
oslSocketAddr
pAddr
=
(
oslSocketAddr
)
rtl_allocateZeroMemory
(
sizeof
(
struct
oslSocketAddrImpl
));
#ifdef DEBUG
g_nSocketAddr
++
;
#endif
return
pAddr
;
}
static
oslSocketAddr
__osl_createSocketAddrWithFamily
(
oslAddrFamily
family
,
sal_Int32
port
,
sal_uInt32
nAddr
)
{
oslSocketAddr
pAddr
;
OSL_ASSERT
(
family
==
osl_Socket_FamilyInet
);
pAddr
=
__osl_createSocketAddr
();
switch
(
family
)
{
case
osl_Socket_FamilyInet
:
{
struct
sockaddr_in
*
pInetAddr
=
(
struct
sockaddr_in
*
)
&
(
pAddr
->
m_sockaddr
);
pInetAddr
->
sin_family
=
FAMILY_TO_NATIVE
(
osl_Socket_FamilyInet
);
pInetAddr
->
sin_addr
.
s_addr
=
nAddr
;
pInetAddr
->
sin_port
=
(
sal_uInt16
)(
port
&
0xffff
);
break
;
}
default:
pAddr
->
m_sockaddr
.
sa_family
=
FAMILY_TO_NATIVE
(
family
);
}
return
pAddr
;
}
static
oslSocketAddr
__osl_createSocketAddrFromSystem
(
struct
sockaddr
*
pSystemSockAddr
)
{
oslSocketAddr
pAddr
=
__osl_createSocketAddr
();
memcpy
(
&
(
pAddr
->
m_sockaddr
),
pSystemSockAddr
,
sizeof
(
struct
sockaddr
)
);
return
pAddr
;
}
static
void
__osl_destroySocketAddr
(
oslSocketAddr
addr
)
{
#ifdef DEBUG
g_nSocketAddr
--
;
#endif
rtl_freeMemory
(
addr
);
}
/*****************************************************************************/
/* osl_createEmptySocketAddr */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_createEmptySocketAddr
(
oslAddrFamily
Family
)
{
oslSocketAddr
pAddr
=
0
;
/* is it an internet-Addr? */
if
(
Family
==
osl_Socket_FamilyInet
)
{
pAddr
=
__osl_createSocketAddrWithFamily
(
Family
,
0
,
htonl
(
INADDR_ANY
)
);
}
else
{
pAddr
=
__osl_createSocketAddrWithFamily
(
Family
,
0
,
0
);
}
return
pAddr
;
}
/*****************************************************************************/
/* osl_copySocketAddr */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_copySocketAddr
(
oslSocketAddr
Addr
)
{
oslSocketAddr
pCopy
=
0
;
if
(
Addr
)
{
pCopy
=
__osl_createSocketAddr
();
if
(
pCopy
)
memcpy
(
&
(
pCopy
->
m_sockaddr
),
&
(
Addr
->
m_sockaddr
),
sizeof
(
struct
sockaddr
));
}
return
pCopy
;
}
/*****************************************************************************/
/* osl_isEqualSocketAddr */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_isEqualSocketAddr
(
oslSocketAddr
Addr1
,
oslSocketAddr
Addr2
)
{
struct
sockaddr
*
pAddr1
=
&
(
Addr1
->
m_sockaddr
);
struct
sockaddr
*
pAddr2
=
&
(
Addr2
->
m_sockaddr
);
OSL_ASSERT
(
pAddr1
);
OSL_ASSERT
(
pAddr2
);
if
(
pAddr1
->
sa_family
==
pAddr2
->
sa_family
)
{
switch
(
pAddr1
->
sa_family
)
{
case
AF_INET
:
{
struct
sockaddr_in
*
pInetAddr1
=
(
struct
sockaddr_in
*
)
pAddr1
;
struct
sockaddr_in
*
pInetAddr2
=
(
struct
sockaddr_in
*
)
pAddr2
;
if
((
pInetAddr1
->
sin_family
==
pInetAddr2
->
sin_family
)
&&
(
pInetAddr1
->
sin_addr
.
s_addr
==
pInetAddr2
->
sin_addr
.
s_addr
)
&&
(
pInetAddr1
->
sin_port
==
pInetAddr2
->
sin_port
))
return
(
sal_True
);
}
default:
{
return
(
memcmp
(
pAddr1
,
Addr2
,
sizeof
(
struct
sockaddr
))
==
0
);
}
}
}
return
(
sal_False
);
}
/*****************************************************************************/
/* osl_createInetBroadcastAddr */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_createInetBroadcastAddr
(
rtl_uString
*
strDottedAddr
,
sal_Int32
Port
)
{
sal_uInt32
nAddr
=
OSL_INADDR_NONE
;
oslSocketAddr
pAddr
;
if
(
strDottedAddr
&&
strDottedAddr
->
length
)
{
/* Dotted host address for limited broadcast */
rtl_String
*
pDottedAddr
=
NULL
;
rtl_uString2String
(
&
pDottedAddr
,
strDottedAddr
->
buffer
,
strDottedAddr
->
length
,
RTL_TEXTENCODING_UTF8
,
OUSTRING_TO_OSTRING_CVTFLAGS
);
nAddr
=
inet_addr
(
pDottedAddr
->
buffer
);
rtl_string_release
(
pDottedAddr
);
}
if
(
nAddr
!=
OSL_INADDR_NONE
)
{
/* Limited broadcast */
nAddr
=
ntohl
(
nAddr
);
if
(
IN_CLASSA
(
nAddr
))
{
nAddr
&=
IN_CLASSA_NET
;
nAddr
|=
IN_CLASSA_HOST
;
}
else
if
(
IN_CLASSB
(
nAddr
))
{
nAddr
&=
IN_CLASSB_NET
;
nAddr
|=
IN_CLASSB_HOST
;
}
else
if
(
IN_CLASSC
(
nAddr
))
{
nAddr
&=
IN_CLASSC_NET
;
nAddr
|=
IN_CLASSC_HOST
;
}
else
{
/* No broadcast in class D */
return
((
oslSocketAddr
)
NULL
);
}
nAddr
=
htonl
(
nAddr
);
}
pAddr
=
__osl_createSocketAddrWithFamily
(
osl_Socket_FamilyInet
,
Port
,
nAddr
);
return
pAddr
;
}
/*****************************************************************************/
/* osl_createInetSocketAddr */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_createInetSocketAddr
(
rtl_uString
*
ustrDottedAddr
,
sal_Int32
Port
)
{
rtl_String
*
strDottedAddr
=
0
;
oslSocketAddr
Addr
;
sal_Char
*
pszDottedAddr
=
0
;
if
(
ustrDottedAddr
!=
0
)
{
rtl_uString2String
(
&
strDottedAddr
,
rtl_uString_getStr
(
ustrDottedAddr
),
rtl_uString_getLength
(
ustrDottedAddr
),
RTL_TEXTENCODING_UTF8
,
OUSTRING_TO_OSTRING_CVTFLAGS
);
pszDottedAddr
=
rtl_string_getStr
(
strDottedAddr
);
}
Addr
=
osl_psz_createInetSocketAddr
(
pszDottedAddr
,
Port
);
if
(
strDottedAddr
!=
0
)
{
rtl_string_release
(
strDottedAddr
);
}
return
Addr
;
}
oslSocketAddr
SAL_CALL
osl_psz_createInetSocketAddr
(
const
sal_Char
*
pszDottedAddr
,
sal_Int32
Port
)
{
oslSocketAddr
pAddr
=
0
;
sal_Int32
Addr
=
inet_addr
(
pszDottedAddr
);
if
(
Addr
!=
-
1
)
{
/* valid dotted addr */
pAddr
=
__osl_createSocketAddrWithFamily
(
osl_Socket_FamilyInet
,
Port
,
Addr
);
}
return
pAddr
;
}
/*****************************************************************************/
/* osl_setAddrOfSocketAddr */
/*****************************************************************************/
oslSocketResult
SAL_CALL
osl_setAddrOfSocketAddr
(
oslSocketAddr
pAddr
,
sal_Sequence
*
pByteSeq
)
{
oslSocketResult
res
=
osl_Socket_Error
;
OSL_ASSERT
(
pAddr
);
OSL_ASSERT
(
pByteSeq
);
if
(
pAddr
&&
pByteSeq
)
{
struct
sockaddr_in
*
pSystemInetAddr
;
OSL_ASSERT
(
pAddr
->
m_sockaddr
.
sa_family
==
FAMILY_TO_NATIVE
(
osl_Socket_FamilyInet
)
);
OSL_ASSERT
(
pByteSeq
->
nElements
==
4
);
pSystemInetAddr
=
(
struct
sockaddr_in
*
)
&
(
pAddr
->
m_sockaddr
);
memcpy
(
&
(
pSystemInetAddr
->
sin_addr
)
,
pByteSeq
->
elements
,
4
);
res
=
osl_Socket_Ok
;
}
return
res
;
}
/*****************************************************************************/
/* osl_getAddrOfSocketAddr */
/*****************************************************************************/
oslSocketResult
SAL_CALL
osl_getAddrOfSocketAddr
(
oslSocketAddr
pAddr
,
sal_Sequence
**
ppByteSeq
)
{
oslSocketResult
res
=
osl_Socket_Error
;
OSL_ASSERT
(
pAddr
);
OSL_ASSERT
(
ppByteSeq
);
if
(
pAddr
&&
ppByteSeq
)
{
struct
sockaddr_in
*
pSystemInetAddr
=
(
struct
sockaddr_in
*
)
&
(
pAddr
->
m_sockaddr
);
rtl_byte_sequence_constructFromArray
(
ppByteSeq
,
(
sal_Int8
*
)
&
(
pSystemInetAddr
->
sin_addr
),
4
);
res
=
osl_Socket_Ok
;
}
return
res
;
}
/*****************************************************************************/
/* _osl_getFullQualifiedDomainName */
/*****************************************************************************/
/** try to figure out a full-qualified hostname, by adding the current domain
as given by the domainname program to the given hostname.
This function MUST NOT call gethostbyname since pHostName allready points
to data returned by gethostname and would be garbled: use gethostname_r
instead!
*/
/* wrap around different interfaces to reentrant gethostbyname */
static
struct
hostent
*
_osl_gethostbyname_r
(
const
char
*
name
,
struct
hostent
*
result
,
char
*
buffer
,
int
buflen
,
int
*
h_errnop
)
{
#ifdef LINUX
struct
hostent
*
__result
;
/* will be the same as result */
int
__error
;
__error
=
gethostbyname_r
(
name
,
result
,
buffer
,
buflen
,
&
__result
,
h_errnop
);
return
__error
?
NULL
:
__result
;
#else
return
gethostbyname_r
(
name
,
result
,
buffer
,
buflen
,
h_errnop
);
#endif
}
static
sal_Bool
_osl_getDomainName
(
sal_Char
*
buffer
,
sal_Int32
bufsiz
)
{
sal_Bool
result
;
int
p
[
2
];
result
=
sal_False
;
if
(
pipe
(
p
)
==
0
)
{
pid_t
pid
;
int
nStatus
;
pid
=
fork
();
if
(
pid
==
0
)
{
char
*
argv
[]
=
{
"/bin/domainname"
,
NULL
};
close
(
p
[
0
]);
dup2
(
p
[
1
],
1
);
close
(
p
[
1
]);
if
(
execvp
(
"/bin/domainname"
,
argv
)
<
0
)
{
exit
(
-
1
);
}
}
else
if
(
pid
>
0
)
{
sal_Int32
k
=
0
,
n
=
bufsiz
;
close
(
p
[
1
]);
if
((
k
=
read
(
p
[
0
],
buffer
,
n
-
1
))
>
0
)
{
buffer
[
k
]
=
0
;
if
(
buffer
[
k
-
1
]
==
'\n'
)
buffer
[
k
-
1
]
=
0
;
result
=
sal_True
;
}
close
(
p
[
0
]);
}
else
{
close
(
p
[
0
]);
close
(
p
[
1
]);
}
waitpid
(
pid
,
&
nStatus
,
0
);
}
return
(
result
);
}
static
sal_Char
*
_osl_getFullQualifiedDomainName
(
const
sal_Char
*
pHostName
)
{
# define DOMAINNAME_LENGTH 512
sal_uInt32
nLengthOfHostName
;
static
sal_uInt32
nLengthOfDomainName
=
0
;
static
sal_Char
*
pDomainName
=
NULL
;
sal_Char
*
pFullQualifiedName
;
#if 0 /* OBSOLETE */
FILE *pPipeToDomainnameExe;
#endif /* OBSOLETE */
/* get a '\0' terminated domainname */
/* read default domainname default from environment */
if
(
nLengthOfDomainName
==
0
)
{
sal_Char
*
pEnvDomain
;
pEnvDomain
=
getenv
(
"STAR_OVERRIDE_DOMAINNAME"
);
if
(
pEnvDomain
)
{
pDomainName
=
strdup
(
pEnvDomain
);
nLengthOfDomainName
=
strlen
(
pDomainName
);
}
}
#if 1
/* NEW */
if
(
nLengthOfDomainName
==
0
)
{
sal_Char
pDomainNameBuffer
[
DOMAINNAME_LENGTH
];
pDomainNameBuffer
[
0
]
=
'\0'
;
if
(
_osl_getDomainName
(
pDomainNameBuffer
,
DOMAINNAME_LENGTH
))
{
pDomainName
=
strdup
(
pDomainNameBuffer
);
nLengthOfDomainName
=
strlen
(
pDomainName
);
}
}
#endif
/* NEW */
#if 0 /* OBSOLETE */
#ifdef SCO
/* call 'domainname > /usr/tmp/some-tmp-file', since
popen read pclose do block or core-dump,
(even the pipe-stuff that comes with pthreads) */
if (nLengthOfDomainName == 0)
{
sal_Char tmp_name[ L_tmpnam ];
FILE *tmp_file;
sal_Char domain_call [ L_tmpnam + 16 ] = "domainname > ";
tmp_name[0] = '\0';
tmpnam ( tmp_name );
strcat ( domain_call, tmp_name );
if ( (system ( domain_call ) == 0)
&& ((tmp_file = fopen( tmp_name, "r" )) != NULL ) )
{
sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
pDomainNameBuffer[0] = '\0';
if ( fgets ( pDomainNameBuffer, DOMAINNAME_LENGTH, tmp_file ) )
{
pDomainName = strdup( pDomainNameBuffer );
nLengthOfDomainName = strlen( pDomainName );
if ( ( nLengthOfDomainName > 0 )
&& ( pDomainName[ nLengthOfDomainName - 1] == '\n' ) )
pDomainName[ --nLengthOfDomainName ] = '\0';
}
fclose ( tmp_file );
}
unlink( tmp_name );
}
#else /* !SCO */
/* read the domainname from pipe to the program domainname */
if ( (nLengthOfDomainName == 0)
&& (pPipeToDomainnameExe = popen( "domainname", "r")) )
{
sal_Char c;
sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
sal_Char *pDomainNamePointer;
pDomainNameBuffer[0] = '\0';
pDomainNamePointer = pDomainNameBuffer;
while ( ((c = getc( pPipeToDomainnameExe )) != EOF)
&& (nLengthOfDomainName < (DOMAINNAME_LENGTH - 1)) )
{
if (! isspace(c))
{
nLengthOfDomainName++ ;
*pDomainNamePointer++ = (sal_Char)c;
}
}
*pDomainNamePointer = '\0';
pDomainName = strdup( pDomainNameBuffer );
pclose( pPipeToDomainnameExe );
}
#endif /* !SCO */
#endif
/* OBSOLETE */
/* compose hostname and domainname */
nLengthOfHostName
=
strlen
(
pHostName
);
pFullQualifiedName
=
(
sal_Char
*
)
malloc
(
(
nLengthOfHostName
+
1
+
nLengthOfDomainName
+
1
)
*
sizeof
(
sal_Char
)
);
memcpy
(
pFullQualifiedName
,
pHostName
,
(
nLengthOfHostName
+
1
)
*
sizeof
(
sal_Char
)
);
if
(
nLengthOfDomainName
>
0
)
{
/* fqdn = hostname + '.' + domainname + '\0' */
pFullQualifiedName
[
nLengthOfHostName
]
=
'.'
;
memcpy
(
pFullQualifiedName
+
nLengthOfHostName
+
1
,
pDomainName
,
nLengthOfDomainName
+
1
);
}
/* check whether full-qualified name and hostname point to the same host
* should almost always be true */
if
(
nLengthOfDomainName
>
0
)
{
struct
hostent
*
pQualifiedHostByName
;
struct
hostent
*
pHostByName
;
sal_Bool
bHostsAreEqual
;
/* buffer for calls to reentrant version of gethostbyname */
struct
hostent
aHostByName
,
aQualifiedHostByName
;
sal_Char
pHostBuffer
[
256
];
sal_Char
pQualifiedHostBuffer
[
256
];
int
nErrorNo
;
pHostBuffer
[
0
]
=
'\0'
;
pQualifiedHostBuffer
[
0
]
=
'\0'
;
/* get list of addresses */
pQualifiedHostByName
=
_osl_gethostbyname_r
(
pFullQualifiedName
,
&
aQualifiedHostByName
,
pQualifiedHostBuffer
,
sizeof
(
pQualifiedHostBuffer
),
&
nErrorNo
);
pHostByName
=
_osl_gethostbyname_r
(
pHostName
,
&
aHostByName
,
pHostBuffer
,
sizeof
(
pHostBuffer
),
&
nErrorNo
);
/* compare addresses */
bHostsAreEqual
=
sal_False
;
if
(
pQualifiedHostByName
&&
pHostByName
)
{
sal_Char
**
p
,
**
q
;
struct
in_addr
in
;
/* lists are expected to be (very) short */
for
(
p
=
pQualifiedHostByName
->
h_addr_list
;
*
p
!=
NULL
;
p
++
)
{
for
(
q
=
pHostByName
->
h_addr_list
;
*
q
!=
NULL
;
q
++
)
{
/* in.s_addr may be in_addr_t or uint32_t or heaven knows */
if
(
memcmp
(
*
p
,
*
q
,
sizeof
(
in
.
s_addr
)
)
==
0
)
{
bHostsAreEqual
=
sal_True
;
break
;
}
}
if
(
bHostsAreEqual
)
break
;
}
}
/* very strange case, but have to believe it: reduce the
* full qualified name to the unqualified host name */
if
(
!
bHostsAreEqual
)
{
OSL_TRACE
(
"_osl_getFullQualifiedDomainName: "
"suspect FQDN: %s
\n
"
,
pFullQualifiedName
);
pFullQualifiedName
[
nLengthOfHostName
]
=
'\0'
;
pFullQualifiedName
=
(
sal_Char
*
)
realloc
(
pFullQualifiedName
,
(
nLengthOfHostName
+
1
)
*
sizeof
(
sal_Char
));
}
}
/* always return a hostname looked up as carefully as possible
* this string must be freed by the caller */
return
pFullQualifiedName
;
}
/*****************************************************************************/
/* _osl_isFullQualifiedDomainName */
/*****************************************************************************/
static
sal_Bool
_osl_isFullQualifiedDomainName
(
const
sal_Char
*
pHostName
)
{
/* a FQDN (aka 'hostname.domain.top_level_domain' )
* is a name which contains a dot '.' in it ( would
* match as well for 'hostname.' but is good enough
* for now )*/
return
(
sal_Bool
)(
strchr
(
pHostName
,
(
int
)
'.'
)
!=
NULL
);
}
/*****************************************************************************/
/* oslHostAddr */
/*****************************************************************************/
struct
oslHostAddrImpl
{
sal_Char
*
pHostName
;
oslSocketAddr
pSockAddr
;
};
static
oslHostAddr
_osl_hostentToHostAddr
(
const
struct
hostent
*
he
)
{
oslHostAddr
pAddr
=
NULL
;
oslSocketAddr
pSockAddr
=
0
;
sal_Char
*
cn
;
if
((
he
==
NULL
)
||
(
he
->
h_name
==
NULL
)
||
(
he
->
h_addr_list
[
0
]
==
NULL
))
return
((
oslHostAddr
)
NULL
);
if
(
_osl_isFullQualifiedDomainName
(
he
->
h_name
))
{
cn
=
(
sal_Char
*
)
malloc
(
strlen
(
he
->
h_name
)
+
1
);
OSL_ASSERT
(
cn
);
if
(
cn
==
NULL
)
return
((
oslHostAddr
)
NULL
);
strcpy
(
cn
,
he
->
h_name
);
}
else
{
cn
=
_osl_getFullQualifiedDomainName
(
he
->
h_name
);
OSL_ASSERT
(
cn
);
if
(
cn
==
NULL
)
return
((
oslHostAddr
)
NULL
);
}
pSockAddr
=
__osl_createSocketAddr
();
OSL_ASSERT
(
pSockAddr
);
if
(
pSockAddr
==
NULL
)
{
free
(
cn
);
return
((
oslHostAddr
)
NULL
);
}
pSockAddr
->
m_sockaddr
.
sa_family
=
he
->
h_addrtype
;
if
(
pSockAddr
->
m_sockaddr
.
sa_family
==
FAMILY_TO_NATIVE
(
osl_Socket_FamilyInet
))
{
struct
sockaddr_in
*
sin
=
(
struct
sockaddr_in
*
)
&
(
pSockAddr
->
m_sockaddr
);
memcpy
(
&
(
sin
->
sin_addr
.
s_addr
),
he
->
h_addr_list
[
0
],
he
->
h_length
);
}
else
{
/* unknown address family */
/* future extensions for new families might be implemented here */
OSL_TRACE
(
"_osl_hostentToHostAddr: unknown address family.
\n
"
);
OSL_ASSERT
(
sal_False
);
__osl_destroySocketAddr
(
pSockAddr
);
free
(
cn
);
return
((
oslHostAddr
)
NULL
);
}
pAddr
=
(
oslHostAddr
)
malloc
(
sizeof
(
struct
oslHostAddrImpl
));
OSL_ASSERT
(
pAddr
);
if
(
pAddr
==
NULL
)
{
__osl_destroySocketAddr
(
pSockAddr
);
free
(
cn
);
return
((
oslHostAddr
)
NULL
);
}
pAddr
->
pHostName
=
cn
;
pAddr
->
pSockAddr
=
pSockAddr
;
return
pAddr
;
}
/*****************************************************************************/
/* osl_createHostAddr */
/*****************************************************************************/
oslHostAddr
SAL_CALL
osl_createHostAddr
(
rtl_uString
*
ustrHostname
,
const
oslSocketAddr
Addr
)
{
oslHostAddr
HostAddr
;
rtl_String
*
strHostname
=
0
;
sal_Char
*
pszHostName
=
0
;
if
(
ustrHostname
!=
0
)
{
rtl_uString2String
(
&
strHostname
,
rtl_uString_getStr
(
ustrHostname
),
rtl_uString_getLength
(
ustrHostname
),
RTL_TEXTENCODING_UTF8
,
OUSTRING_TO_OSTRING_CVTFLAGS
);
pszHostName
=
rtl_string_getStr
(
strHostname
);
}
HostAddr
=
osl_psz_createHostAddr
(
pszHostName
,
Addr
);
if
(
strHostname
!=
0
)
{
rtl_string_release
(
strHostname
);
}
return
HostAddr
;
}
oslHostAddr
SAL_CALL
osl_psz_createHostAddr
(
const
sal_Char
*
pszHostname
,
const
oslSocketAddr
pAddr
)
{
oslHostAddr
pHostAddr
;
sal_Char
*
cn
;
OSL_ASSERT
(
pszHostname
&&
pAddr
);
if
((
pszHostname
==
NULL
)
||
(
pAddr
==
NULL
))
return
((
oslHostAddr
)
NULL
);
cn
=
(
sal_Char
*
)
malloc
(
strlen
(
pszHostname
)
+
1
);
OSL_ASSERT
(
cn
);
if
(
cn
==
NULL
)
return
((
oslHostAddr
)
NULL
);
strcpy
(
cn
,
pszHostname
);
pHostAddr
=
(
oslHostAddr
)
malloc
(
sizeof
(
struct
oslHostAddrImpl
));
OSL_ASSERT
(
pHostAddr
);
if
(
pAddr
==
NULL
)
{
free
(
cn
);
return
((
oslHostAddr
)
NULL
);
}
pHostAddr
->
pHostName
=
cn
;
pHostAddr
->
pSockAddr
=
osl_copySocketAddr
(
pAddr
);
return
pHostAddr
;
}
/*****************************************************************************/
/* osl_createHostAddrByName */
/*****************************************************************************/
oslHostAddr
SAL_CALL
osl_createHostAddrByName
(
rtl_uString
*
ustrHostname
)
{
oslHostAddr
HostAddr
;
rtl_String
*
strHostname
=
0
;
sal_Char
*
pszHostName
=
0
;
if
(
ustrHostname
!=
0
)
{
rtl_uString2String
(
&
strHostname
,
rtl_uString_getStr
(
ustrHostname
),
rtl_uString_getLength
(
ustrHostname
),
RTL_TEXTENCODING_UTF8
,
OUSTRING_TO_OSTRING_CVTFLAGS
);
pszHostName
=
rtl_string_getStr
(
strHostname
);
}
HostAddr
=
osl_psz_createHostAddrByName
(
pszHostName
);
if
(
strHostname
!=
0
)
{
rtl_string_release
(
strHostname
);
}
return
HostAddr
;
}
oslHostAddr
SAL_CALL
osl_psz_createHostAddrByName
(
const
sal_Char
*
pszHostname
)
{
struct
hostent
*
he
;
oslHostAddr
addr
;
static
oslMutex
mutex
=
NULL
;
if
(
mutex
==
NULL
)
mutex
=
osl_createMutex
();
osl_acquireMutex
(
mutex
);
he
=
gethostbyname
((
sal_Char
*
)
pszHostname
);
addr
=
_osl_hostentToHostAddr
(
he
);
osl_releaseMutex
(
mutex
);
return
addr
;
}
/*****************************************************************************/
/* osl_createHostAddrByAddr */
/*****************************************************************************/
oslHostAddr
SAL_CALL
osl_createHostAddrByAddr
(
const
oslSocketAddr
pAddr
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
==
NULL
)
return
((
oslHostAddr
)
NULL
);
if
(
pAddr
->
m_sockaddr
.
sa_family
==
FAMILY_TO_NATIVE
(
osl_Socket_FamilyInet
))
{
const
struct
sockaddr_in
*
sin
=
(
const
struct
sockaddr_in
*
)
&
(
pAddr
->
m_sockaddr
);
struct
hostent
*
he
;
if
(
sin
->
sin_addr
.
s_addr
==
htonl
(
INADDR_ANY
))
return
((
oslHostAddr
)
NULL
);
he
=
gethostbyaddr
((
sal_Char
*
)
&
(
sin
->
sin_addr
),
sizeof
(
sin
->
sin_addr
),
sin
->
sin_family
);
return
_osl_hostentToHostAddr
(
he
);
}
return
((
oslHostAddr
)
NULL
);
}
/*****************************************************************************/
/* osl_copyHostAddr */
/*****************************************************************************/
oslHostAddr
SAL_CALL
osl_copyHostAddr
(
const
oslHostAddr
pAddr
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
)
return
osl_psz_createHostAddr
(
pAddr
->
pHostName
,
pAddr
->
pSockAddr
);
else
return
((
oslHostAddr
)
NULL
);
}
/*****************************************************************************/
/* osl_getHostnameOfHostAddr */
/*****************************************************************************/
void
SAL_CALL
osl_getHostnameOfHostAddr
(
const
oslHostAddr
Addr
,
rtl_uString
**
ustrHostname
)
{
const
sal_Char
*
pHostname
=
0
;
pHostname
=
osl_psz_getHostnameOfHostAddr
(
Addr
);
rtl_uString_newFromAscii
(
ustrHostname
,
pHostname
);
return
;
}
const
sal_Char
*
SAL_CALL
osl_psz_getHostnameOfHostAddr
(
const
oslHostAddr
pAddr
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
)
return
pAddr
->
pHostName
;
else
return
NULL
;
}
/*****************************************************************************/
/* osl_getSocketAddrOfHostAddr */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_getSocketAddrOfHostAddr
(
const
oslHostAddr
pAddr
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
)
return
((
oslSocketAddr
)(
pAddr
->
pSockAddr
));
else
return
NULL
;
}
/*****************************************************************************/
/* osl_destroyHostAddr */
/*****************************************************************************/
void
SAL_CALL
osl_destroyHostAddr
(
oslHostAddr
pAddr
)
{
if
(
pAddr
)
{
if
(
pAddr
->
pHostName
)
free
(
pAddr
->
pHostName
);
if
(
pAddr
->
pSockAddr
)
osl_destroySocketAddr
(
pAddr
->
pSockAddr
);
free
(
pAddr
);
}
}
/*****************************************************************************/
/* osl_getLocalHostname */
/*****************************************************************************/
oslSocketResult
SAL_CALL
osl_getLocalHostname
(
rtl_uString
**
ustrLocalHostname
)
{
oslSocketResult
Result
;
sal_Char
pszHostname
[
1024
];
pszHostname
[
0
]
=
'\0'
;
Result
=
osl_psz_getLocalHostname
(
pszHostname
,
sizeof
(
pszHostname
));
rtl_uString_newFromAscii
(
ustrLocalHostname
,
pszHostname
);
return
Result
;
}
oslSocketResult
SAL_CALL
osl_psz_getLocalHostname
(
sal_Char
*
pBuffer
,
sal_uInt32
nBufLen
)
{
static
sal_Char
LocalHostname
[
256
]
=
""
;
if
(
strlen
(
LocalHostname
)
==
0
)
{
const
sal_Char
*
pStr
;
#ifdef SYSV
struct
utsname
uts
;
if
(
uname
(
&
uts
)
<
0
)
return
osl_Socket_Error
;
if
((
strlen
(
uts
.
nodename
)
+
1
)
>
nBufLen
)
return
osl_Socket_Error
;
strcpy
(
LocalHostname
,
uts
.
nodename
);
#else
/* BSD compatible */
if
(
gethostname
(
LocalHostname
,
sizeof
(
LocalHostname
))
!=
0
)
return
osl_Socket_Error
;
#endif
/* SYSV */
/* check if we have an FQDN */
if
(
strchr
(
LocalHostname
,
'.'
)
==
NULL
)
{
oslHostAddr
Addr
;
/* no, determine it via dns */
Addr
=
osl_psz_createHostAddrByName
(
LocalHostname
);
if
((
pStr
=
osl_psz_getHostnameOfHostAddr
(
Addr
))
!=
NULL
)
{
#if 0 /* OBSOLETE */
sal_Char* pChr;
#endif /* OBSOLETE */
strcpy
(
LocalHostname
,
pStr
);
#if 0 /* OBSOLETE */
/* already done by _osl_getFullQualifiedDomainName() with
much better heuristics, so this may be contraproductive */
/* no FQDN, last try append domain name */
if ((pChr = strchr(LocalHostname, '.')) == NULL)
{
FILE *fp;
pChr = &LocalHostname[strlen(LocalHostname)];
if ( (fp = popen("domainname", "r")) != 0 )
{
int c;
*pChr++ = '.';
while ((c = getc(fp)) != EOF)
{
if (! isspace(c))
*pChr++ = (sal_Char)c;
}
*pChr = '\0';
fclose(fp);
}
else
LocalHostname[0] = '\0';
}
#endif /* OBSOLETE */
}
osl_destroyHostAddr
(
Addr
);
}
}
if
(
strlen
(
LocalHostname
)
>
0
)
{
strncpy
(
pBuffer
,
LocalHostname
,
nBufLen
);
pBuffer
[
nBufLen
-
1
]
=
'\0'
;
return
osl_Socket_Ok
;
}
return
osl_Socket_Error
;
}
/*****************************************************************************/
/* osl_resolveHostname */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_resolveHostname
(
rtl_uString
*
ustrHostname
)
{
oslSocketAddr
Addr
;
rtl_String
*
strHostname
=
0
;
sal_Char
*
pszHostName
=
0
;
if
(
ustrHostname
!=
0
)
{
rtl_uString2String
(
&
strHostname
,
rtl_uString_getStr
(
ustrHostname
),
rtl_uString_getLength
(
ustrHostname
),
RTL_TEXTENCODING_UTF8
,
OUSTRING_TO_OSTRING_CVTFLAGS
);
pszHostName
=
rtl_string_getStr
(
strHostname
);
}
Addr
=
osl_psz_resolveHostname
(
pszHostName
);
if
(
strHostname
!=
0
)
{
rtl_string_release
(
strHostname
);
}
return
Addr
;
}
oslSocketAddr
SAL_CALL
osl_psz_resolveHostname
(
const
sal_Char
*
pszHostname
)
{
struct
oslHostAddrImpl
*
pAddr
=
(
oslHostAddr
)
osl_psz_createHostAddrByName
(
pszHostname
);
if
(
pAddr
)
{
oslSocketAddr
SockAddr
=
osl_copySocketAddr
(
pAddr
->
pSockAddr
);
osl_destroyHostAddr
(
pAddr
);
return
(
SockAddr
);
}
return
((
oslSocketAddr
)
NULL
);
}
/*****************************************************************************/
/* osl_getServicePort */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_getServicePort
(
rtl_uString
*
ustrServicename
,
rtl_uString
*
ustrProtocol
)
{
sal_Int32
nPort
;
rtl_String
*
strServicename
=
0
;
rtl_String
*
strProtocol
=
0
;
sal_Char
*
pszServiceName
=
0
;
sal_Char
*
pszProtocol
=
0
;
if
(
ustrServicename
!=
0
)
{
rtl_uString2String
(
&
strServicename
,
rtl_uString_getStr
(
ustrServicename
),
rtl_uString_getLength
(
ustrServicename
),
RTL_TEXTENCODING_UTF8
,
OUSTRING_TO_OSTRING_CVTFLAGS
);
pszServiceName
=
rtl_string_getStr
(
strServicename
);
}
if
(
ustrProtocol
!=
0
)
{
rtl_uString2String
(
&
strProtocol
,
rtl_uString_getStr
(
ustrProtocol
),
rtl_uString_getLength
(
ustrProtocol
),
RTL_TEXTENCODING_UTF8
,
OUSTRING_TO_OSTRING_CVTFLAGS
);
pszProtocol
=
rtl_string_getStr
(
strProtocol
);
}
nPort
=
osl_psz_getServicePort
(
pszServiceName
,
pszProtocol
);
if
(
strServicename
!=
0
)
{
rtl_string_release
(
strServicename
);
}
if
(
strProtocol
!=
0
)
{
rtl_string_release
(
strProtocol
);
}
return
nPort
;
}
sal_Int32
SAL_CALL
osl_psz_getServicePort
(
const
sal_Char
*
pszServicename
,
const
sal_Char
*
pszProtocol
)
{
struct
servent
*
ps
;
ps
=
getservbyname
(
pszServicename
,
pszProtocol
);
if
(
ps
!=
0
)
return
ntohs
(
ps
->
s_port
);
return
OSL_INVALID_PORT
;
}
/*****************************************************************************/
/* osl_destroySocketAddr */
/*****************************************************************************/
void
SAL_CALL
osl_destroySocketAddr
(
oslSocketAddr
pAddr
)
{
__osl_destroySocketAddr
(
pAddr
);
}
/*****************************************************************************/
/* osl_getFamilyOfSocketAddr */
/*****************************************************************************/
oslAddrFamily
SAL_CALL
osl_getFamilyOfSocketAddr
(
oslSocketAddr
pAddr
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
)
return
FAMILY_FROM_NATIVE
(
pAddr
->
m_sockaddr
.
sa_family
);
else
return
osl_Socket_FamilyInvalid
;
}
/*****************************************************************************/
/* osl_getInetPortOfSocketAddr */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_getInetPortOfSocketAddr
(
oslSocketAddr
pAddr
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
)
{
struct
sockaddr_in
*
pSystemInetAddr
=
(
struct
sockaddr_in
*
)
&
(
pAddr
->
m_sockaddr
);
if
(
pSystemInetAddr
->
sin_family
==
FAMILY_TO_NATIVE
(
osl_Socket_FamilyInet
))
return
ntohs
(
pSystemInetAddr
->
sin_port
);
}
return
OSL_INVALID_PORT
;
}
/*****************************************************************************/
/* osl_setInetPortOfSocketAddr */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_setInetPortOfSocketAddr
(
oslSocketAddr
pAddr
,
sal_Int32
Port
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
)
{
struct
sockaddr_in
*
pSystemInetAddr
=
(
struct
sockaddr_in
*
)
&
(
pAddr
->
m_sockaddr
);
if
(
pSystemInetAddr
->
sin_family
==
FAMILY_TO_NATIVE
(
osl_Socket_FamilyInet
))
{
pSystemInetAddr
->
sin_port
=
htons
((
short
)
Port
);
return
sal_True
;
}
}
/* this is not a inet-addr => can't set port */
return
sal_False
;
}
/*****************************************************************************/
/* osl_getHostnameOfSocketAddr */
/*****************************************************************************/
oslSocketResult
SAL_CALL
osl_getHostnameOfSocketAddr
(
oslSocketAddr
Addr
,
rtl_uString
**
ustrHostname
)
{
oslSocketResult
Result
;
sal_Char
pszHostname
[
1024
];
pszHostname
[
0
]
=
'\0'
;
Result
=
osl_psz_getHostnameOfSocketAddr
(
Addr
,
pszHostname
,
sizeof
(
pszHostname
));
rtl_uString_newFromAscii
(
ustrHostname
,
pszHostname
);
return
Result
;
}
oslSocketResult
SAL_CALL
osl_psz_getHostnameOfSocketAddr
(
oslSocketAddr
pAddr
,
sal_Char
*
pBuffer
,
sal_uInt32
BufferSize
)
{
oslHostAddr
pHostAddr
=
(
oslHostAddr
)
osl_createHostAddrByAddr
(
pAddr
);
if
(
pHostAddr
)
{
strncpy
(
pBuffer
,
pHostAddr
->
pHostName
,
BufferSize
);
pBuffer
[
BufferSize
-
1
]
=
'\0'
;
osl_destroyHostAddr
(
pHostAddr
);
return
osl_Socket_Ok
;
}
return
osl_Socket_Error
;
}
/*****************************************************************************/
/* osl_getDottedInetAddrOfSocketAddr */
/*****************************************************************************/
oslSocketResult
SAL_CALL
osl_getDottedInetAddrOfSocketAddr
(
oslSocketAddr
Addr
,
rtl_uString
**
ustrDottedInetAddr
)
{
oslSocketResult
Result
;
sal_Char
pszDottedInetAddr
[
1024
];
pszDottedInetAddr
[
0
]
=
'\0'
;
Result
=
osl_psz_getDottedInetAddrOfSocketAddr
(
Addr
,
pszDottedInetAddr
,
sizeof
(
pszDottedInetAddr
));
rtl_uString_newFromAscii
(
ustrDottedInetAddr
,
pszDottedInetAddr
);
return
Result
;
}
oslSocketResult
SAL_CALL
osl_psz_getDottedInetAddrOfSocketAddr
(
oslSocketAddr
pAddr
,
sal_Char
*
pBuffer
,
sal_uInt32
BufferSize
)
{
OSL_ASSERT
(
pAddr
);
if
(
pAddr
)
{
struct
sockaddr_in
*
pSystemInetAddr
=
(
struct
sockaddr_in
*
)
&
(
pAddr
->
m_sockaddr
);
if
(
pSystemInetAddr
->
sin_family
==
FAMILY_TO_NATIVE
(
osl_Socket_FamilyInet
))
{
strncpy
(
pBuffer
,
inet_ntoa
(
pSystemInetAddr
->
sin_addr
),
BufferSize
);
pBuffer
[
BufferSize
-
1
]
=
'\0'
;
return
osl_Socket_Ok
;
}
}
return
osl_Socket_Error
;
}
#if 0
/*****************************************************************************/
/* osl_getIpxNetNumber */
/*****************************************************************************/
oslSocketResult SAL_CALL osl_getIpxNetNumber(oslSocketAddr Addr,
oslSocketIpxNetNumber NetNumber)
{
struct sockaddr_ipx* pAddr;
pAddr= (struct sockaddr_ipx*)Addr;
OSL_ASSERT(pAddr);
if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
{
memcpy(NetNumber, pAddr->sa_netnum, sizeof(NetNumber));
return osl_Socket_Ok;
}
else
return osl_Socket_Error;
}
/*****************************************************************************/
/* osl_getIpxNodeNumber */
/*****************************************************************************/
oslSocketResult SAL_CALL osl_getIpxNodeNumber(oslSocketAddr Addr,
oslSocketIpxNodeNumber NodeNumber)
{
struct sockaddr_ipx* pAddr;
pAddr= (struct sockaddr_ipx*)Addr;
OSL_ASSERT(pAddr);
if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
{
memcpy(NodeNumber, pAddr->sa_nodenum, sizeof(NodeNumber));
return osl_Socket_Ok;
}
else
return osl_Socket_Error;
}
/*****************************************************************************/
/* osl_getIpxSocketNumber */
/*****************************************************************************/
sal_Int32 SAL_CALL osl_getIpxSocketNumber(oslSocketAddr Addr)
{
struct sockaddr_ipx* pAddr= (struct sockaddr_ipx*)Addr;
OSL_ASSERT(pAddr);
if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
return pAddr->sa_socket;
else
return OSL_INVALID_IPX_SOCKET_NO;
}
#endif
/*****************************************************************************/
/* osl_createSocket */
/*****************************************************************************/
oslSocket
SAL_CALL
osl_createSocket
(
oslAddrFamily
Family
,
oslSocketType
Type
,
oslProtocol
Protocol
)
{
int
Flags
;
oslSocket
pSocket
;
/* alloc memory */
pSocket
=
__osl_createSocketImpl
(
OSL_INVALID_SOCKET
);
/* create socket */
pSocket
->
m_Socket
=
socket
(
FAMILY_TO_NATIVE
(
Family
),
TYPE_TO_NATIVE
(
Type
),
PROTOCOL_TO_NATIVE
(
Protocol
));
/* creation failed => free memory */
if
(
pSocket
->
m_Socket
==
OSL_INVALID_SOCKET
)
{
OSL_TRACE
(
"osl_createSocket failed. Errno: %d; %s
\n
"
,
errno
,
strerror
(
errno
));
__osl_destroySocketImpl
((
pSocket
));
pSocket
=
0
;
}
else
{
/* set close-on-exec flag */
if
((
Flags
=
fcntl
(
pSocket
->
m_Socket
,
F_GETFD
,
0
))
!=
-
1
)
{
Flags
|=
FD_CLOEXEC
;
if
(
fcntl
(
pSocket
->
m_Socket
,
F_SETFD
,
Flags
)
==
-
1
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_createSocket failed changing socket flags. Errno: %d; %s
\n
"
,
errno
,
strerror
(
errno
));
}
}
else
{
pSocket
->
m_nLastError
=
errno
;
}
pSocket
->
m_CloseCallback
=
NULL
;
pSocket
->
m_CallbackArg
=
NULL
;
}
return
pSocket
;
}
/*****************************************************************************/
/* osl_copySocket */
/*****************************************************************************/
oslSocket
SAL_CALL
osl_copySocket
(
oslSocket
pSocket
)
{
osl_acquireSocket
(
pSocket
);
return
pSocket
;
}
void
SAL_CALL
osl_acquireSocket
(
oslSocket
pSocket
)
{
osl_incrementInterlockedCount
(
&
(
pSocket
->
m_nRefCount
)
);
}
void
SAL_CALL
osl_releaseSocket
(
oslSocket
pSocket
)
{
if
(
pSocket
&&
0
==
osl_decrementInterlockedCount
(
&
(
pSocket
->
m_nRefCount
)
)
)
{
#if defined(LINUX)
if
(
pSocket
->
m_bIsAccepting
==
sal_True
)
{
OSL_ENSURE
(
0
,
"osl_destroySocket : attempt to destroy socket while accepting
\n
"
);
return
;
}
#endif
osl_closeSocket
(
pSocket
);
__osl_destroySocketImpl
(
pSocket
);
}
}
/*****************************************************************************/
/* osl_destroySocket */
/*****************************************************************************/
void
SAL_CALL
osl_destroySocket
(
oslSocket
pSocket
)
{
osl_releaseSocket
(
pSocket
);
}
/*****************************************************************************/
/* osl_closeSocket */
/*****************************************************************************/
void
SAL_CALL
osl_closeSocket
(
oslSocket
pSocket
)
{
int
nRet
;
int
nFD
;
/* socket already invalid */
if
(
pSocket
==
0
)
return
;
pSocket
->
m_nLastError
=
0
;
nFD
=
pSocket
->
m_Socket
;
pSocket
->
m_Socket
=
OSL_INVALID_SOCKET
;
#if defined(LINUX)
pSocket
->
m_bIsInShutdown
=
sal_True
;
if
(
pSocket
->
m_bIsAccepting
==
sal_True
)
{
int
nConnFD
;
struct
sockaddr
aSockAddr
;
socklen_t
nSockLen
=
sizeof
(
aSockAddr
);
nRet
=
getsockname
(
nFD
,
&
aSockAddr
,
&
nSockLen
);
#if defined(DEBUG)
if
(
nRet
<
0
)
{
perror
(
"getsockname"
);
}
#endif
/* DEBUG */
if
(
aSockAddr
.
sa_family
==
AF_INET
)
{
struct
sockaddr_in
*
pSockAddrIn
=
(
struct
sockaddr_in
*
)
&
aSockAddr
;
if
(
pSockAddrIn
->
sin_addr
.
s_addr
==
htonl
(
INADDR_ANY
)
)
{
pSockAddrIn
->
sin_addr
.
s_addr
=
htonl
(
INADDR_LOOPBACK
);
}
nConnFD
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
#if defined(DEBUG)
if
(
nConnFD
<
0
)
{
perror
(
"socket"
);
}
#endif
/* DEBUG */
nRet
=
connect
(
nConnFD
,
&
aSockAddr
,
sizeof
(
aSockAddr
));
#if defined(DEBUG)
if
(
nRet
<
0
)
{
perror
(
"connect"
);
}
#endif
/* DEBUG */
close
(
nConnFD
);
}
}
#endif
/* LINUX */
/* registrierten Callback ausfuehren */
if
(
pSocket
->
m_CloseCallback
!=
NULL
)
{
pSocket
->
m_CloseCallback
(
pSocket
->
m_CallbackArg
);
}
nRet
=
close
(
nFD
);
if
(
nRet
!=
0
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"closeSocket close error '%s'
\n
"
,
strerror
(
errno
));
}
pSocket
->
m_Socket
=
OSL_INVALID_SOCKET
;
}
/*****************************************************************************/
/* osl_getLocalAddrOfSocket */
/* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
/* are the same! I don't like it very much but see no other easy way to conceal */
/* the struct sockaddr from the eyes of the user. */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_getLocalAddrOfSocket
(
oslSocket
pSocket
)
{
#ifdef LINUX
socklen_t
AddrLen
;
#else
/* mfe: Solaris 'cc +w' means Addrlen should be signed! */
/* it's really defined as 'int*' in /usr/include/sys/socket.h! */
/* the man page says it expects a 'size_t' */
int
AddrLen
;
#endif
struct
sockaddr
Addr
;
oslSocketAddr
pAddr
;
if
(
pSocket
==
NULL
)
/* ENOTSOCK */
return
((
oslSocketAddr
)
NULL
);
AddrLen
=
sizeof
(
struct
sockaddr
);
if
(
getsockname
(
pSocket
->
m_Socket
,
&
Addr
,
PTR_SIZE_T
(
AddrLen
))
==
OSL_SOCKET_ERROR
)
return
((
oslSocketAddr
)
NULL
);
pAddr
=
__osl_createSocketAddrFromSystem
(
&
Addr
);
return
pAddr
;
}
/*****************************************************************************/
/* osl_getPeerAddrOfSocket */
/*****************************************************************************/
oslSocketAddr
SAL_CALL
osl_getPeerAddrOfSocket
(
oslSocket
pSocket
)
{
sal_uInt32
AddrLen
;
struct
sockaddr
Addr
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
0
;
}
pSocket
->
m_nLastError
=
0
;
AddrLen
=
sizeof
(
struct
sockaddr
);
if
(
getpeername
(
pSocket
->
m_Socket
,
&
Addr
,
PTR_SIZE_T
(
AddrLen
))
==
OSL_SOCKET_ERROR
)
{
pSocket
->
m_nLastError
=
errno
;
return
0
;
}
return
__osl_createSocketAddrFromSystem
(
&
Addr
);
}
/*****************************************************************************/
/* osl_bindAddrToSocket */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_bindAddrToSocket
(
oslSocket
pSocket
,
oslSocketAddr
pAddr
)
{
int
nRet
;
OSL_ASSERT
(
pSocket
&&
pAddr
);
if
(
pSocket
==
0
||
pAddr
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
nRet
=
bind
(
pSocket
->
m_Socket
,
&
(
pAddr
->
m_sockaddr
),
sizeof
(
struct
sockaddr
));
if
(
nRet
==
OSL_SOCKET_ERROR
)
{
pSocket
->
m_nLastError
=
errno
;
return
sal_False
;
}
return
sal_True
;
}
/*****************************************************************************/
/* osl_listenOnSocket */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_listenOnSocket
(
oslSocket
pSocket
,
sal_Int32
MaxPendingConnections
)
{
int
nRet
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
nRet
=
listen
(
pSocket
->
m_Socket
,
MaxPendingConnections
==
-
1
?
SOMAXCONN
:
MaxPendingConnections
);
if
(
nRet
==
OSL_SOCKET_ERROR
)
{
pSocket
->
m_nLastError
=
errno
;
return
sal_False
;
}
return
sal_True
;
}
/*****************************************************************************/
/* osl_connectSocketTo */
/*****************************************************************************/
oslSocketResult
SAL_CALL
osl_connectSocketTo
(
oslSocket
pSocket
,
oslSocketAddr
pAddr
,
const
TimeValue
*
pTimeout
)
{
fd_set
WriteSet
;
fd_set
ExcptSet
;
int
ReadyHandles
;
struct
timeval
tv
;
oslSocketResult
Result
=
osl_Socket_Ok
;
OSL_PRECOND
(
pSocket
,
"osl_connectSocketTo(): need a valid socket!
\n
"
);
if
(
pSocket
==
0
)
{
return
osl_Socket_Error
;
}
pSocket
->
m_nLastError
=
0
;
if
(
osl_isNonBlockingMode
(
pSocket
))
{
if
(
connect
(
pSocket
->
m_Socket
,
&
(
pAddr
->
m_sockaddr
),
sizeof
(
struct
sockaddr
))
!=
OSL_SOCKET_ERROR
)
return
osl_Socket_Ok
;
else
if
(
errno
==
EWOULDBLOCK
||
errno
==
EINPROGRESS
)
{
pSocket
->
m_nLastError
=
EINPROGRESS
;
return
osl_Socket_InProgress
;
}
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"can't connect : '%s'"
,
strerror
(
errno
));
return
osl_Socket_Error
;
}
/* set socket temporarily to non-blocking */
OSL_VERIFY
(
osl_enableNonBlockingMode
(
pSocket
,
sal_True
));
/* initiate connect */
if
(
connect
(
pSocket
->
m_Socket
,
&
(
pAddr
->
m_sockaddr
),
sizeof
(
struct
sockaddr
))
!=
OSL_SOCKET_ERROR
)
{
/* immediate connection */
osl_enableNonBlockingMode
(
pSocket
,
sal_False
);
return
osl_Socket_Ok
;
}
else
{
/* really an error or just delayed? */
if
(
errno
!=
EINPROGRESS
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_connectSocketTo(): connect failed: errno: %d (%s)
\n
"
,
errno
,
strerror
(
errno
));
osl_enableNonBlockingMode
(
pSocket
,
sal_False
);
return
osl_Socket_Error
;
}
}
/* prepare select set for socket */
FD_ZERO
(
&
WriteSet
);
FD_ZERO
(
&
ExcptSet
);
FD_SET
(
pSocket
->
m_Socket
,
&
WriteSet
);
FD_SET
(
pSocket
->
m_Socket
,
&
ExcptSet
);
/* prepare timeout */
if
(
pTimeout
)
{
/* divide milliseconds into seconds and microseconds */
tv
.
tv_sec
=
pTimeout
->
Seconds
;
tv
.
tv_usec
=
pTimeout
->
Nanosec
/
1000L
;
}
/* select */
ReadyHandles
=
select
(
pSocket
->
m_Socket
+
1
,
0
,
PTR_FD_SET
(
WriteSet
),
PTR_FD_SET
(
ExcptSet
),
(
pTimeout
)
?
&
tv
:
0
);
if
(
ReadyHandles
>
0
)
/* connected */
{
if
(
FD_ISSET
(
pSocket
->
m_Socket
,
&
WriteSet
)
)
{
int
nErrorCode
=
0
;
#ifdef SOLARIS
/* mfe: Solaris 'cc +w' means 5th argument should be a 'int*'!
it's really defined as 'int*' in /usr/include/sys/socket.h!
the man page says it expects a 'size_t*'
*/
int
nErrorSize
=
sizeof
(
nErrorCode
);
#else
size_t
nErrorSize
=
sizeof
(
nErrorCode
);
#endif
int
nSockOpt
;
nSockOpt
=
getsockopt
(
pSocket
->
m_Socket
,
SOL_SOCKET
,
SO_ERROR
,
#ifdef SOLARIS
/* mfe: Solaris 'cc +w' means 4th argument should be a 'char*'!
it's really defined as 'char*' in /usr/include/sys/socket.h!
the man page says it expects a 'void*'
*/
(
char
*
)
#endif
&
nErrorCode
,
&
nErrorSize
);
if
(
(
nSockOpt
==
0
)
&&
(
nErrorCode
==
0
))
Result
=
osl_Socket_Ok
;
else
Result
=
osl_Socket_Error
;
}
else
{
Result
=
osl_Socket_Error
;
}
}
else
if
(
ReadyHandles
<
0
)
/* error */
{
if
(
errno
==
EBADF
)
/* most probably interrupted by close() */
{
/* do not access pSockImpl because it is about to be or */
/* already destroyed */
return
osl_Socket_Interrupted
;
}
else
{
pSocket
->
m_nLastError
=
errno
;
Result
=
osl_Socket_Error
;
}
}
else
/* timeout */
{
pSocket
->
m_nLastError
=
errno
;
Result
=
osl_Socket_TimedOut
;
}
osl_enableNonBlockingMode
(
pSocket
,
sal_False
);
return
Result
;
}
/*****************************************************************************/
/* osl_acceptConnectionOnSocket */
/*****************************************************************************/
oslSocket
SAL_CALL
osl_acceptConnectionOnSocket
(
oslSocket
pSocket
,
oslSocketAddr
*
ppAddr
)
{
struct
sockaddr
Addr
;
int
Connection
,
Flags
;
sal_uInt32
AddrLen
=
sizeof
(
struct
sockaddr
);
oslSocket
pConnectionSockImpl
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
0
;
}
pSocket
->
m_nLastError
=
0
;
#if defined(LINUX)
pSocket
->
m_bIsAccepting
=
sal_True
;
#endif
if
(
ppAddr
&&
*
ppAddr
)
{
osl_destroySocketAddr
(
*
ppAddr
);
*
ppAddr
=
0
;
}
/* prevent Linux EINTR behaviour */
do
{
Connection
=
accept
(
pSocket
->
m_Socket
,
&
Addr
,
PTR_SIZE_T
(
AddrLen
));
}
while
(
Connection
==
-
1
&&
errno
==
EINTR
);
/* accept failed? */
if
(
Connection
==
OSL_SOCKET_ERROR
)
{
pSocket
->
m_nLastError
=
errno
;
#if defined(DEBUG)
fprintf
(
stderr
,
"osl_acceptConnectionOnSocket : accept error '%s'
\n
"
,
strerror
(
errno
));
#endif
#if defined(LINUX)
pSocket
->
m_bIsAccepting
=
sal_False
;
#endif
return
0
;
}
OSL_ASSERT
(
AddrLen
==
sizeof
(
struct
sockaddr
));
#if defined(LINUX)
if
(
pSocket
->
m_bIsInShutdown
==
sal_True
)
{
close
(
Connection
);
#if defined(DEBUG)
fprintf
(
stderr
,
"osl_acceptConnectionOnSocket : close while accept
\n
"
);
#endif
return
0
;
}
#endif
if
(
ppAddr
)
{
*
ppAddr
=
__osl_createSocketAddrFromSystem
(
&
Addr
);
}
/* alloc memory */
pConnectionSockImpl
=
__osl_createSocketImpl
(
OSL_INVALID_SOCKET
);
/* set close-on-exec flag */
if
((
Flags
=
fcntl
(
Connection
,
F_GETFD
,
0
))
!=
-
1
)
{
Flags
|=
FD_CLOEXEC
;
if
(
fcntl
(
Connection
,
F_SETFD
,
Flags
)
==
-
1
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)
\n
"
,
errno
,
strerror
(
errno
));
}
}
pConnectionSockImpl
->
m_Socket
=
Connection
;
pConnectionSockImpl
->
m_nLastError
=
0
;
pConnectionSockImpl
->
m_CloseCallback
=
NULL
;
pConnectionSockImpl
->
m_CallbackArg
=
NULL
;
#if defined(LINUX)
pConnectionSockImpl
->
m_bIsAccepting
=
sal_False
;
pSocket
->
m_bIsAccepting
=
sal_False
;
#endif
return
pConnectionSockImpl
;
}
/*****************************************************************************/
/* osl_receiveSocket */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_receiveSocket
(
oslSocket
pSocket
,
void
*
pBuffer
,
sal_uInt32
BytesToRead
,
oslSocketMsgFlag
Flag
)
{
int
nRead
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
OSL_TRACE
(
"osl_receiveSocket : Invalid socket"
);
return
-
1
;
}
pSocket
->
m_nLastError
=
0
;
do
{
nRead
=
recv
(
pSocket
->
m_Socket
,
(
sal_Char
*
)
pBuffer
,
BytesToRead
,
MSG_FLAG_TO_NATIVE
(
Flag
));
}
while
(
nRead
<
0
&&
errno
==
EINTR
);
if
(
nRead
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_receiveSocket failed : %i '%s'"
,
nRead
,
strerror
(
errno
));
}
else
if
(
nRead
==
0
)
{
OSL_TRACE
(
"osl_receiveSocket failed : %i '%s'"
,
nRead
,
"EOL"
);
}
return
nRead
;
}
/*****************************************************************************/
/* osl_receiveFromSocket */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_receiveFromSocket
(
oslSocket
pSocket
,
oslSocketAddr
pSenderAddr
,
void
*
pBuffer
,
sal_uInt32
BufferSize
,
oslSocketMsgFlag
Flag
)
{
int
nRead
;
struct
sockaddr
*
pSystemSockAddr
=
0
;
int
AddrLen
=
0
;
if
(
pSenderAddr
)
{
AddrLen
=
sizeof
(
struct
sockaddr
);
pSystemSockAddr
=
&
(
pSenderAddr
->
m_sockaddr
);
}
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
OSL_TRACE
(
"osl_receiveFromSocket : Invalid socket"
);
return
-
1
;
}
pSocket
->
m_nLastError
=
0
;
nRead
=
recvfrom
(
pSocket
->
m_Socket
,
(
sal_Char
*
)
pBuffer
,
BufferSize
,
MSG_FLAG_TO_NATIVE
(
Flag
),
pSystemSockAddr
,
PTR_SIZE_T
(
AddrLen
));
if
(
nRead
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_receiveFromSocket failed : %i '%s'"
,
nRead
,
strerror
(
errno
));
}
else
if
(
nRead
==
0
)
{
OSL_TRACE
(
"osl_receiveSocket failed : %i '%s'"
,
nRead
,
"EOL"
);
}
return
nRead
;
}
/*****************************************************************************/
/* osl_sendSocket */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_sendSocket
(
oslSocket
pSocket
,
const
void
*
pBuffer
,
sal_uInt32
BytesToSend
,
oslSocketMsgFlag
Flag
)
{
int
nWritten
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
OSL_TRACE
(
"osl_sendSocket : Invalid socket"
);
return
-
1
;
}
pSocket
->
m_nLastError
=
0
;
do
{
nWritten
=
send
(
pSocket
->
m_Socket
,
(
sal_Char
*
)
pBuffer
,
BytesToSend
,
MSG_FLAG_TO_NATIVE
(
Flag
));
}
while
(
nWritten
<
0
&&
errno
==
EINTR
);
if
(
nWritten
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_sendSocket failed : %i '%s'"
,
nWritten
,
strerror
(
errno
));
}
else
if
(
nWritten
==
0
)
{
OSL_TRACE
(
"osl_sendSocket failed : %i '%s'"
,
nWritten
,
"EOL"
);
}
return
nWritten
;
}
/*****************************************************************************/
/* osl_sendToSocket */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_sendToSocket
(
oslSocket
pSocket
,
oslSocketAddr
ReceiverAddr
,
const
void
*
pBuffer
,
sal_uInt32
BytesToSend
,
oslSocketMsgFlag
Flag
)
{
int
nWritten
;
struct
sockaddr
*
pSystemSockAddr
=
0
;
int
AddrLen
=
0
;
if
(
ReceiverAddr
)
{
pSystemSockAddr
=
&
(
ReceiverAddr
->
m_sockaddr
);
AddrLen
=
sizeof
(
struct
sockaddr
);
}
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
OSL_TRACE
(
"osl_sendToSocket : Invalid socket"
);
return
-
1
;
}
pSocket
->
m_nLastError
=
0
;
/* ReceiverAddr might be 0 when used on a connected socket. */
/* Then sendto should behave like send. */
nWritten
=
sendto
(
pSocket
->
m_Socket
,
(
sal_Char
*
)
pBuffer
,
BytesToSend
,
MSG_FLAG_TO_NATIVE
(
Flag
),
pSystemSockAddr
,
AddrLen
);
if
(
nWritten
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_sendToSocket failed : %i '%s'"
,
nWritten
,
strerror
(
errno
));
}
else
if
(
nWritten
==
0
)
{
OSL_TRACE
(
"osl_sendToSocket failed : %i '%s'"
,
nWritten
,
"EOL"
);
}
return
nWritten
;
}
/*****************************************************************************/
/* osl_readSocket */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_readSocket
(
oslSocket
pSocket
,
void
*
pBuffer
,
sal_Int32
n
)
{
sal_uInt8
*
Ptr
=
(
sal_uInt8
*
)
pBuffer
;
sal_uInt32
BytesRead
=
0
;
sal_uInt32
BytesToRead
=
n
;
OSL_ASSERT
(
pSocket
);
/* loop until all desired bytes were read or an error occured */
while
(
BytesToRead
>
0
)
{
sal_Int32
RetVal
;
RetVal
=
osl_receiveSocket
(
pSocket
,
Ptr
,
BytesToRead
,
osl_Socket_MsgNormal
);
/* error occured? */
if
(
RetVal
<=
0
)
{
break
;
}
BytesToRead
-=
RetVal
;
BytesRead
+=
RetVal
;
Ptr
+=
RetVal
;
}
return
BytesRead
;
}
/*****************************************************************************/
/* osl_writeSocket */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_writeSocket
(
oslSocket
pSocket
,
const
void
*
pBuffer
,
sal_Int32
n
)
{
/* loop until all desired bytes were send or an error occured */
sal_uInt32
BytesSend
=
0
;
sal_uInt32
BytesToSend
=
n
;
sal_uInt8
*
Ptr
=
(
sal_uInt8
*
)
pBuffer
;
OSL_ASSERT
(
pSocket
);
while
(
BytesToSend
>
0
)
{
sal_Int32
RetVal
;
RetVal
=
osl_sendSocket
(
pSocket
,
Ptr
,
BytesToSend
,
osl_Socket_MsgNormal
);
/* error occured? */
if
(
RetVal
<=
0
)
{
break
;
}
BytesToSend
-=
RetVal
;
BytesSend
+=
RetVal
;
Ptr
+=
RetVal
;
}
return
BytesSend
;
}
/*****************************************************************************/
/* osl_isReceiveReady */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_isReceiveReady
(
oslSocket
pSocket
,
const
TimeValue
*
pTimeout
)
{
fd_set
fds
;
struct
timeval
tv
;
int
result
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
FD_ZERO
(
&
fds
);
FD_SET
(
pSocket
->
m_Socket
,
&
fds
);
if
(
pTimeout
)
{
tv
.
tv_sec
=
pTimeout
->
Seconds
;
tv
.
tv_usec
=
pTimeout
->
Nanosec
/
1000L
;
}
result
=
select
(
pSocket
->
m_Socket
+
1
,
/* highest socketno to monitor */
PTR_FD_SET
(
fds
),
/* check read operations */
0
,
/* check write ops */
0
,
/* ckeck for OOB */
(
pTimeout
)
?
&
tv
:
0
);
/* use timeout? */
if
(
result
<
0
)
/* error */
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_isReceiveReady(): select-error: %d (%s)
\n
"
,
errno
,
strerror
(
errno
));
return
sal_False
;
}
if
(
result
==
0
)
/* timeout */
{
pSocket
->
m_nLastError
=
errno
;
return
sal_False
;
}
return
sal_True
;
}
/*****************************************************************************/
/* osl_isSendReady */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_isSendReady
(
oslSocket
pSocket
,
const
TimeValue
*
pTimeout
)
{
fd_set
fds
;
struct
timeval
tv
;
int
nRet
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
FD_ZERO
(
&
fds
);
FD_SET
(
pSocket
->
m_Socket
,
&
fds
);
if
(
pTimeout
)
{
tv
.
tv_sec
=
pTimeout
->
Seconds
;
tv
.
tv_usec
=
pTimeout
->
Nanosec
/
1000L
;
}
nRet
=
select
(
pSocket
->
m_Socket
+
1
,
/* highest socketno to monitor */
0
,
/* check read operations */
PTR_FD_SET
(
fds
),
/* check write ops */
0
,
/* ckeck for OOB */
(
pTimeout
)
?
&
tv
:
0
);
/* use timeout? */
if
(
nRet
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_isSendReady(): select-error: %d (%s)
\n
"
,
errno
,
strerror
(
errno
));
return
sal_False
;
}
if
(
nRet
==
0
)
{
pSocket
->
m_nLastError
=
errno
;
return
sal_False
;
}
return
sal_True
;
}
/*****************************************************************************/
/* osl_isExceptionPending */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_isExceptionPending
(
oslSocket
pSocket
,
const
TimeValue
*
pTimeout
)
{
fd_set
fds
;
struct
timeval
tv
;
int
nRet
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
FD_ZERO
(
&
fds
);
FD_SET
(
pSocket
->
m_Socket
,
&
fds
);
if
(
pTimeout
)
{
tv
.
tv_sec
=
pTimeout
->
Seconds
;
tv
.
tv_usec
=
pTimeout
->
Nanosec
/
1000L
;
}
nRet
=
select
(
pSocket
->
m_Socket
+
1
,
/* highest socketno to monitor */
0
,
/* check read operations */
0
,
/* check write ops */
PTR_FD_SET
(
fds
),
/* ckeck for OOB */
(
pTimeout
)
?
&
tv
:
0
);
/* use timeout? */
if
(
nRet
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
OSL_TRACE
(
"osl_isExceptionPending(): select-error: %d (%s)
\n
"
,
errno
,
strerror
(
errno
));
return
sal_False
;
}
if
(
nRet
==
0
)
{
pSocket
->
m_nLastError
=
errno
;
return
sal_False
;
}
return
sal_True
;
}
/*****************************************************************************/
/* osl_shutdownSocket */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_shutdownSocket
(
oslSocket
pSocket
,
oslSocketDirection
Direction
)
{
int
nRet
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
nRet
=
shutdown
(
pSocket
->
m_Socket
,
DIRECTION_TO_NATIVE
(
Direction
));
if
(
nRet
!=
0
)
{
pSocket
->
m_nLastError
=
errno
;
#ifdef DEBUG
fprintf
(
stderr
,
"shutdown error '%s'
\n
"
,
strerror
(
errno
));
#endif
}
return
(
nRet
==
0
);
}
/*****************************************************************************/
/* osl_getSocketOption */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_getSocketOption
(
oslSocket
pSocket
,
oslSocketOptionLevel
Level
,
oslSocketOption
Option
,
void
*
pBuffer
,
sal_uInt32
BufferLen
)
{
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
-
1
;
}
pSocket
->
m_nLastError
=
0
;
if
(
getsockopt
(
pSocket
->
m_Socket
,
OPTION_LEVEL_TO_NATIVE
(
Level
),
OPTION_TO_NATIVE
(
Option
),
(
sal_Char
*
)
pBuffer
,
PTR_SIZE_T
(
BufferLen
))
==
-
1
)
{
pSocket
->
m_nLastError
=
errno
;
return
-
1
;
}
return
BufferLen
;
}
/*****************************************************************************/
/* osl_setSocketOption */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_setSocketOption
(
oslSocket
pSocket
,
oslSocketOptionLevel
Level
,
oslSocketOption
Option
,
void
*
pBuffer
,
sal_uInt32
BufferLen
)
{
int
nRet
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
nRet
=
setsockopt
(
pSocket
->
m_Socket
,
OPTION_LEVEL_TO_NATIVE
(
Level
),
OPTION_TO_NATIVE
(
Option
),
(
sal_Char
*
)
pBuffer
,
BufferLen
);
if
(
nRet
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
return
sal_False
;
}
return
sal_True
;
}
/*****************************************************************************/
/* osl_enableNonBlockingMode */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_enableNonBlockingMode
(
oslSocket
pSocket
,
sal_Bool
On
)
{
int
flags
;
int
nRet
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
flags
=
fcntl
(
pSocket
->
m_Socket
,
F_GETFL
,
0
);
if
(
On
)
flags
|=
O_NONBLOCK
;
else
flags
&=
~
(
O_NONBLOCK
);
nRet
=
fcntl
(
pSocket
->
m_Socket
,
F_SETFL
,
flags
);
if
(
nRet
<
0
)
{
pSocket
->
m_nLastError
=
errno
;
return
sal_False
;
}
return
sal_True
;
}
/*****************************************************************************/
/* osl_isNonBlockingMode */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_isNonBlockingMode
(
oslSocket
pSocket
)
{
int
flags
;
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
sal_False
;
}
pSocket
->
m_nLastError
=
0
;
flags
=
fcntl
(
pSocket
->
m_Socket
,
F_GETFL
,
0
);
if
(
flags
==
-
1
||
!
(
flags
&
O_NONBLOCK
))
return
sal_False
;
else
return
sal_True
;
}
/*****************************************************************************/
/* osl_getSocketType */
/*****************************************************************************/
oslSocketType
SAL_CALL
osl_getSocketType
(
oslSocket
pSocket
)
{
int
Type
=
0
;
sal_uInt32
TypeSize
=
sizeof
(
Type
);
OSL_ASSERT
(
pSocket
);
if
(
pSocket
==
0
)
{
return
osl_Socket_TypeInvalid
;
}
pSocket
->
m_nLastError
=
0
;
if
(
getsockopt
(
pSocket
->
m_Socket
,
OPTION_LEVEL_TO_NATIVE
(
osl_Socket_LevelSocket
),
OPTION_TO_NATIVE
(
osl_Socket_OptionType
),
(
sal_Char
*
)
&
Type
,
PTR_SIZE_T
(
TypeSize
))
==
-
1
)
{
/* error */
pSocket
->
m_nLastError
=
errno
;
return
osl_Socket_TypeInvalid
;
}
return
TYPE_FROM_NATIVE
(
Type
);
}
/*****************************************************************************/
/* osl_getLastSocketErrorDescription */
/*****************************************************************************/
void
SAL_CALL
osl_getLastSocketErrorDescription
(
oslSocket
Socket
,
rtl_uString
**
ustrError
)
{
sal_Char
pszError
[
1024
];
pszError
[
0
]
=
'\0'
;
osl_psz_getLastSocketErrorDescription
(
Socket
,
pszError
,
sizeof
(
pszError
));
rtl_uString_newFromAscii
(
ustrError
,
pszError
);
return
;
}
void
SAL_CALL
osl_psz_getLastSocketErrorDescription
(
oslSocket
pSocket
,
sal_Char
*
pBuffer
,
sal_uInt32
BufferSize
)
{
/* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
pBuffer
[
BufferSize
-
1
]
=
'\0'
;
if
(
pSocket
==
0
)
{
strncpy
(
pBuffer
,
strerror
(
EINVAL
),
BufferSize
-
1
);
return
;
}
strncpy
(
pBuffer
,
strerror
(
pSocket
->
m_nLastError
),
BufferSize
-
1
);
return
;
}
/*****************************************************************************/
/* osl_getLastSocketError */
/*****************************************************************************/
oslSocketError
SAL_CALL
osl_getLastSocketError
(
oslSocket
pSocket
)
{
if
(
pSocket
==
0
)
{
return
ERROR_FROM_NATIVE
(
EINVAL
);
}
return
ERROR_FROM_NATIVE
(
pSocket
->
m_nLastError
);
}
/*****************************************************************************/
/* SocketSet */
/*****************************************************************************/
typedef
struct
_TSocketSetImpl
{
int
m_MaxHandle
;
/* for select(), the largest descriptor in the set */
fd_set
m_Set
;
/* the set of descriptors */
}
TSocketSetImpl
;
/*****************************************************************************/
/* osl_createSocketSet */
/*****************************************************************************/
oslSocketSet
SAL_CALL
osl_createSocketSet
()
{
TSocketSetImpl
*
pSet
;
pSet
=
(
TSocketSetImpl
*
)
malloc
(
sizeof
(
TSocketSetImpl
));
OSL_ASSERT
(
pSet
);
if
(
pSet
)
{
pSet
->
m_MaxHandle
=
0
;
FD_ZERO
(
&
pSet
->
m_Set
);
}
return
(
oslSocketSet
)
pSet
;
}
/*****************************************************************************/
/* osl_destroySocketSet */
/*****************************************************************************/
void
SAL_CALL
osl_destroySocketSet
(
oslSocketSet
Set
)
{
if
(
Set
)
free
(
Set
);
}
/*****************************************************************************/
/* osl_clearSocketSet */
/*****************************************************************************/
void
SAL_CALL
osl_clearSocketSet
(
oslSocketSet
Set
)
{
TSocketSetImpl
*
pSet
;
OSL_ASSERT
(
Set
);
if
(
Set
==
0
)
{
return
;
}
pSet
=
(
TSocketSetImpl
*
)
Set
;
pSet
->
m_MaxHandle
=
0
;
FD_ZERO
(
&
pSet
->
m_Set
);
}
/*****************************************************************************/
/* osl_addToSocketSet */
/*****************************************************************************/
void
SAL_CALL
osl_addToSocketSet
(
oslSocketSet
Set
,
oslSocket
pSocket
)
{
TSocketSetImpl
*
pSet
;
OSL_ASSERT
(
Set
);
OSL_ASSERT
(
pSocket
);
if
(
Set
==
0
||
pSocket
==
0
)
{
return
;
}
pSet
=
(
TSocketSetImpl
*
)
Set
;
/* correct max handle */
if
(
pSocket
->
m_Socket
>
pSet
->
m_MaxHandle
)
pSet
->
m_MaxHandle
=
pSocket
->
m_Socket
;
FD_SET
(
pSocket
->
m_Socket
,
&
pSet
->
m_Set
);
}
/*****************************************************************************/
/* osl_removeFromSocketSet */
/*****************************************************************************/
void
SAL_CALL
osl_removeFromSocketSet
(
oslSocketSet
Set
,
oslSocket
pSocket
)
{
TSocketSetImpl
*
pSet
;
OSL_ASSERT
(
Set
);
OSL_ASSERT
(
pSocket
);
if
(
Set
==
0
||
pSocket
==
0
)
{
return
;
}
pSet
=
(
TSocketSetImpl
*
)
Set
;
/* correct max handle */
if
(
pSocket
->
m_Socket
==
pSet
->
m_MaxHandle
)
{
/* not optimal, since the next used descriptor might be */
/* much smaller than m_Socket-1, but it will do */
pSet
->
m_MaxHandle
--
;
if
(
pSet
->
m_MaxHandle
<
0
)
{
pSet
->
m_MaxHandle
=
0
;
/* avoid underflow */
}
}
FD_CLR
(
pSocket
->
m_Socket
,
&
pSet
->
m_Set
);
}
/*****************************************************************************/
/* osl_isInSocketSet */
/*****************************************************************************/
sal_Bool
SAL_CALL
osl_isInSocketSet
(
oslSocketSet
Set
,
oslSocket
pSocket
)
{
TSocketSetImpl
*
pSet
;
OSL_ASSERT
(
Set
);
OSL_ASSERT
(
pSocket
);
if
(
Set
==
0
||
pSocket
==
0
)
{
return
sal_False
;
}
pSet
=
(
TSocketSetImpl
*
)
Set
;
return
(
FD_ISSET
(
pSocket
->
m_Socket
,
&
pSet
->
m_Set
)
!=
0
);
}
/*****************************************************************************/
/* osl_demultiplexSocketEvents */
/*****************************************************************************/
sal_Int32
SAL_CALL
osl_demultiplexSocketEvents
(
oslSocketSet
IncomingSet
,
oslSocketSet
OutgoingSet
,
oslSocketSet
OutOfBandSet
,
const
TimeValue
*
pTimeout
)
{
int
MaxHandle
=
0
;
struct
timeval
tv
;
TSocketSetImpl
*
pInSet
;
TSocketSetImpl
*
pOutSet
;
TSocketSetImpl
*
pOOBSet
;
if
(
pTimeout
)
{
/* non-blocking call */
tv
.
tv_sec
=
pTimeout
->
Seconds
;
tv
.
tv_usec
=
pTimeout
->
Nanosec
/
1000L
;
}
/* map opaque data to impl-types */
pInSet
=
(
TSocketSetImpl
*
)
IncomingSet
;
pOutSet
=
(
TSocketSetImpl
*
)
OutgoingSet
;
pOOBSet
=
(
TSocketSetImpl
*
)
OutOfBandSet
;
/* get max handle from all sets */
if
(
pInSet
)
MaxHandle
=
pInSet
->
m_MaxHandle
;
if
(
pOutSet
&&
(
pOutSet
->
m_MaxHandle
>
MaxHandle
))
MaxHandle
=
pOutSet
->
m_MaxHandle
;
if
(
pOOBSet
&&
(
pOOBSet
->
m_MaxHandle
>
MaxHandle
))
MaxHandle
=
pOOBSet
->
m_MaxHandle
;
return
select
(
MaxHandle
+
1
,
pInSet
?
PTR_FD_SET
(
pInSet
->
m_Set
)
:
0
,
pOutSet
?
PTR_FD_SET
(
pOutSet
->
m_Set
)
:
0
,
pOOBSet
?
PTR_FD_SET
(
pOOBSet
->
m_Set
)
:
0
,
pTimeout
?
&
tv
:
0
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment