Hello community, here is the log from the commit of package kdbusaddons for openSUSE:Factory checked in at 2019-09-23 12:22:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kdbusaddons (Old) and /work/SRC/openSUSE:Factory/.kdbusaddons.new.7948 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kdbusaddons" Mon Sep 23 12:22:14 2019 rev:70 rq:730917 version:5.62.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kdbusaddons/kdbusaddons.changes 2019-08-19 21:04:25.848901099 +0200 +++ /work/SRC/openSUSE:Factory/.kdbusaddons.new.7948/kdbusaddons.changes 2019-09-23 12:22:16.749758971 +0200 @@ -1,0 +2,13 @@ +Sat Sep 7 20:36:37 UTC 2019 - Christophe Giboudeaux <christo...@krop.fr> + +- Update to 5.62.0 + * New feature release + * For more details please see: + * https://www.kde.org/announcements/kde-frameworks-5.62.0.php +- Changes since 5.61.0: + * Remove unused includes + * make deadservicetest unix exclusive + * remove useless moc include + * fix race on kcrash auto-restarts + +------------------------------------------------------------------- Old: ---- kdbusaddons-5.61.0.tar.xz kdbusaddons-5.61.0.tar.xz.sig New: ---- kdbusaddons-5.62.0.tar.xz kdbusaddons-5.62.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kdbusaddons.spec ++++++ --- /var/tmp/diff_new_pack.FEbpBV/_old 2019-09-23 12:22:17.641758825 +0200 +++ /var/tmp/diff_new_pack.FEbpBV/_new 2019-09-23 12:22:17.641758825 +0200 @@ -17,14 +17,14 @@ %define lname libKF5DBusAddons5 -%define _tar_path 5.61 +%define _tar_path 5.62 # Full KF5 version (e.g. 5.33.0) %{!?_kf5_version: %global _kf5_version %{version}} # Last major and minor KF5 version (e.g. 5.33) %{!?_kf5_bugfix_version: %define _kf5_bugfix_version %(echo %{_kf5_version} | awk -F. '{print $1"."$2}')} %bcond_without lang Name: kdbusaddons -Version: 5.61.0 +Version: 5.62.0 Release: 0 Summary: Convenience classes for QtDBus License: LGPL-2.1-or-later ++++++ kdbusaddons-5.61.0.tar.xz -> kdbusaddons-5.62.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/CMakeLists.txt new/kdbusaddons-5.62.0/CMakeLists.txt --- old/kdbusaddons-5.61.0/CMakeLists.txt 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/CMakeLists.txt 2019-09-07 15:57:05.000000000 +0200 @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.5) -set(KF5_VERSION "5.61.0") # handled by release scripts +set(KF5_VERSION "5.62.0") # handled by release scripts project(KDBusAddons VERSION ${KF5_VERSION}) include(FeatureSummary) -find_package(ECM 5.61.0 NO_MODULE) +find_package(ECM 5.62.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/autotests/CMakeLists.txt new/kdbusaddons-5.62.0/autotests/CMakeLists.txt --- old/kdbusaddons-5.61.0/autotests/CMakeLists.txt 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/autotests/CMakeLists.txt 2019-09-07 15:57:05.000000000 +0200 @@ -5,6 +5,18 @@ include(ECMAddTests) +if(UNIX) + add_executable(kdbussimpleservice kdbussimpleservice.cpp) + target_link_libraries(kdbussimpleservice Qt5::Core KF5::DBusAddons) + + ecm_add_tests( + deadservicetest.cpp + LINK_LIBRARIES Qt5::Test KF5::DBusAddons + ) + + add_dependencies(deadservicetest kdbussimpleservice) +endif() + ecm_add_tests( kdbusinterprocesslocktest.cpp kdbusservicetest.cpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/autotests/deadservicetest.cpp new/kdbusaddons-5.62.0/autotests/deadservicetest.cpp --- old/kdbusaddons-5.61.0/autotests/deadservicetest.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/kdbusaddons-5.62.0/autotests/deadservicetest.cpp 2019-09-07 15:57:05.000000000 +0200 @@ -0,0 +1,114 @@ +/* This file is part of libkdbus + + Copyright (c) 2019 Harald Sitter <sit...@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <QDBusConnection> +#include <QDBusConnectionInterface> +#include <QDBusServiceWatcher> +#include <QDebug> +#include <QProcess> +#include <QTest> + +#include <signal.h> +#include <unistd.h> + +static const QString s_serviceName = QStringLiteral("org.kde.kdbussimpleservice"); + +class TestObject : public QObject +{ + Q_OBJECT + + QList<int> m_danglingPids; +private Q_SLOTS: + void cleanupTestCase() + { + // Make sure we don't leave dangling processes even when we had an + // error and the process is stopped. + for (int pid : m_danglingPids) { + kill(pid, SIGKILL); + } + } + + void testDeadService() + { + QVERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(s_serviceName).value()); + + QProcess proc1; + proc1.setProgram(QFINDTESTDATA("kdbussimpleservice")); + proc1.setProcessChannelMode(QProcess::ForwardedChannels); + proc1.start(); + QVERIFY(proc1.waitForStarted()); + m_danglingPids << proc1.pid(); + + // Spy isn't very suitable here because we'd be racing with proc1 or + // signal blocking since we'd need to unblock before spying but then + // there is an ɛ between unblock and spy. + Q_PID pid1 = proc1.pid(); // store local, in case the proc disappears + QVERIFY(pid1 >= 0); + bool proc1Registered = QTest::qWaitFor([&]() { + QTest::qSleep(1000); + return QDBusConnection::sessionBus().interface()->servicePid(s_serviceName).value() == pid1; + }, 8000); + QVERIFY(proc1Registered); + + // suspend proc1, we don't want it responding on dbus anymore, but still + // be running so it holds the name. + QCOMPARE(kill(proc1.pid(), SIGSTOP), 0); + + // start second instance + QProcess proc2; + proc2.setProgram(QFINDTESTDATA("kdbussimpleservice")); + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("KCRASH_AUTO_RESTARTED", "1"); + proc2.setProcessEnvironment(env); + proc2.setProcessChannelMode(QProcess::ForwardedChannels); + proc2.start(); + QVERIFY(proc2.waitForStarted()); + m_danglingPids << proc2.pid(); + + // sleep a bit. fairly awkward. we need proc2 to be waiting on the name + // but we can't easily determine when it started waiting. in lieu of + // better instrumentation let's just sleep a bit. + qDebug() << "sleeping"; + QTest::qSleep(4000); + + // Let proc1 go up in flames so that dbus-daemon reclaims the name and + // gives it to proc2. + qDebug() << "murder on the orient express"; + QCOMPARE(0, kill(proc1.pid(), SIGUSR1)); + QCOMPARE(0, kill(proc1.pid(), SIGCONT)); + + Q_PID pid2 = proc2.pid(); // store local, in case the proc disappears + QVERIFY(pid2 >= 0); + // Wait for service to be owned by proc2. + bool proc2Registered = QTest::qWaitFor([&]() { + QTest::qSleep(1000); + return QDBusConnection::sessionBus().interface()->servicePid(s_serviceName).value() == pid2; + }, 8000); + QVERIFY(proc2Registered); + + proc1.kill(); + m_danglingPids.removeAll(pid1); + proc2.kill(); + m_danglingPids.removeAll(pid2); + } +}; + +QTEST_MAIN(TestObject) + +#include "deadservicetest.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/autotests/kdbusinterprocesslocktest.cpp new/kdbusaddons-5.62.0/autotests/kdbusinterprocesslocktest.cpp --- old/kdbusaddons-5.61.0/autotests/kdbusinterprocesslocktest.cpp 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/autotests/kdbusinterprocesslocktest.cpp 2019-09-07 15:57:05.000000000 +0200 @@ -21,9 +21,7 @@ #include <QDebug> #include <QFile> #include <QProcess> -#include <QTimer> - -#include <QtTest> +#include <QTest> #include <kdbusinterprocesslock.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/autotests/kdbussimpleservice.cpp new/kdbusaddons-5.62.0/autotests/kdbussimpleservice.cpp --- old/kdbusaddons-5.61.0/autotests/kdbussimpleservice.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/kdbusaddons-5.62.0/autotests/kdbussimpleservice.cpp 2019-09-07 15:57:05.000000000 +0200 @@ -0,0 +1,90 @@ +/* This file is part of libkdbus + + Copyright (c) 2019 Harald Sitter <sit...@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <QCoreApplication> +#include <QDebug> +#include <QThread> +#include <kdbusservice.h> + +// sigaction +#include <signal.h> +// close +#include <unistd.h> + +// rlimit +#include <sys/time.h> +#include <sys/resource.h> + +// USR1. +// Close all sockets and eventually ABRT. This mimics behavior during KCrash +// handling. Closing all sockets will effectively disconnect us from the bus +// and result in the daemon reclaiming all our service names and allowing +// other processes to register them instead. +void usr1_handler(int signum) +{ + qDebug() << "usr1" << signum << SIGSEGV; + + // Close all remaining file descriptors so we drop off of the bus. + struct rlimit rlp; + getrlimit(RLIMIT_NOFILE, &rlp); + for (int i = 3; i < (int)rlp.rlim_cur; i++) { + close(i); + } + + // Sleep a bit for good measure. We could actually loop ad infinitum here + // as after USR1 we are expected to get killed. In the interest of sane + // behavior we'll simply exit on our own as well though. + sleep(4); + abort(); +} + +// Simple application under test. +// Closes all sockets on USR1 and aborts to simulate a kcrash shutdown behavior +// which can result in a service registration race. +int main(int argc, char *argv[]) +{ + qDebug() << "hello there!"; + + struct sigaction action; + + action.sa_handler = usr1_handler; + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGUSR1); + action.sa_flags = SA_RESTART; + + if (sigaction(SIGUSR1, &action, nullptr) < 0) { + qDebug() << "failed to register segv handler"; + return 1; + } + + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationName("kdbussimpleservice"); + QCoreApplication::setOrganizationDomain("kde.org"); + + KDBusService service(KDBusService::Unique); + if (!service.isRegistered()) { + qDebug() << "service not registered => exiting"; + return 1; + } + qDebug() << "service registered"; + + int ret = app.exec(); + qDebug() << "exiting deadservice"; + return ret; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/po/id/kdbusaddons5_qt.po new/kdbusaddons-5.62.0/po/id/kdbusaddons5_qt.po --- old/kdbusaddons-5.61.0/po/id/kdbusaddons5_qt.po 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/po/id/kdbusaddons5_qt.po 2019-09-07 15:57:05.000000000 +0200 @@ -2,12 +2,12 @@ # Copyright (C) 2010 This_file_is_part_of_KDE # This file is distributed under the same license as the kquitapp package. # Andhika Padmawan <andhika.padma...@gmail.com>, 2010. -# Wantoyo <wanto...@gmail.com>, 2017, 2018. +# Wantoyo <wanto...@gmail.com>, 2017, 2018, 2019. # msgid "" msgstr "" "Project-Id-Version: kquitapp\n" -"PO-Revision-Date: 2018-11-23 07:39+0700\n" +"PO-Revision-Date: 2019-08-27 13:56+0700\n" "Last-Translator: Wantoyo <wanto...@gmail.com>\n" "Language-Team: Indonesian <kde-i18n-...@kde.org>\n" "Language: id\n" @@ -15,7 +15,7 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Lokalize 2.0\n" +"X-Generator: Lokalize 19.04.3\n" "X-Qt-Contexts: true\n" #: tools/kquitapp/kquitapp.cpp:31 @@ -36,7 +36,7 @@ #: tools/kquitapp/kquitapp.cpp:34 msgctxt "main|" msgid "The name of the application to quit" -msgstr "Nama dari aplikasi yang dikeluarkan" +msgstr "Nama dari aplikasi yang diberhentikan" #: tools/kquitapp/kquitapp.cpp:57 #, qt-format diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/po/ml/kdbusaddons5_qt.po new/kdbusaddons-5.62.0/po/ml/kdbusaddons5_qt.po --- old/kdbusaddons-5.61.0/po/ml/kdbusaddons5_qt.po 1970-01-01 01:00:00.000000000 +0100 +++ new/kdbusaddons-5.62.0/po/ml/kdbusaddons5_qt.po 2019-09-07 15:57:05.000000000 +0200 @@ -0,0 +1,47 @@ +msgid "" +msgstr "" +"Project-Id-Version: kdbusaddons5_qt\n" +"Last-Translator: Automatically generated\n" +"Language-Team: Swathanthra|സ്വതന്ത്ര Malayalam|മലയാളം Computing|കമ്പ്യൂട്ടിങ്ങ് <smc." +"org.in>\n" +"Language: ml\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Qt-Contexts: true\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: tools/kquitapp/kquitapp.cpp:31 +msgctxt "main|" +msgid "Quit a D-Bus enabled application easily" +msgstr "" + +#: tools/kquitapp/kquitapp.cpp:32 +msgctxt "main|" +msgid "Full service name, overrides application name provided" +msgstr "" + +#: tools/kquitapp/kquitapp.cpp:33 +msgctxt "main|" +msgid "Path in the D-Bus interface to use" +msgstr "" + +#: tools/kquitapp/kquitapp.cpp:34 +msgctxt "main|" +msgid "The name of the application to quit" +msgstr "" + +#: tools/kquitapp/kquitapp.cpp:57 +#, qt-format +msgctxt "main|" +msgid "Application %1 could not be found using service %2 and path %3." +msgstr "" + +#: tools/kquitapp/kquitapp.cpp:63 +#, qt-format +msgctxt "main|" +msgid "" +"Quitting application %1 failed. Error reported was:\n" +"\n" +" %2 : %3" +msgstr "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/po/tg/kdbusaddons5_qt.po new/kdbusaddons-5.62.0/po/tg/kdbusaddons5_qt.po --- old/kdbusaddons-5.61.0/po/tg/kdbusaddons5_qt.po 1970-01-01 01:00:00.000000000 +0100 +++ new/kdbusaddons-5.62.0/po/tg/kdbusaddons5_qt.po 2019-09-07 15:57:05.000000000 +0200 @@ -0,0 +1,52 @@ +# Victor Ibragimov <victor.ibragi...@gmail.com>, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"PO-Revision-Date: 2019-08-16 19:15+0500\n" +"Last-Translator: Victor Ibragimov <victor.ibragi...@gmail.com>\n" +"Language-Team: English <kde-i18n-...@kde.org>\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Qt-Contexts: true\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.3\n" + +#: tools/kquitapp/kquitapp.cpp:31 +msgctxt "main|" +msgid "Quit a D-Bus enabled application easily" +msgstr "Ба осонӣ баромадан аз барномаи дорои D-Bus" + +#: tools/kquitapp/kquitapp.cpp:32 +msgctxt "main|" +msgid "Full service name, overrides application name provided" +msgstr "Номи хидмати пурра, номи барномаи таъминшударо рӯйҳамнависӣ мекунад" + +#: tools/kquitapp/kquitapp.cpp:33 +msgctxt "main|" +msgid "Path in the D-Bus interface to use" +msgstr "Масир дар воситаи D-Bus, ки истифода мешавад" + +#: tools/kquitapp/kquitapp.cpp:34 +msgctxt "main|" +msgid "The name of the application to quit" +msgstr "Номи барномае, ки мебарояд" + +#: tools/kquitapp/kquitapp.cpp:57 +#, qt-format +msgctxt "main|" +msgid "Application %1 could not be found using service %2 and path %3." +msgstr "Барномаи %1 бо истифодаи хидмати %2 ва масири %3 ёфт нашуд." + +#: tools/kquitapp/kquitapp.cpp:63 +#, qt-format +msgctxt "main|" +msgid "" +"Quitting application %1 failed. Error reported was:\n" +"\n" +" %2 : %3" +msgstr "" +"Баромад аз барномаи %1 қатъ шуд. Хатои гузоришшуда:\n" +"\n" +" %2 : %3" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/po/zh_CN/kdbusaddons5_qt.po new/kdbusaddons-5.62.0/po/zh_CN/kdbusaddons5_qt.po --- old/kdbusaddons-5.61.0/po/zh_CN/kdbusaddons5_qt.po 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/po/zh_CN/kdbusaddons5_qt.po 2019-09-07 15:57:05.000000000 +0200 @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: kdeorg\n" -"PO-Revision-Date: 2019-07-18 14:57\n" +"PO-Revision-Date: 2019-09-05 09:25\n" "Last-Translator: Guo Yunhe (guoyunhe)\n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/src/kdbusinterprocesslock.cpp new/kdbusaddons-5.62.0/src/kdbusinterprocesslock.cpp --- old/kdbusaddons-5.61.0/src/kdbusinterprocesslock.cpp 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/src/kdbusinterprocesslock.cpp 2019-09-07 15:57:05.000000000 +0200 @@ -25,7 +25,6 @@ #include <QEventLoop> #include <QDBusConnectionInterface> -#include <QDebug> class KDBusInterProcessLockPrivate { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/src/kdbusservice.cpp new/kdbusaddons-5.62.0/src/kdbusservice.cpp --- old/kdbusaddons-5.61.0/src/kdbusservice.cpp 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/src/kdbusservice.cpp 2019-09-07 15:57:05.000000000 +0200 @@ -2,6 +2,7 @@ Copyright (c) 2011 David Faure <fa...@kde.org> Copyright (c) 2011 Kevin Ottens <er...@kde.org> + Copyright (c) 2019 Harald Sitter <sit...@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -74,26 +75,50 @@ int exitValue; }; -KDBusService::KDBusService(StartupOptions options, QObject *parent) - : QObject(parent), d(new KDBusServicePrivate) -{ - new KDBusServiceAdaptor(this); - new KDBusServiceExtensionsAdaptor(this); - QDBusConnectionInterface *bus = nullptr; +// Wraps a serviceName registration. +class Registration : public QObject { + Q_OBJECT +public: + enum class Register { + RegisterWitoutQueue, + RegisterWithQueue + }; + + Registration(KDBusService *s_, KDBusServicePrivate *d_, KDBusService::StartupOptions options_) + : s(s_) + , d(d_) + , options(options_) + { + if (!QDBusConnection::sessionBus().isConnected() || !(bus = QDBusConnection::sessionBus().interface())) { + d->errorMessage = QLatin1String("Session bus not found\n" + "To circumvent this problem try the following command (with Linux and bash)\n" + "export $(dbus-launch)"); + } else { + generateServiceName(); + } + } - if (!QDBusConnection::sessionBus().isConnected() || !(bus = QDBusConnection::sessionBus().interface())) { - d->errorMessage = QLatin1String("Session bus not found\n" - "To circumvent this problem try the following command (with Linux and bash)\n" - "export $(dbus-launch)"); + void run() { + if (bus) { + registerOnBus(); + } + + if (!d->registered && ((options & KDBusService::NoExitOnFailure) == 0)) { + qCritical() << d->errorMessage; + exit(1); + } } - if (bus) { + private: + + void generateServiceName() + { d->serviceName = d->generateServiceName(); - QString objectPath = QLatin1Char('/') + d->serviceName; + objectPath = QLatin1Char('/') + d->serviceName; objectPath.replace(QLatin1Char('.'), QLatin1Char('/')); objectPath.replace(QLatin1Char('-'), QLatin1Char('_')); // see spec change at https://bugs.freedesktop.org/show_bug.cgi?id=95129 - if (options & Multiple) { + if (options & KDBusService::Multiple) { bool inSandbox = false; if (!qEnvironmentVariableIsEmpty("XDG_RUNTIME_DIR")) { inSandbox = QFileInfo::exists(QString::fromUtf8(qgetenv("XDG_RUNTIME_DIR")) + QLatin1String("/flatpak-info")); @@ -105,57 +130,135 @@ d->serviceName += QLatin1Char('-') + QString::number(QCoreApplication::applicationPid()); } } + } + + void registerOnBus() + { + auto bus = QDBusConnection::sessionBus(); + bool objectRegistered = false; + objectRegistered = bus.registerObject(QStringLiteral("/MainApplication"), + QCoreApplication::instance(), + QDBusConnection::ExportAllSlots | + QDBusConnection::ExportScriptableProperties | + QDBusConnection::ExportAdaptors); + if (!objectRegistered) { + qWarning() << "Failed to register /MainApplication on DBus"; + return; + } + + objectRegistered = bus.registerObject(objectPath, s, QDBusConnection::ExportAdaptors); + if (!objectRegistered) { + qWarning() << "Failed to register" << objectPath << "on DBus"; + return; + } + + attemptRegistration(); + + if (d->registered) { + if (QCoreApplication *app = QCoreApplication::instance()) { + connect(app, &QCoreApplication::aboutToQuit, + s, &KDBusService::unregister); + } + } + } - QDBusConnection::sessionBus().registerObject(QStringLiteral("/MainApplication"), QCoreApplication::instance(), - QDBusConnection::ExportAllSlots | - QDBusConnection::ExportScriptableProperties | - QDBusConnection::ExportAdaptors); - QDBusConnection::sessionBus().registerObject(objectPath, this, - QDBusConnection::ExportAdaptors); - - d->registered = bus->registerService(d->serviceName) == QDBusConnectionInterface::ServiceRegistered; - - if (!d->registered) { - if (options & Unique) { - // Already running so it's ok! - QVariantMap platform_data; - platform_data.insert(QStringLiteral("desktop-startup-id"), QString::fromUtf8(qgetenv("DESKTOP_STARTUP_ID"))); - if (QCoreApplication::arguments().count() > 1) { - OrgKdeKDBusServiceInterface iface(d->serviceName, objectPath, QDBusConnection::sessionBus()); - iface.setTimeout(5 * 60 * 1000); // Application can take time to answer - QDBusReply<int> reply = iface.CommandLine(QCoreApplication::arguments(), QDir::currentPath(), platform_data); - if (reply.isValid()) { - exit(reply.value()); - } else { - d->errorMessage = reply.error().message(); - } + void attemptRegistration() + { + Q_ASSERT(!d->registered); + + auto queueOption = QDBusConnectionInterface::DontQueueService; + + if (options & KDBusService::Unique) { + // When a process crashes and gets auto-restarted by KCrash we may + // be in this code path "too early". There is a bit of a delay + // between the restart and the previous process dropping off of the + // bus and thus releasing its registered names. As a result there + // is a good chance that if we wait a bit the name will shortly + // become registered. + + queueOption = QDBusConnectionInterface::QueueService; + + connect(bus, &QDBusConnectionInterface::serviceRegistered, + this, [this](const QString &service) { + if (service != d->serviceName) { + return; + } + + d->registered = true; + registrationLoop.quit(); + }); + } + + d->registered = + (bus->registerService(d->serviceName, queueOption) == QDBusConnectionInterface::ServiceRegistered); + + if (d->registered) { + return; + } + + if (options & KDBusService::Unique) { + // Already running so it's ok! + QVariantMap platform_data; + platform_data.insert(QStringLiteral("desktop-startup-id"), QString::fromUtf8(qgetenv("DESKTOP_STARTUP_ID"))); + if (QCoreApplication::arguments().count() > 1) { + OrgKdeKDBusServiceInterface iface(d->serviceName, objectPath, QDBusConnection::sessionBus()); + iface.setTimeout(5 * 60 * 1000); // Application can take time to answer + QDBusReply<int> reply = iface.CommandLine(QCoreApplication::arguments(), QDir::currentPath(), platform_data); + if (reply.isValid()) { + exit(reply.value()); } else { - OrgFreedesktopApplicationInterface iface(d->serviceName, objectPath, QDBusConnection::sessionBus()); - iface.setTimeout(5 * 60 * 1000); // Application can take time to answer - QDBusReply<void> reply = iface.Activate(platform_data); - if (reply.isValid()) { - exit(0); - } else { - d->errorMessage = reply.error().message(); - } + d->errorMessage = reply.error().message(); } } else { - d->errorMessage = QLatin1String("Couldn't register name '") - + d->serviceName - + QLatin1String("' with DBUS - another process owns it already!"); + OrgFreedesktopApplicationInterface iface(d->serviceName, objectPath, QDBusConnection::sessionBus()); + iface.setTimeout(5 * 60 * 1000); // Application can take time to answer + QDBusReply<void> reply = iface.Activate(platform_data); + if (reply.isValid()) { + exit(0); + } else { + d->errorMessage = reply.error().message(); + } } - } else { - if (QCoreApplication *app = QCoreApplication::instance()) { - connect(app, &QCoreApplication::aboutToQuit, this, &KDBusService::unregister); - } + // service did not respond in a valid way.... + // let's wait to see if our queued registration finishes perhaps. + waitForRegistration(); + } + + if (!d->registered) { // either multi service or failed to reclaim name + d->errorMessage = QLatin1String("Couldn't register name '") + + d->serviceName + + QLatin1String("' with DBUS - another process owns it already!"); } } - if (!d->registered && ((options & NoExitOnFailure) == 0)) { - qCritical() << d->errorMessage; - exit(1); + void waitForRegistration() + { + QTimer quitTimer; + // Wait a bit longer when we know this instance was restarted. There's + // a very good chance we'll eventually get the name once the defunct + // process closes its sockets. + quitTimer.start(qEnvironmentVariableIsSet("KCRASH_AUTO_RESTARTED") ? 8000 : 2000); + connect(&quitTimer, &QTimer::timeout, ®istrationLoop, &QEventLoop::quit); + registrationLoop.exec(); } + + QDBusConnectionInterface *bus = nullptr; + KDBusService *s = nullptr; + KDBusServicePrivate *d = nullptr; + KDBusService::StartupOptions options; + QEventLoop registrationLoop; + QString objectPath; +}; + +KDBusService::KDBusService(StartupOptions options, QObject *parent) + : QObject(parent), d(new KDBusServicePrivate) +{ + new KDBusServiceAdaptor(this); + new KDBusServiceExtensionsAdaptor(this); + + Registration registration(this, d, options); + registration.run(); } KDBusService::~KDBusService() @@ -240,3 +343,5 @@ // TODO (via hook) KStartupInfo::appStarted(platform_data.value("desktop-startup-id")) return d->exitValue; } + +#include "kdbusservice.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/src/kdedmodule.cpp new/kdbusaddons-5.62.0/src/kdedmodule.cpp --- old/kdbusaddons-5.61.0/src/kdedmodule.cpp 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/src/kdedmodule.cpp 2019-09-07 15:57:05.000000000 +0200 @@ -23,7 +23,6 @@ #include "kdedmodule.h" #include "kdbusaddons_debug.h" -#include <QTimer> #include <QDBusConnection> #include <QDBusObjectPath> #include <QDBusMessage> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/src/kdedmodule.h new/kdbusaddons-5.62.0/src/kdedmodule.h --- old/kdbusaddons-5.61.0/src/kdedmodule.h 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/src/kdedmodule.h 2019-09-07 15:57:05.000000000 +0200 @@ -25,7 +25,6 @@ #include <kdbusaddons_export.h> #include <QObject> -#include <QByteArray> class KDEDModulePrivate; class Kded; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kdbusaddons-5.61.0/src/kdeinitinterface.h new/kdbusaddons-5.62.0/src/kdeinitinterface.h --- old/kdbusaddons-5.61.0/src/kdeinitinterface.h 2019-08-03 21:52:28.000000000 +0200 +++ new/kdbusaddons-5.62.0/src/kdeinitinterface.h 2019-09-07 15:57:05.000000000 +0200 @@ -22,8 +22,6 @@ #ifndef KDEINIT_IFACE_H #define KDEINIT_IFACE_H -#include <QObject> -#include <QUrl> #include <kdbusaddons_export.h>