diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-04-08 14:14:16 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-08-13 16:34:51 +0000 |
commit | 01d0b1d6e3fe76d1cd09eeb6474c69e712f37b16 (patch) | |
tree | e6b489dd67209f2235bc077b52657a84a06cbfec /src/corelib/global | |
parent | 2366ca059e6c4b8ae93a125eb8df8f660275d527 (diff) |
Merge the multiple implementations of getting the local hostname
This commit moves the functionality from QtNetwork's QHostInfo to
QtCore. Note that due to Windows ws2_32.dll's quirky behavior of
requiring WSAStartup before calling gethostname, this change required
moving the initialization to QtCore too.
On Linux systems, gethostname() gets the name from uname(), so we bypass
the middle man and save one memcpy.
Change-Id: I27eaacb532114dd188c4ffff13d32655a6301346
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global')
-rw-r--r-- | src/corelib/global/qglobal.cpp | 124 | ||||
-rw-r--r-- | src/corelib/global/qsysinfo.h | 2 |
2 files changed, 126 insertions, 0 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 37a765b40a..77ac53f7e9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -65,6 +65,20 @@ # endif #endif +#ifdef Q_OS_WINRT +#include <wrl.h> +#include <windows.networking.h> +#include <windows.networking.sockets.h> +#include <windows.networking.connectivity.h> +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; +using namespace ABI::Windows::Networking; +using namespace ABI::Windows::Networking::Connectivity; +using namespace ABI::Windows::Networking::Sockets; +#endif + #if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL) # include <envLib.h> #endif @@ -90,6 +104,10 @@ #include <private/qcore_unix_p.h> #endif +#ifdef Q_OS_BSD4 +#include <sys/sysctl.h> +#endif + #include "archdetect.cpp" QT_BEGIN_NAMESPACE @@ -1887,6 +1905,36 @@ QT_END_INCLUDE_NAMESPACE #ifndef Q_OS_WINRT +# ifndef QT_BOOTSTRAPPED +class QWindowsSockInit +{ +public: + QWindowsSockInit(); + ~QWindowsSockInit(); + int version; +}; + +QWindowsSockInit::QWindowsSockInit() +: version(0) +{ + //### should we try for 2.2 on all platforms ?? + WSAData wsadata; + + // IPv6 requires Winsock v2.0 or better. + if (WSAStartup(MAKEWORD(2,0), &wsadata) != 0) { + qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed."); + } else { + version = 0x20; + } +} + +QWindowsSockInit::~QWindowsSockInit() +{ + WSACleanup(); +} +Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit) +# endif // QT_BOOTSTRAPPED + # ifndef Q_OS_WINCE // Determine Windows versions >= 8 by querying the version of kernel32.dll. @@ -2775,6 +2823,82 @@ QString QSysInfo::prettyProductName() return unknownText(); } +#ifndef QT_BOOTSTRAPPED +/*! + \since 5.6 + + Returns this machine's host name, if one is configured. Note that hostnames + are not guaranteed to be globally unique, especially if they were + configured automatically. + + This function does not guarantee the returned host name is a Fully + Qualified Domain Name (FQDN). For that, use QHostInfo to resolve the + returned name to an FQDN. + + This function returns the same as QHostInfo::localHostName(). + + \sa QHostInfo::localDomainName + */ +QString QSysInfo::machineHostName() +{ +#if defined(Q_OS_LINUX) + // gethostname(3) on Linux just calls uname(2), so do it ourselves + // and avoid a memcpy + struct utsname u; + if (uname(&u) == 0) + return QString::fromLocal8Bit(u.nodename); +#elif defined(Q_OS_WINRT) + ComPtr<INetworkInformationStatics> statics; + GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics); + + ComPtr<IVectorView<HostName *>> hostNames; + statics->GetHostNames(&hostNames); + if (!hostNames) + return QString(); + + unsigned int size; + hostNames->get_Size(&size); + if (size == 0) + return QString(); + + for (unsigned int i = 0; i < size; ++i) { + ComPtr<IHostName> hostName; + hostNames->GetAt(i, &hostName); + HostNameType type; + hostName->get_Type(&type); + if (type != HostNameType_DomainName) + continue; + + HString name; + hostName->get_CanonicalName(name.GetAddressOf()); + UINT32 length; + PCWSTR rawString = name.GetRawBuffer(&length); + return QString::fromWCharArray(rawString, length); + } + ComPtr<IHostName> firstHost; + hostNames->GetAt(0, &firstHost); + + HString name; + firstHost->get_CanonicalName(name.GetAddressOf()); + UINT32 length; + PCWSTR rawString = name.GetRawBuffer(&length); + return QString::fromWCharArray(rawString, length); +#else +# ifdef Q_OS_WIN + // Important: QtNetwork depends on machineHostName() initializing ws2_32.dll + winsockInit(); +# endif + + char hostName[512]; + if (gethostname(hostName, sizeof(hostName)) == -1) + return QString(); + hostName[sizeof(hostName) - 1] = '\0'; + return QString::fromLocal8Bit(hostName); +#endif + return QString(); +} +#endif // QT_BOOTSTRAPPED + /*! \macro void Q_ASSERT(bool test) \relates <QtGlobal> diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h index d40e6659c7..27a285fd36 100644 --- a/src/corelib/global/qsysinfo.h +++ b/src/corelib/global/qsysinfo.h @@ -186,6 +186,8 @@ public: static QString productType(); static QString productVersion(); static QString prettyProductName(); + + static QString machineHostName(); }; QT_END_NAMESPACE |