diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index d7a92a12eb..7074fcd5eb 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -38,13 +38,12 @@ qtConfig(dnslookup) { } unix { - !integrity:qtConfig(dnslookup) { - SOURCES += kernel/qdnslookup_unix.cpp - qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl - } + !integrity:qtConfig(dnslookup): SOURCES += kernel/qdnslookup_unix.cpp SOURCES += kernel/qhostinfo_unix.cpp + qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl + qtConfig(linux-netlink): SOURCES += kernel/qnetworkinterface_linux.cpp else: SOURCES += kernel/qnetworkinterface_unix.cpp } diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index d22608e22f..e4810d68ee 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -66,6 +66,10 @@ # include #endif +#if defined(Q_OS_FREEBSD) || QT_CONFIG(dlopen) +# include +#endif + QT_BEGIN_NAMESPACE // Almost always the same. If not, specify in qplatformdefs.h. @@ -115,6 +119,18 @@ struct LibResolv }; } +static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym) +{ + if (lib.isLoaded()) + return lib.resolve(sym); + +#if defined(RTLD_DEFAULT) && (defined(Q_OS_FREEBSD) || QT_CONFIG(dlopen)) + return reinterpret_cast(dlsym(RTLD_DEFAULT, sym)); +#else + return nullptr; +#endif +} + LibResolv::LibResolv() { QLibrary lib; @@ -124,31 +140,30 @@ LibResolv::LibResolv() #endif { lib.setFileName(QLatin1String("resolv")); - if (!lib.load()) - return; + lib.load(); } // res_ninit is required for localDomainName() - local_res_ninit = res_ninit_proto(lib.resolve("__res_ninit")); + local_res_ninit = res_ninit_proto(resolveSymbol(lib, "__res_ninit")); if (!local_res_ninit) - local_res_ninit = res_ninit_proto(lib.resolve("res_ninit")); + local_res_ninit = res_ninit_proto(resolveSymbol(lib, "res_ninit")); if (local_res_ninit) { // we must now find res_nclose - local_res_nclose = res_nclose_proto(lib.resolve("res_nclose")); + local_res_nclose = res_nclose_proto(resolveSymbol(lib, "res_nclose")); if (!local_res_nclose) - local_res_nclose = res_nclose_proto(lib.resolve("__res_nclose")); + local_res_nclose = res_nclose_proto(resolveSymbol(lib, "__res_nclose")); if (!local_res_nclose) local_res_ninit = nullptr; } if (ReinitNecessary || !local_res_ninit) { - local_res_init = res_init_proto(lib.resolve("__res_init")); + local_res_init = res_init_proto(resolveSymbol(lib, "__res_init")); if (!local_res_init) - local_res_init = res_init_proto(lib.resolve("res_init")); + local_res_init = res_init_proto(resolveSymbol(lib, "res_init")); if (local_res_init && !local_res_ninit) { // if we can't get a thread-safe context, we have to use the global _res state - local_res = res_state_ptr(lib.resolve("_res")); + local_res = res_state_ptr(resolveSymbol(lib, "_res")); } } }