Find libssl on linux using paths of loaded libraries

The installed path of libssl may include an element describing the
architecture, e.g. x86_64-linux-gnu or i386-linux-gnu.
In most cases, the libraries already loaded (static dependencies of
Qt, such as libc) will include the path where libssl is installed.

Use dl_iterate_phdr to find the paths. This is a linux specific
function, but it does provide "/lib/<arch>" and "/usr/lib/<arch>"
at the point ssl symbols are being resolved when running the
qsslsocket autotest (which has less dependencies than a typical
Qt app).

Task-number: QTBUG-24694
Change-Id: I9af8081f41bb85c2fcff450a2acda5672a7f7518
Reviewed-by: Harald Fernengel <harald.fernengel@nokia.com>
This commit is contained in:
Shane Kearns 2012-03-28 16:06:57 +01:00 committed by Qt by Nokia
parent 76ae64abb5
commit e5337ad1b1

View File

@ -53,6 +53,9 @@
#if defined(Q_OS_UNIX)
#include <QtCore/qdir.h>
#endif
#ifdef Q_OS_LINUX
#include <link.h>
#endif
QT_BEGIN_NAMESPACE
@ -347,6 +350,23 @@ static bool libGreaterThan(const QString &lhs, const QString &rhs)
return true;
}
#ifdef Q_OS_LINUX
static int dlIterateCallback(struct dl_phdr_info *info, size_t size, void *data)
{
if (size < sizeof (info->dlpi_addr) + sizeof (info->dlpi_name))
return 1;
QSet<QString> *paths = (QSet<QString> *)data;
QString path = QString::fromLocal8Bit(info->dlpi_name);
if (!path.isEmpty()) {
QFileInfo fi(path);
path = fi.absolutePath();
if (!path.isEmpty())
paths->insert(path);
}
return 0;
}
#endif
static QStringList findAllLibSsl()
{
QStringList paths;
@ -358,6 +378,12 @@ static QStringList findAllLibSsl()
.split(QLatin1Char(':'), QString::SkipEmptyParts);
# endif
paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
#ifdef Q_OS_LINUX
// discover paths of already loaded libraries
QSet<QString> loadedPaths;
dl_iterate_phdr(dlIterateCallback, &loadedPaths);
paths.append(loadedPaths.toList());
#endif
QStringList foundSsls;
foreach (const QString &path, paths) {