Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdbus_symbols.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:load-external-library-via-qlibrary
5
7#include <QtCore/qlatin1stringview.h>
8#if QT_CONFIG(library)
9#include <QtCore/qlibrary.h>
10#include <QtCore/private/qlocking_p.h>
11#endif
12#include <QtCore/qmutex.h>
13
14#ifndef QT_NO_DBUS
15
17
18using namespace Qt::StringLiterals;
19
20#if !defined QT_LINKED_LIBDBUS
21
22#if QT_CONFIG(library)
23Q_CONSTINIT static QLibrary *qdbus_libdbus = nullptr;
24
25void qdbus_unloadLibDBus()
26{
27 if (qdbus_libdbus) {
28 if (qEnvironmentVariableIsSet("QDBUS_FORCE_SHUTDOWN"))
29 qdbus_libdbus->resolve("dbus_shutdown")();
30 qdbus_libdbus->unload();
31 }
32 delete qdbus_libdbus;
33 qdbus_libdbus = nullptr;
34}
35#endif
36
38{
39#if QT_CONFIG(library)
40#ifdef QT_BUILD_INTERNAL
41 // this is to simulate a library load failure for our autotest suite.
42 if (!qEnvironmentVariableIsEmpty("QT_SIMULATE_DBUS_LIBFAIL"))
43 return false;
44#endif
45
46 Q_CONSTINIT static bool triedToLoadLibrary = false;
47 Q_CONSTINIT static QBasicMutex mutex;
48 const auto locker = qt_scoped_lock(mutex);
49
50 QLibrary *&lib = qdbus_libdbus;
51 if (triedToLoadLibrary)
52 return lib && lib->isLoaded();
53
54 lib = new QLibrary;
55 lib->setLoadHints(QLibrary::ExportExternalSymbolsHint); // make libdbus symbols available for apps that need more advanced control over the dbus
56 triedToLoadLibrary = true;
57
58 static constexpr int majorversions[] = { 3, 2, -1 };
59 const QString baseNames[] = {
60#ifdef Q_OS_WIN
61 "dbus-1"_L1,
62#endif
63 "libdbus-1"_L1
64 };
65
66 lib->unload();
67 for (const int majorversion : majorversions) {
68 for (const QString &baseName : baseNames) {
69#ifdef Q_OS_WIN
70 QString suffix;
71 if (majorversion != -1)
72 suffix = QString::number(- majorversion); // negative so it prepends the dash
73 lib->setFileName(baseName + suffix);
74#else
75 lib->setFileNameAndVersion(baseName, majorversion);
76#endif
77 if (lib->load() && lib->resolve("dbus_connection_open_private"))
78 return true;
79
80 lib->unload();
81 }
82 }
83
84 delete lib;
85 lib = nullptr;
86 return false;
87#else
88 return true;
89#endif
90}
91
93{
94#if QT_CONFIG(library)
95 if (qdbus_loadLibDBus())
96 return qdbus_libdbus->resolve(name);
97#else
98 Q_UNUSED(name);
99#endif
100 return nullptr;
101}
102
104{
105#if QT_CONFIG(library)
106 if (Q_UNLIKELY(!qdbus_loadLibDBus()))
107 qFatal("Cannot find libdbus-1 in your system to resolve symbol '%s'.", name);
108
109 QFunctionPointer ptr = qdbus_libdbus->resolve(name);
110 if (Q_UNLIKELY(!ptr))
111 qFatal("Cannot resolve '%s' in your libdbus-1.", name);
112
113 return ptr;
114#else
115 Q_UNUSED(name);
116 return nullptr;
117#endif
118}
119
120#else
121static void qdbus_unloadLibDBus()
122{
123 if (qEnvironmentVariableIsSet("QDBUS_FORCE_SHUTDOWN"))
124 dbus_shutdown();
125}
126
127#endif // !QT_LINKED_LIBDBUS
128
129#if defined(QT_LINKED_LIBDBUS) || QT_CONFIG(library)
130Q_DESTRUCTOR_FUNCTION(qdbus_unloadLibDBus)
131#endif
132
133QT_END_NAMESPACE
134
135#endif // QT_NO_DBUS
bool qdbus_loadLibDBus()
QFunctionPointer qdbus_resolve_conditionally(const char *name)
QFunctionPointer qdbus_resolve_me(const char *name)