1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtDBus module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qdbusconnection.h"
42#include "qdbusconnection_p.h"
43
44#include <qdebug.h>
45#include <qcoreapplication.h>
46#include <qstringlist.h>
47#include <qvector.h>
48#include <qtimer.h>
49#include <qthread.h>
50
51#include "qdbusconnectioninterface.h"
52#include "qdbuserror.h"
53#include "qdbusmessage.h"
54#include "qdbusmessage_p.h"
55#include "qdbusinterface_p.h"
56#include "qdbusutil_p.h"
57#include "qdbusconnectionmanager_p.h"
58#include "qdbuspendingcall_p.h"
59
60#include "qdbusthreaddebug_p.h"
61
62#include <algorithm>
63
64#ifdef interface
65#undef interface
66#endif
67
68#ifndef QT_NO_DBUS
69
70QT_BEGIN_NAMESPACE
71
72#ifdef Q_OS_WIN
73static void preventDllUnload();
74#endif
75
76Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
77
78struct QDBusConnectionManager::ConnectionRequestData
79{
80 enum RequestType {
81 ConnectToStandardBus,
82 ConnectToBusByAddress,
83 ConnectToPeerByAddress
84 } type;
85
86 union {
87 QDBusConnection::BusType busType;
88 const QString *busAddress;
89 };
90 const QString *name;
91
92 QDBusConnectionPrivate *result;
93
94 bool suspendedDelivery;
95};
96
97QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::BusType type)
98{
99 Q_STATIC_ASSERT(int(QDBusConnection::SessionBus) + int(QDBusConnection::SystemBus) == 1);
100 Q_ASSERT(type == QDBusConnection::SessionBus || type == QDBusConnection::SystemBus);
101
102 if (!qdbus_loadLibDBus())
103 return 0;
104
105 // we'll start in suspended delivery mode if we're in the main thread
106 // (the event loop will resume delivery)
107 bool suspendedDelivery = qApp && qApp->thread() == QThread::currentThread();
108
109 QMutexLocker lock(&defaultBusMutex);
110 if (defaultBuses[type])
111 return defaultBuses[type];
112
113 QString name = QStringLiteral("qt_default_session_bus");
114 if (type == QDBusConnection::SystemBus)
115 name = QStringLiteral("qt_default_system_bus");
116 return defaultBuses[type] = connectToBus(type, name, suspendedDelivery);
117}
118
119QDBusConnectionPrivate *QDBusConnectionManager::connection(const QString &name) const
120{
121 return connectionHash.value(name, 0);
122}
123
124void QDBusConnectionManager::removeConnection(const QString &name)
125{
126 QDBusConnectionPrivate *d = 0;
127 d = connectionHash.take(name);
128 if (d && !d->ref.deref())
129 d->deleteLater();
130
131 // Static objects may be keeping the connection open.
132 // However, it is harmless to have outstanding references to a connection that is
133 // closing as long as those references will be soon dropped without being used.
134
135 // ### Output a warning if connections are being used after they have been removed.
136}
137
138QDBusConnectionManager::QDBusConnectionManager()
139{
140 connect(this, &QDBusConnectionManager::connectionRequested,
141 this, &QDBusConnectionManager::executeConnectionRequest, Qt::BlockingQueuedConnection);
142 connect(this, &QDBusConnectionManager::serverRequested,
143 this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection);
144 moveToThread(this); // ugly, don't do this in other projects
145
146#ifdef Q_OS_WIN
147 // prevent the library from being unloaded on Windows. See comments in the function.
148 preventDllUnload();
149#endif
150 defaultBuses[0] = defaultBuses[1] = nullptr;
151 start();
152}
153
154QDBusConnectionManager::~QDBusConnectionManager()
155{
156 quit();
157 wait();
158}
159
160QDBusConnectionManager* QDBusConnectionManager::instance()
161{
162 return _q_manager();
163}
164
165Q_DBUS_EXPORT void qDBusBindToApplication();
166void qDBusBindToApplication()
167{
168}
169
170void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionPrivate *c)
171{
172 connectionHash[name] = c;
173 c->name = name;
174}
175
176void QDBusConnectionManager::run()
177{
178 exec();
179
180 // cleanup:
181 QMutexLocker locker(&mutex);
182 for (QHash<QString, QDBusConnectionPrivate *>::const_iterator it = connectionHash.constBegin();
183 it != connectionHash.constEnd(); ++it) {
184 QDBusConnectionPrivate *d = it.value();
185 if (!d->ref.deref()) {
186 delete d;
187 } else {
188 d->closeConnection();
189 d->moveToThread(nullptr); // allow it to be deleted in another thread
190 }
191 }
192 connectionHash.clear();
193
194 // allow deletion from any thread without warning
195 moveToThread(nullptr);
196}
197
198QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(QDBusConnection::BusType type, const QString &name,
199 bool suspendedDelivery)
200{
201 ConnectionRequestData data;
202 data.type = ConnectionRequestData::ConnectToStandardBus;
203 data.busType = type;
204 data.name = &name;
205 data.suspendedDelivery = suspendedDelivery;
206
207 emit connectionRequested(&data);
208 if (suspendedDelivery && data.result->connection) {
209 data.result->ref.ref();
210 QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(data.result);
211 QTimer::singleShot(0, o, SLOT(execute()));
212 o->moveToThread(qApp->thread()); // qApp was checked in the caller
213 }
214 return data.result;
215}
216
217QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(const QString &address, const QString &name)
218{
219 ConnectionRequestData data;
220 data.type = ConnectionRequestData::ConnectToBusByAddress;
221 data.busAddress = &address;
222 data.name = &name;
223 data.suspendedDelivery = false;
224
225 emit connectionRequested(&data);
226 return data.result;
227}
228
229QDBusConnectionPrivate *QDBusConnectionManager::connectToPeer(const QString &address, const QString &name)
230{
231 ConnectionRequestData data;
232 data.type = ConnectionRequestData::ConnectToPeerByAddress;
233 data.busAddress = &address;
234 data.name = &name;
235 data.suspendedDelivery = false;
236
237 emit connectionRequested(&data);
238 return data.result;
239}
240
241void QDBusConnectionManager::executeConnectionRequest(QDBusConnectionManager::ConnectionRequestData *data)
242{
243 QMutexLocker locker(&mutex);
244 const QString &name = *data->name;
245 QDBusConnectionPrivate *&d = data->result;
246
247 // check if the connection exists by name
248 d = connection(name);
249 if (d || name.isEmpty())
250 return;
251
252 d = new QDBusConnectionPrivate;
253 DBusConnection *c = 0;
254 QDBusErrorInternal error;
255 switch (data->type) {
256 case ConnectionRequestData::ConnectToStandardBus:
257 switch (data->busType) {
258 case QDBusConnection::SystemBus:
259 c = q_dbus_bus_get_private(DBUS_BUS_SYSTEM, error);
260 break;
261 case QDBusConnection::SessionBus:
262 c = q_dbus_bus_get_private(DBUS_BUS_SESSION, error);
263 break;
264 case QDBusConnection::ActivationBus:
265 c = q_dbus_bus_get_private(DBUS_BUS_STARTER, error);
266 break;
267 }
268 break;
269
270 case ConnectionRequestData::ConnectToBusByAddress:
271 case ConnectionRequestData::ConnectToPeerByAddress:
272 c = q_dbus_connection_open_private(data->busAddress->toUtf8().constData(), error);
273 if (c && data->type == ConnectionRequestData::ConnectToBusByAddress) {
274 // register on the bus
275 if (!q_dbus_bus_register(c, error)) {
276 q_dbus_connection_unref(c);
277 c = 0;
278 }
279 }
280 break;
281 }
282
283 setConnection(name, d);
284 if (data->type == ConnectionRequestData::ConnectToPeerByAddress) {
285 d->setPeer(c, error);
286 } else {
287 // create the bus service
288 // will lock in QDBusConnectionPrivate::connectRelay()
289 d->setConnection(c, error);
290 d->createBusService();
291 if (c && data->suspendedDelivery)
292 d->setDispatchEnabled(false);
293 }
294}
295
296void QDBusConnectionManager::createServer(const QString &address, void *server)
297{
298 QDBusErrorInternal error;
299 QDBusConnectionPrivate *d = new QDBusConnectionPrivate;
300 d->setServer(static_cast<QDBusServer *>(server),
301 q_dbus_server_listen(address.toUtf8().constData(), error), error);
302}
303
304/*!
305 \class QDBusConnection
306 \inmodule QtDBus
307 \since 4.2
308
309 \brief The QDBusConnection class represents a connection to the D-Bus bus daemon.
310
311 This class is the initial point in a D-Bus session. Using it, you
312 can get access to remote objects, interfaces; connect remote
313 signals to your object's slots; register objects, etc.
314
315 D-Bus connections are created using the connectToBus() function,
316 which opens a connection to the server daemon and does the initial
317 handshaking, associating that connection with a name. Further
318 attempts to connect using the same name will return the same
319 connection.
320
321 The connection is then torn down using the disconnectFromBus()
322 function.
323
324 Once disconnected, calling connectToBus() will not reestablish a
325 connection, you must create a new QDBusConnection instance.
326
327 As a convenience for the two most common connection types, the
328 sessionBus() and systemBus() functions return open connections to
329 the session server daemon and the system server daemon,
330 respectively. Those connections are opened when first used and are
331 closed when the QCoreApplication destructor is run.
332
333 D-Bus also supports peer-to-peer connections, without the need for
334 a bus server daemon. Using this facility, two applications can
335 talk to each other and exchange messages. This can be achieved by
336 passing an address to connectToBus() function, which was opened by
337 another D-Bus application using QDBusServer.
338*/
339
340/*!
341 \enum QDBusConnection::BusType
342 Specifies the type of the bus connection. The valid bus types are:
343
344 \value SessionBus the session bus, associated with the running desktop session
345 \value SystemBus the system bus, used to communicate with system-wide processes
346 \value ActivationBus the activation bus, the "alias" for the bus that started the
347 service
348
349 On the Session Bus, one can find other applications by the same user that are sharing the same
350 desktop session (hence the name). On the System Bus, however, processes shared for the whole
351 system are usually found.
352*/
353
354/*!
355 \enum QDBusConnection::RegisterOption
356 Specifies the options for registering objects with the connection. The possible values are:
357
358 \value ExportAdaptors export the contents of adaptors found in this object
359
360 \value ExportScriptableSlots export this object's scriptable slots
361 \value ExportScriptableSignals export this object's scriptable signals
362 \value ExportScriptableProperties export this object's scriptable properties
363 \value ExportScriptableInvokables export this object's scriptable invokables
364 \value ExportScriptableContents shorthand form for ExportScriptableSlots |
365 ExportScriptableSignals |
366 ExportScriptableProperties
367
368 \value ExportNonScriptableSlots export this object's non-scriptable slots
369 \value ExportNonScriptableSignals export this object's non-scriptable signals
370 \value ExportNonScriptableProperties export this object's non-scriptable properties
371 \value ExportNonScriptableInvokables export this object's non-scriptable invokables
372 \value ExportNonScriptableContents shorthand form for ExportNonScriptableSlots |
373 ExportNonScriptableSignals |
374 ExportNonScriptableProperties
375
376 \value ExportAllSlots export all of this object's slots
377 \value ExportAllSignals export all of this object's signals
378 \value ExportAllProperties export all of this object's properties
379 \value ExportAllInvokables export all of this object's invokables
380 \value ExportAllContents export all of this object's contents
381 \value ExportChildObjects export this object's child objects
382
383 \sa registerObject(), QDBusAbstractAdaptor, {usingadaptors.html}{Using adaptors}
384*/
385
386/*!
387 \internal
388 \since 4.8
389 \enum QDBusConnection::VirtualObjectRegisterOption
390 Specifies the options for registering virtual objects with the connection. The possible values are:
391
392 \value SingleNode register a virtual object to handle one path only
393 \value SubPath register a virtual object so that it handles all sub paths
394
395 \sa registerVirtualObject(), QDBusVirtualObject
396*/
397
398/*!
399 \enum QDBusConnection::UnregisterMode
400 The mode for unregistering an object path:
401
402 \value UnregisterNode unregister this node only: do not unregister child objects
403 \value UnregisterTree unregister this node and all its sub-tree
404
405 Note, however, if this object was registered with the ExportChildObjects option, UnregisterNode
406 will unregister the child objects too.
407*/
408
409/*!
410 \since 4.8
411 \enum QDBusConnection::ConnectionCapability
412
413 This enum describes the available capabilities for a D-Bus connection.
414
415 \value UnixFileDescriptorPassing enables passing of Unix file descriptors to other processes
416 (see QDBusUnixFileDescriptor)
417
418 \sa connectionCapabilities()
419*/
420
421/*!
422 Creates a QDBusConnection object attached to the connection with name \a name.
423
424 This does not open the connection. You have to call connectToBus() to open it.
425*/
426QDBusConnection::QDBusConnection(const QString &name)
427{
428 if (name.isEmpty() || _q_manager.isDestroyed()) {
429 d = 0;
430 } else {
431 QMutexLocker locker(&_q_manager()->mutex);
432 d = _q_manager()->connection(name);
433 if (d)
434 d->ref.ref();
435 }
436}
437
438/*!
439 Creates a copy of the \a other connection.
440*/
441QDBusConnection::QDBusConnection(const QDBusConnection &other)
442{
443 d = other.d;
444 if (d)
445 d->ref.ref();
446}
447
448/*!
449 \internal
450 Creates a connection object with the given \a dd as private object.
451*/
452QDBusConnection::QDBusConnection(QDBusConnectionPrivate *dd)
453{
454 d = dd;
455 if (d)
456 d->ref.ref();
457}
458
459/*!
460 Disposes of this object. This does not close the connection: you
461 have to call disconnectFromBus() to do that.
462*/
463QDBusConnection::~QDBusConnection()
464{
465 if (d && !d->ref.deref())
466 d->deleteLater();
467}
468
469/*!
470 Creates a copy of the connection \a other in this object. Note
471 that the connection this object referenced before the copy, is not
472 spontaneously disconnected.
473
474 \sa disconnectFromBus()
475*/
476QDBusConnection &QDBusConnection::operator=(const QDBusConnection &other)
477{
478 if (other.d)
479 other.d->ref.ref();
480 if (d && !d->ref.deref())
481 d->deleteLater();
482 d = other.d;
483 return *this;
484}
485
486/*!
487 Opens a connection of type \a type to one of the known busses and
488 associate with it the connection name \a name. Returns a
489 QDBusConnection object associated with that connection.
490*/
491QDBusConnection QDBusConnection::connectToBus(BusType type, const QString &name)
492{
493 if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
494 QDBusConnectionPrivate *d = 0;
495 return QDBusConnection(d);
496 }
497 return QDBusConnection(_q_manager()->connectToBus(type, name, false));
498}
499
500/*!
501 Opens a connection to a private bus on address \a address and associate with it the
502 connection name \a name. Returns a QDBusConnection object associated with that connection.
503*/
504QDBusConnection QDBusConnection::connectToBus(const QString &address,
505 const QString &name)
506{
507 if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
508 QDBusConnectionPrivate *d = 0;
509 return QDBusConnection(d);
510 }
511 return QDBusConnection(_q_manager()->connectToBus(address, name));
512}
513/*!
514 \since 4.8
515
516 Opens a peer-to-peer connection on address \a address and associate with it the
517 connection name \a name. Returns a QDBusConnection object associated with that connection.
518*/
519QDBusConnection QDBusConnection::connectToPeer(const QString &address,
520 const QString &name)
521{
522 if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
523 QDBusConnectionPrivate *d = 0;
524 return QDBusConnection(d);
525 }
526 return QDBusConnection(_q_manager()->connectToPeer(address, name));
527}
528
529/*!
530 Closes the bus connection of name \a name.
531
532 Note that if there are still QDBusConnection objects associated
533 with the same connection, the connection will not be closed until
534 all references are dropped. However, no further references can be
535 created using the QDBusConnection constructor.
536*/
537void QDBusConnection::disconnectFromBus(const QString &name)
538{
539 if (_q_manager()) {
540 QMutexLocker locker(&_q_manager()->mutex);
541 QDBusConnectionPrivate *d = _q_manager()->connection(name);
542 if (d && d->mode != QDBusConnectionPrivate::ClientMode)
543 return;
544 _q_manager()->removeConnection(name);
545 }
546}
547
548/*!
549 \since 4.8
550
551 Closes the peer connection of name \a name.
552
553 Note that if there are still QDBusConnection objects associated
554 with the same connection, the connection will not be closed until
555 all references are dropped. However, no further references can be
556 created using the QDBusConnection constructor.
557*/
558void QDBusConnection::disconnectFromPeer(const QString &name)
559{
560 if (_q_manager()) {
561 QMutexLocker locker(&_q_manager()->mutex);
562 QDBusConnectionPrivate *d = _q_manager()->connection(name);
563 if (d && d->mode != QDBusConnectionPrivate::PeerMode)
564 return;
565 _q_manager()->removeConnection(name);
566 }
567}
568
569/*!
570 Sends the \a message over this connection, without waiting for a
571 reply. This is suitable for errors, signals, and return values as
572 well as calls whose return values are not necessary.
573
574 Returns \c true if the message was queued successfully, false otherwise.
575*/
576bool QDBusConnection::send(const QDBusMessage &message) const
577{
578 if (!d || !d->connection) {
579 QDBusError err = QDBusError(QDBusError::Disconnected,
580 QDBusUtil::disconnectedErrorMessage());
581 if (d)
582 d->lastError = err;
583 return false;
584 }
585 return d->send(message);
586}
587
588/*!
589 Sends the \a message over this connection and returns immediately.
590 When the reply is received, the method \a returnMethod is called in
591 the \a receiver object. If an error occurs, the method \a errorMethod
592 will be called instead.
593
594 If no reply is received within \a timeout milliseconds, an automatic
595 error will be delivered indicating the expiration of the call.
596 The default \a timeout is -1, which will be replaced with an
597 implementation-defined value that is suitable for inter-process
598 communications (generally, 25 seconds).
599
600 This function is suitable for method calls only. It is guaranteed
601 that the slot will be called exactly once with the reply, as long
602 as the parameter types match and no error occurs.
603
604 Returns \c true if the message was sent, or false if the message could
605 not be sent.
606*/
607bool QDBusConnection::callWithCallback(const QDBusMessage &message, QObject *receiver,
608 const char *returnMethod, const char *errorMethod,
609 int timeout) const
610{
611 if (!d || !d->connection) {
612 QDBusError err = QDBusError(QDBusError::Disconnected,
613 QDBusUtil::disconnectedErrorMessage());
614 if (d)
615 d->lastError = err;
616 return false;
617 }
618 return d->sendWithReplyAsync(message, receiver, returnMethod, errorMethod, timeout) != 0;
619}
620
621/*!
622 \overload
623 \deprecated
624 Sends the \a message over this connection and returns immediately.
625 When the reply is received, the method \a returnMethod is called in
626 the \a receiver object.
627
628 This function is suitable for method calls only. It is guaranteed
629 that the slot will be called exactly once with the reply, as long
630 as the parameter types match and no error occurs.
631
632 This function is dangerous because it cannot report errors, including
633 the expiration of the timeout.
634
635 Returns \c true if the message was sent, or false if the message could
636 not be sent.
637*/
638bool QDBusConnection::callWithCallback(const QDBusMessage &message, QObject *receiver,
639 const char *returnMethod, int timeout) const
640{
641 return callWithCallback(message, receiver, returnMethod, 0, timeout);
642}
643
644/*!
645 Sends the \a message over this connection and blocks, waiting for
646 a reply, for at most \a timeout milliseconds. This function is
647 suitable for method calls only. It returns the reply message as
648 its return value, which will be either of type
649 QDBusMessage::ReplyMessage or QDBusMessage::ErrorMessage.
650
651 If no reply is received within \a timeout milliseconds, an automatic
652 error will be delivered indicating the expiration of the call.
653 The default \a timeout is -1, which will be replaced with an
654 implementation-defined value that is suitable for inter-process
655 communications (generally, 25 seconds).
656
657 See the QDBusInterface::call() function for a more friendly way
658 of placing calls.
659
660 \warning If \a mode is QDBus::BlockWithGui, this function will
661 reenter the Qt event loop in order to wait for the
662 reply. During the wait, it may deliver signals and other
663 method calls to your application. Therefore, it must be
664 prepared to handle a reentrancy whenever a call is
665 placed with call().
666*/
667QDBusMessage QDBusConnection::call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const
668{
669 if (!d || !d->connection) {
670 QDBusError err = QDBusError(QDBusError::Disconnected,
671 QDBusUtil::disconnectedErrorMessage());
672 if (d)
673 d->lastError = err;
674
675 return QDBusMessage::createError(err);
676 }
677
678 if (mode != QDBus::NoBlock)
679 return d->sendWithReply(message, mode, timeout);
680
681 d->send(message);
682 QDBusMessage retval;
683 retval << QVariant(); // add one argument (to avoid .at(0) problems)
684 return retval;
685}
686
687/*!
688 \since 4.5
689 Sends the \a message over this connection and returns
690 immediately. This function is suitable for method calls only. It
691 returns an object of type QDBusPendingCall which can be used to
692 track the status of the reply.
693
694 If no reply is received within \a timeout milliseconds, an automatic
695 error will be delivered indicating the expiration of the call. The
696 default \a timeout is -1, which will be replaced with an
697 implementation-defined value that is suitable for inter-process
698 communications (generally, 25 seconds). This timeout is also the
699 upper limit for waiting in QDBusPendingCall::waitForFinished().
700
701 See the QDBusInterface::asyncCall() function for a more friendly way
702 of placing calls.
703*/
704QDBusPendingCall QDBusConnection::asyncCall(const QDBusMessage &message, int timeout) const
705{
706 if (!d || !d->connection) {
707 return QDBusPendingCall(0); // null pointer -> disconnected
708 }
709
710 QDBusPendingCallPrivate *priv = d->sendWithReplyAsync(message, 0, 0, 0, timeout);
711 return QDBusPendingCall(priv);
712}
713
714/*!
715 Connects the signal specified by the \a service, \a path, \a interface and \a name parameters to
716 the slot \a slot in object \a receiver. The arguments \a service and \a path can be empty,
717 denoting a connection to any signal of the (\a interface, \a name) pair, from any remote
718 application.
719
720 Returns \c true if the connection was successful.
721
722 \warning The signal will only be delivered to the slot if the parameters match. This verification
723 can be done only when the signal is received, not at connection time.
724*/
725bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
726 const QString &name, QObject *receiver, const char *slot)
727{
728 return connect(service, path, interface, name, QStringList(), QString(), receiver, slot);
729}
730
731/*!
732 \overload
733
734 Connects the signal to the slot \a slot in object \a
735 receiver. Unlike the previous connect() overload, this function
736 allows one to specify the parameter signature to be connected
737 using the \a signature variable. The function will then verify
738 that this signature can be delivered to the slot specified by \a
739 slot and return false otherwise.
740
741 Returns \c true if the connection was successful.
742
743 \note This function verifies that the signal signature matches the
744 slot's parameters, but it does not verify that the actual
745 signal exists with the given signature in the remote
746 service.
747*/
748bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
749 const QString &name, const QString &signature,
750 QObject *receiver, const char *slot)
751{
752 return connect(service, path, interface, name, QStringList(), signature, receiver, slot);
753}
754
755/*!
756 \overload
757 \since 4.6
758
759 Connects the signal to the slot \a slot in object \a
760 receiver. Unlike the previous connect() overload, this function
761 allows one to specify the parameter signature to be connected
762 using the \a signature variable. The function will then verify
763 that this signature can be delivered to the slot specified by \a
764 slot and return false otherwise.
765
766 The \a argumentMatch parameter lists the string parameters to be matched,
767 in sequential order. Note that, to match an empty string, you need to
768 pass a QString that is empty but not null (i.e., QString("")). A null
769 QString skips matching at that position.
770
771 Returns \c true if the connection was successful.
772
773 \note This function verifies that the signal signature matches the
774 slot's parameters, but it does not verify that the actual
775 signal exists with the given signature in the remote
776 service.
777*/
778bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
779 const QString &name, const QStringList &argumentMatch, const QString &signature,
780 QObject *receiver, const char *slot)
781{
782
783 if (!receiver || !slot || !d || !d->connection)
784 return false;
785 if (interface.isEmpty() && name.isEmpty())
786 return false;
787 if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) {
788#ifndef QT_NO_DEBUG
789 qWarning("QDBusConnection::connect: interface name '%s' is not valid", interface.toLatin1().constData());
790#endif
791 return false;
792 }
793 if (!service.isEmpty() && !QDBusUtil::isValidBusName(service)) {
794#ifndef QT_NO_DEBUG
795 qWarning("QDBusConnection::connect: service name '%s' is not valid", service.toLatin1().constData());
796#endif
797 return false;
798 }
799 if (!path.isEmpty() && !QDBusUtil::isValidObjectPath(path)) {
800#ifndef QT_NO_DEBUG
801 qWarning("QDBusConnection::connect: object path '%s' is not valid", path.toLatin1().constData());
802#endif
803 return false;
804 }
805
806 return d->connectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
807}
808
809/*!
810 Disconnects the signal specified by the \a service, \a path, \a interface
811 and \a name parameters from the slot \a slot in object \a receiver. The
812 arguments must be the same as passed to the connect() function.
813
814 Returns \c true if the disconnection was successful.
815*/
816bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString &interface,
817 const QString &name, QObject *receiver, const char *slot)
818{
819 return disconnect(service, path, interface, name, QStringList(), QString(), receiver, slot);
820}
821
822/*!
823 \overload
824
825 Disconnects the signal specified by the \a service, \a path, \a
826 interface, \a name, and \a signature parameters from the slot \a slot in
827 object \a receiver. The arguments must be the same as passed to the
828 connect() function.
829
830 Returns \c true if the disconnection was successful.
831*/
832bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString& interface,
833 const QString &name, const QString &signature,
834 QObject *receiver, const char *slot)
835{
836 return disconnect(service, path, interface, name, QStringList(), signature, receiver, slot);
837}
838
839/*!
840 \overload
841 \since 4.6
842
843 Disconnects the signal specified by the \a service, \a path, \a
844 interface, \a name, \a argumentMatch, and \a signature parameters from
845 the slot \a slot in object \a receiver. The arguments must be the same as
846 passed to the connect() function.
847
848 Returns \c true if the disconnection was successful.
849*/
850bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString& interface,
851 const QString &name, const QStringList &argumentMatch, const QString &signature,
852 QObject *receiver, const char *slot)
853{
854 if (!receiver || !slot || !d || !d->connection)
855 return false;
856 if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface))
857 return false;
858 if (interface.isEmpty() && name.isEmpty())
859 return false;
860
861 return d->disconnectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
862}
863
864/*!
865 Registers the object \a object at path \a path and returns \c true if
866 the registration was successful. The \a options parameter
867 specifies how much of the object \a object will be exposed through
868 D-Bus.
869
870 This function does not replace existing objects: if there is already an object registered at
871 path \a path, this function will return false. Use unregisterObject() to unregister it first.
872
873 You cannot register an object as a child object of an object that
874 was registered with QDBusConnection::ExportChildObjects.
875*/
876bool QDBusConnection::registerObject(const QString &path, QObject *object, RegisterOptions options)
877{
878 return registerObject(path, QString(), object, options);
879}
880
881/*!
882 \overload
883 \since 5.5
884
885 Registers the object \a object at path \a path with interface name \a interface
886 and returns \c true if the registration was successful. The \a options parameter
887 specifies how much of the object \a object will be exposed through
888 D-Bus.
889
890 This function does not replace existing objects: if there is already an object registered at
891 path \a path, this function will return false. Use unregisterObject() to unregister it first.
892
893 You cannot register an object as a child object of an object that
894 was registered with QDBusConnection::ExportChildObjects.
895*/
896bool QDBusConnection::registerObject(const QString &path, const QString &interface, QObject *object, RegisterOptions options)
897{
898 Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusConnection::registerObject",
899 "Invalid object path given");
900 if (!d || !d->connection || !object || !options || !QDBusUtil::isValidObjectPath(path))
901 return false;
902
903 auto pathComponents = path.splitRef(QLatin1Char('/'));
904 if (pathComponents.constLast().isEmpty())
905 pathComponents.removeLast();
906 QDBusWriteLocker locker(RegisterObjectAction, d);
907
908 // lower-bound search for where this object should enter in the tree
909 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator node = &d->rootNode;
910 int i = 1;
911 while (node) {
912 if (pathComponents.count() == i) {
913 // this node exists
914 // consider it free if there's no object here and the user is not trying to
915 // replace the object sub-tree
916 if (node->obj)
917 return false;
918
919 if (options & QDBusConnectionPrivate::VirtualObject) {
920 if (options & SubPath && !node->children.isEmpty())
921 return false;
922 } else {
923 if ((options & ExportChildObjects && !node->children.isEmpty()))
924 return false;
925 }
926 // we can add the object here
927 node->obj = object;
928 node->flags = options;
929 node->interfaceName = interface;
930
931 d->registerObject(node);
932 //qDebug("REGISTERED FOR %s", path.toLocal8Bit().constData());
933 return true;
934 }
935
936 // if a virtual object occupies this path, return false
937 if (node->obj && (node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath)) {
938 //qDebug("Cannot register object at %s because QDBusVirtualObject handles all sub-paths.",
939 // qPrintable(path));
940 return false;
941 }
942
943 // find the position where we'd insert the node
944 QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it =
945 std::lower_bound(node->children.begin(), node->children.end(), pathComponents.at(i));
946 if (it != node->children.end() && it->name == pathComponents.at(i)) {
947 // match: this node exists
948 node = it;
949
950 // are we allowed to go deeper?
951 if (node->flags & ExportChildObjects) {
952 // we're not
953 //qDebug("Cannot register object at %s because %s exports its own child objects",
954 // qPrintable(path), qPrintable(pathComponents.at(i)));
955 return false;
956 }
957 } else {
958 // add entry
959 node = node->children.insert(it, pathComponents.at(i).toString());
960 }
961
962 // iterate
963 ++i;
964 }
965
966 Q_ASSERT_X(false, "QDBusConnection::registerObject", "The impossible happened");
967 return false;
968}
969
970/*!
971 \internal
972 \since 4.8
973 Registers a QDBusTreeNode for a path. It can handle a path including all child paths, thus
974 handling multiple DBus nodes.
975
976 To unregister a QDBusTreeNode use the unregisterObject() function with its path.
977*/
978bool QDBusConnection::registerVirtualObject(const QString &path, QDBusVirtualObject *treeNode,
979 VirtualObjectRegisterOption options)
980{
981 int opts = options | QDBusConnectionPrivate::VirtualObject;
982 return registerObject(path, (QObject*) treeNode, (RegisterOptions) opts);
983}
984
985/*!
986 Unregisters an object that was registered with the registerObject() at the object path given by
987 \a path and, if \a mode is QDBusConnection::UnregisterTree, all of its sub-objects too.
988
989 Note that you cannot unregister objects that were not registered with registerObject().
990*/
991void QDBusConnection::unregisterObject(const QString &path, UnregisterMode mode)
992{
993 if (!d || !d->connection || !QDBusUtil::isValidObjectPath(path))
994 return;
995
996 QDBusWriteLocker locker(UnregisterObjectAction, d);
997 d->unregisterObject(path, mode);
998}
999
1000/*!
1001 Return the object that was registered with the registerObject() at the object path given by
1002 \a path.
1003*/
1004QObject *QDBusConnection::objectRegisteredAt(const QString &path) const
1005{
1006 Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusConnection::registeredObject",
1007 "Invalid object path given");
1008 if (!d || !d->connection || !QDBusUtil::isValidObjectPath(path))
1009 return 0;
1010
1011 auto pathComponents = path.splitRef(QLatin1Char('/'));
1012 if (pathComponents.constLast().isEmpty())
1013 pathComponents.removeLast();
1014
1015 // lower-bound search for where this object should enter in the tree
1016 QDBusReadLocker lock(ObjectRegisteredAtAction, d);
1017 const QDBusConnectionPrivate::ObjectTreeNode *node = &d->rootNode;
1018
1019 int i = 1;
1020 while (node) {
1021 if (pathComponents.count() == i)
1022 return node->obj;
1023 if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath))
1024 return node->obj;
1025
1026 QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it =
1027 std::lower_bound(node->children.constBegin(), node->children.constEnd(), pathComponents.at(i));
1028 if (it == node->children.constEnd() || it->name != pathComponents.at(i))
1029 break; // node not found
1030
1031 node = it;
1032 ++i;
1033 }
1034 return 0;
1035}
1036
1037
1038
1039/*!
1040 Returns a QDBusConnectionInterface object that represents the
1041 D-Bus server interface on this connection.
1042*/
1043QDBusConnectionInterface *QDBusConnection::interface() const
1044{
1045 if (!d || d->mode != QDBusConnectionPrivate::ClientMode)
1046 return 0;
1047 return d->busService;
1048}
1049
1050/*!
1051 \internal
1052 \since 4.8
1053
1054 Returns the internal, implementation-defined pointer for this
1055 connection. Currently, this returns a DBusConnection* pointer,
1056 without changing the reference count. It is the responsibility of
1057 the caller to call dbus_connection_ref if it wants to store the
1058 pointer.
1059*/
1060void *QDBusConnection::internalPointer() const
1061{
1062 return d ? d->connection : 0;
1063}
1064
1065/*!
1066 Returns \c true if this QDBusConnection object is connected.
1067*/
1068bool QDBusConnection::isConnected() const
1069{
1070 return d && d->connection && q_dbus_connection_get_is_connected(d->connection);
1071}
1072
1073/*!
1074 Returns the last error that happened in this connection.
1075
1076 This function is provided for low-level code. If you're using
1077 QDBusInterface::call(), error codes are reported by its return
1078 value.
1079
1080 \sa QDBusInterface, QDBusMessage
1081*/
1082QDBusError QDBusConnection::lastError() const
1083{
1084 return d ? d->lastError : QDBusError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
1085}
1086
1087/*!
1088 Returns the unique connection name for this connection, if this QDBusConnection object is
1089 connected, or an empty QString otherwise.
1090
1091 A Unique Connection Name is a string in the form ":x.xxx" (where x
1092 are decimal digits) that is assigned by the D-Bus server daemon
1093 upon connection. It uniquely identifies this client in the bus.
1094
1095 This function returns an empty QString for peer-to-peer connections.
1096*/
1097QString QDBusConnection::baseService() const
1098{
1099 return d ? d->baseService : QString();
1100}
1101
1102/*!
1103 \since 4.5
1104
1105 Returns the connection name for this connection, as given as the
1106 name parameter to connectToBus().
1107
1108 The connection name can be used to uniquely identify actual
1109 underlying connections to buses. Copies made from a single
1110 connection will always implicitly share the underlying connection,
1111 and hence will have the same connection name.
1112
1113 Inversely, two connections having different connection names will
1114 always either be connected to different buses, or have a different
1115 unique name (as returned by baseService()) on that bus.
1116
1117 \sa connectToBus(), disconnectFromBus()
1118*/
1119QString QDBusConnection::name() const
1120{
1121 return d ? d->name : QString();
1122}
1123
1124/*!
1125 \since 4.8
1126
1127 Returns the capabilities of this connection as negotiated with the bus
1128 server or peer. If this QDBusConnection is not connected, this function
1129 returns no capabilities.
1130*/
1131QDBusConnection::ConnectionCapabilities QDBusConnection::connectionCapabilities() const
1132{
1133 return d ? d->capabilities : ConnectionCapabilities(0);
1134}
1135
1136/*!
1137 Attempts to register the \a serviceName on the D-Bus server and
1138 returns \c true if the registration succeeded. The registration will
1139 fail if the name is already registered by another application.
1140
1141 \sa unregisterService(), QDBusConnectionInterface::registerService()
1142*/
1143bool QDBusConnection::registerService(const QString &serviceName)
1144{
1145 if (interface() && interface()->registerService(serviceName)) {
1146 if (d) d->registerService(serviceName);
1147 return true;
1148 }
1149 return false;
1150}
1151
1152/*!
1153 Unregisters the service \a serviceName that was previously
1154 registered with registerService() and returns \c true if it
1155 succeeded.
1156
1157 \sa registerService(), QDBusConnectionInterface::unregisterService()
1158*/
1159bool QDBusConnection::unregisterService(const QString &serviceName)
1160{
1161 if (interface()->unregisterService(serviceName)) {
1162 if (d) d->unregisterService(serviceName);
1163 return true;
1164 }
1165 return false;
1166}
1167
1168/*!
1169 \fn QDBusConnection QDBusConnection::sessionBus()
1170
1171 Returns a QDBusConnection object opened with the session bus. The object
1172 reference returned by this function is valid until the application terminates,
1173 at which point the connection will be closed and the object deleted.
1174*/
1175QDBusConnection QDBusConnection::sessionBus()
1176{
1177 if (_q_manager.isDestroyed())
1178 return QDBusConnection(nullptr);
1179 return QDBusConnection(_q_manager()->busConnection(SessionBus));
1180}
1181
1182/*!
1183 \fn QDBusConnection QDBusConnection::systemBus()
1184
1185 Returns a QDBusConnection object opened with the system bus. The object reference returned
1186 by this function is valid until the QCoreApplication's destructor is run, when the
1187 connection will be closed and the object, deleted.
1188*/
1189QDBusConnection QDBusConnection::systemBus()
1190{
1191 if (_q_manager.isDestroyed())
1192 return QDBusConnection(nullptr);
1193 return QDBusConnection(_q_manager()->busConnection(SystemBus));
1194}
1195
1196#if QT_DEPRECATED_SINCE(5,5)
1197/*!
1198 \deprecated
1199
1200 Always returns a disconnected, invalid QDBusConnection object. For the old
1201 functionality of determining the sender connection, please use QDBusContext.
1202
1203 \sa QDBusContext
1204*/
1205QDBusConnection QDBusConnection::sender()
1206{
1207 return QDBusConnection(QString());
1208}
1209#endif
1210
1211/*!
1212 \internal
1213*/
1214void QDBusConnectionPrivate::createBusService()
1215{
1216 Q_ASSERT(mode == ClientMode);
1217 QDBusConnection connection(this);
1218 busService = new QDBusConnectionInterface(connection, this);
1219 ref.deref(); // busService has increased the refcounting to us
1220 // avoid cyclic refcounting
1221
1222 QObject::connect(this, &QDBusConnectionPrivate::callWithCallbackFailed,
1223 busService, emit &QDBusConnectionInterface::callWithCallbackFailed,
1224 Qt::QueuedConnection);
1225}
1226
1227/*!
1228 \since 4.8
1229 Returns the local machine ID as known to the D-Bus system. Each
1230 node or host that runs D-Bus has a unique identifier that can be
1231 used to distinguish it from other hosts if they are sharing
1232 resources like the filesystem.
1233
1234 Note that the local machine ID is not guaranteed to be persistent
1235 across boots of the system, so this identifier should not be
1236 stored in persistent storage (like the filesystem). It is
1237 guaranteed to remain constant only during the lifetime of this
1238 boot session.
1239*/
1240QByteArray QDBusConnection::localMachineId()
1241{
1242 char *dbus_machine_id = q_dbus_get_local_machine_id();
1243 QByteArray result = dbus_machine_id;
1244 q_dbus_free(dbus_machine_id);
1245 return result;
1246}
1247
1248/*!
1249 \namespace QDBus
1250 \inmodule QtDBus
1251
1252 \brief The QDBus namespace contains miscellaneous identifiers used
1253 throughout the Qt D-Bus module.
1254*/
1255
1256/*!
1257 \enum QDBus::CallMode
1258
1259 This enum describes the various ways of placing a function call. The valid modes are:
1260
1261 \value NoBlock Place the call but don't wait for the reply (the reply's contents
1262 will be discarded).
1263 \value Block Don't use an event loop to wait for a reply, but instead block on
1264 network operations while waiting. This means the
1265 user-interface may not be updated until the function returns.
1266 \value BlockWithGui Use the Qt event loop to wait for a reply. This means that the
1267 user-interface will stay responsive (processing input events),
1268 but it also means other events may happen, like signal delivery
1269 and other D-Bus method calls.
1270 \value AutoDetect Automatically detect if the called function has a reply.
1271
1272 When using BlockWithGui, applications must be prepared for reentrancy in any function.
1273*/
1274
1275/*!
1276 \fn void QDBusConnection::swap(QDBusConnection &other)
1277
1278 Swaps this QDBusConnection instance with \a other.
1279*/
1280
1281QT_END_NAMESPACE
1282
1283#ifdef Q_OS_WIN
1284# include <qt_windows.h>
1285
1286QT_BEGIN_NAMESPACE
1287static void preventDllUnload()
1288{
1289 // Thread termination is really wacky on Windows. For some reason we don't
1290 // understand, exiting from the thread may try to unload the DLL. Since the
1291 // QDBusConnectionManager thread runs until the DLL is unloaded, we've got
1292 // a deadlock: the main thread is waiting for the manager thread to exit,
1293 // but the manager thread is attempting to acquire a lock to unload the DLL.
1294 //
1295 // We work around the issue by preventing the unload from happening in the
1296 // first place.
1297 //
1298 // For this trick, see
1299 // https://blogs.msdn.microsoft.com/oldnewthing/20131105-00/?p=2733
1300
1301 static HMODULE self;
1302 GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
1303 GET_MODULE_HANDLE_EX_FLAG_PIN,
1304 reinterpret_cast<const wchar_t *>(&self), // any address in this DLL
1305 &self);
1306}
1307QT_END_NAMESPACE
1308#endif
1309
1310#endif // QT_NO_DBUS
1311