#include "wx/object.h"
#include "wx/log.h"
#include "wx/intl.h"
+ #include "wx/thread.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
- #if !defined(__MWERKS__)
- #include <memory.h>
- #endif
+ #include <memory.h>
#endif // !WX_PRECOMP
#include "wx/socket.h"
#include "wx/private/socket.h"
#include "wx/private/sckaddr.h"
-#ifdef __UNIX__
+#include <errno.h>
+
+#if defined(__UNIX__) && !defined(__WXMSW__)
#include <netdb.h>
#include <arpa/inet.h>
#endif // __UNIX__
// ============================================================================
// TODO: use POSIX getaddrinfo() (also available in Winsock 2) for simplicity
-// and IPv6 support
+// and to use the same code for IPv4 and IPv6 support
-#ifdef __WXMSW__
+#ifdef __WINDOWS__
#define HAVE_INET_ADDR
+ #ifndef HAVE_GETHOSTBYNAME
#define HAVE_GETHOSTBYNAME
+ #endif
+ #ifndef HAVE_GETSERVBYNAME
#define HAVE_GETSERVBYNAME
+ #endif
// under MSW getxxxbyname() functions are MT-safe (but not reentrant) so
// we don't need to serialize calls to them
#define wxHAS_MT_SAFE_GETBY_FUNCS
-#endif // __WXMSW__
+
+ #if wxUSE_IPV6
+ // this header does dynamic dispatching of getaddrinfo/freeaddrinfo()
+ // by implementing them in its own code if the system versions are not
+ // available (as is the case for anything < XP)
+ //
+ // NB: if this is not available for the other compilers (so far tested
+ // with MSVC only) we should just use wxDynamicLibrary "manually"
+ #ifdef __VISUALC__
+ // disable a warning occurring in Microsoft own version of this file
+ #pragma warning(disable:4706)
+ #endif
+ #include <wspiapi.h>
+ #ifdef __VISUALC__
+ #pragma warning(default:4706)
+ #endif
+ #endif
+#endif // __WINDOWS__
// we assume that we have gethostbyaddr_r() if and only if we have
// gethostbyname_r() and that it uses the similar conventions to it (see
#endif
// the _r functions need the extra buffer parameter but unfortunately its type
-// differs between different systems
+// differs between different systems and for the systems which use opaque
+// structs for it (at least AIX and OpenBSD) it must be zero-filled before
+// being passed to the system functions
#ifdef HAVE_FUNC_GETHOSTBYNAME_R_3
- typedef hostent_data wxGethostBuf;
+ struct wxGethostBuf : hostent_data
+ {
+ wxGethostBuf()
+ {
+ memset(this, 0, sizeof(hostent_data));
+ }
+ };
#else
typedef char wxGethostBuf[1024];
#endif
-#ifdef HAVE_FUNC_GETSERVBYNAME_R_3
- typedef servent_data wxGetservBuf;
+#ifdef HAVE_FUNC_GETSERVBYNAME_R_4
+ struct wxGetservBuf : servent_data
+ {
+ wxGetservBuf()
+ {
+ memset(this, 0, sizeof(servent_data));
+ }
+ };
#else
typedef char wxGetservBuf[1024];
#endif
-#ifdef wxHAS_MT_SAFE_GETBY_FUNCS
+#if defined(wxHAS_MT_SAFE_GETBY_FUNCS) || !wxUSE_THREADS
#define wxLOCK_GETBY_MUTEX(name)
#else // may need mutexes to protect getxxxbyxxx() calls
#if defined(HAVE_GETHOSTBYNAME) || \
#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
he = gethostbyname_r(hostname, h, buffer, size, err);
#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
- he = gethostbyname_r(hostname, h, &buffer);
- *err = h_errno;
+ wxUnusedVar(var);
+ *err = gethostbyname_r(hostname, h, &buffer);
+ he = h;
#elif defined(HAVE_GETHOSTBYNAME)
wxLOCK_GETBY_MUTEX(name);
#elif defined(HAVE_FUNC_GETHOSTBYADDR_R_5)
he = gethostbyaddr_r(addr_buf, buf_size, proto, h, buffer, size, err);
#elif defined(HAVE_FUNC_GETHOSTBYADDR_R_3)
- he = gethostbyaddr_r(addr_buf, buf_size, proto, h, buffer);
- *err = h_errno;
+ wxUnusedVar(size);
+ *err = gethostbyaddr_r(addr_buf, buf_size, proto, h, &buffer);
+ he = h;
#elif defined(HAVE_GETHOSTBYADDR)
wxLOCK_GETBY_MUTEX(addr);
servent *wxGetservbyname_r(const char *port,
const char *protocol,
servent *serv,
- wxGetservBuf buffer,
+ wxGetservBuf& buffer,
int size)
{
servent *se;
#elif defined(HAVE_FUNC_GETSERVBYNAME_R_5)
se = getservbyname_r(port, protocol, serv, buffer, size);
#elif defined(HAVE_FUNC_GETSERVBYNAME_R_4)
- se = getservbyname_r(port, protocol, serv, &buffer);
+ wxUnusedVar(size);
+ if ( getservbyname_r(port, protocol, serv, &buffer) != 0 )
+ return NULL;
#elif defined(HAVE_GETSERVBYNAME)
wxLOCK_GETBY_MUTEX(serv);
if ( !addr )
return false;
- const wxUTF8Buf namebuf(name.utf8_str());
+ const wxScopedCharBuffer namebuf(name.utf8_str());
// first check if this is an address in quad dotted notation
#if defined(HAVE_INET_ATON)
if ( !addr )
return false;
- const wxUTF8Buf buf(path.utf8_str());
+ const wxScopedCharBuffer buf(path.utf8_str());
if ( strlen(buf) >= UNIX_PATH_MAX )
return false;
// wxSockAddress
// ----------------------------------------------------------------------------
+const sockaddr *wxSockAddress::GetAddressData() const
+{
+ return GetAddress().GetAddr();
+}
+
+int wxSockAddress::GetAddressDataLen() const
+{
+ return GetAddress().GetLen();
+}
+
void wxSockAddress::Init()
{
- if ( !wxSocketBase::IsInitialized() )
+ if ( wxIsMainThread() && !wxSocketBase::IsInitialized() )
{
// we must do it before using any socket functions
(void)wxSocketBase::Initialize();
return wxString::Format
(
- "%lu.%lu.%lu.%lu",
+ "%u.%u.%u.%u",
(addr >> 24) & 0xff,
(addr >> 16) & 0xff,
(addr >> 8) & 0xff,