commit:     19e4556dcb739c816b4181e1343e560bbb73f3b6
Author:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
AuthorDate: Fri Jan  9 14:42:31 2026 +0000
Commit:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
CommitDate: Fri Jan  9 20:50:44 2026 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=19e4556d

x11-misc/sddm: restart greeter when helper is in a wrong state

See also: https://github.com/sddm/sddm/issues/1908

Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>

 ...sddm-0.21.0_p20251101-fix-restart-greeter.patch | 457 +++++++++++++++++++++
 x11-misc/sddm/sddm-0.21.0_p20251101.ebuild         |   6 +-
 2 files changed, 461 insertions(+), 2 deletions(-)

diff --git 
a/x11-misc/sddm/files/sddm-0.21.0_p20251101-fix-restart-greeter.patch 
b/x11-misc/sddm/files/sddm-0.21.0_p20251101-fix-restart-greeter.patch
new file mode 100644
index 000000000000..71fb01464e34
--- /dev/null
+++ b/x11-misc/sddm/files/sddm-0.21.0_p20251101-fix-restart-greeter.patch
@@ -0,0 +1,457 @@
+From 4d06b6f77024d3ecaa458f0474691bf8b5f1306e Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Sun, 13 Jul 2025 19:42:40 +0200
+Subject: [PATCH 1/9] fix(helper): do not badly exit on SIGHUP
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/HelperApp.cpp | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index 32da42df3..49b7e1d79 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -53,8 +53,13 @@ namespace SDDM {
+             , m_socket(new QLocalSocket(this)) {
+         qInstallMessageHandler(HelperMessageHandler);
+         SignalHandler *s = new SignalHandler(this);
++        s->addCustomSignal(SIGHUP);
+         QObject::connect(s, &SignalHandler::sigtermReceived, m_session, [] {
+-            QCoreApplication::instance()->exit(-1);
++            QCoreApplication::instance()->exit(Auth::HELPER_OTHER_ERROR);
++        });
++
++        QObject::connect(s, &SignalHandler::customSignalReceived, m_session, 
[](int) {
++            QCoreApplication::instance()->exit(Auth::HELPER_OTHER_ERROR);
+         });
+ 
+         QTimer::singleShot(0, this, SLOT(setUp()));
+
+From 2eba0aa7e32da2becfb2e48327b7f4e94cdd0275 Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Sun, 20 Jul 2025 17:15:54 +0200
+Subject: [PATCH 2/9] fix(helper): avoid exiting 1 at all costs when session
+ finishes
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/HelperApp.cpp | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index 49b7e1d79..7e8cd6d10 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -199,7 +199,12 @@ namespace SDDM {
+     }
+ 
+     void HelperApp::sessionFinished(int status) {
+-        exit(status);
++        if (status != 0) {
++            qWarning("Session crashed (exit code %d).", status);
++            exit(Auth::HELPER_SESSION_ERROR);
++        }
++        else
++            exit(Auth::HELPER_SUCCESS);
+     }
+ 
+     void HelperApp::info(const QString& message, Auth::Info type) {
+
+From ff0a330ada7062094fc2360e0432c92063f3ec2d Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Tue, 29 Jul 2025 22:18:34 +0200
+Subject: [PATCH 3/9] fix(auth): do not cast exit status if `QProcess` is not
+ exited normally
+
+A QProcess::CrashExit happen in most cases when a signal killed it. And
+returning from a signal-killed process on Linux makes QProcess:finished
+return the signal, which is a really bad idea to cast into a random
+enum.
+
+Qt also mentions that `exitCode` is only valid for QProcess::NormalExit
+invocations
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/auth/Auth.cpp | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/auth/Auth.cpp b/src/auth/Auth.cpp
+index 6c9b5c6b4..6ff38ef1f 100644
+--- a/src/auth/Auth.cpp
++++ b/src/auth/Auth.cpp
+@@ -230,7 +230,10 @@ namespace SDDM {
+         else
+             qWarning("Auth: sddm-helper exited with %d", exitCode);
+ 
+-        Q_EMIT 
qobject_cast<Auth*>(parent())->finished((Auth::HelperExitStatus)exitCode);
++        if (exitStatus == QProcess::NormalExit)
++            Q_EMIT 
qobject_cast<Auth*>(parent())->finished((Auth::HelperExitStatus)exitCode);
++        else
++            Q_EMIT 
qobject_cast<Auth*>(parent())->finished(Auth::HELPER_OTHER_ERROR);
+     }
+ 
+     void Auth::Private::childError(QProcess::ProcessError error) {
+
+From 97e918b17a5ebc6cb8629cde3a6bc8b5bf44cacc Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Wed, 30 Jul 2025 12:24:17 +0200
+Subject: [PATCH 4/9] fix(helper): remove overload of `QProcess::finished` in
+ UserSession
+
+This will allow HelperApp to dinstinguish between a crash (most likely
+by a signal) from a normal exit.
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/HelperApp.cpp   | 12 ++++++++----
+ src/helper/HelperApp.h     |  2 +-
+ src/helper/UserSession.cpp |  3 +--
+ src/helper/UserSession.h   |  4 ----
+ 4 files changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index 7e8cd6d10..e0141bb7c 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -131,7 +131,7 @@ namespace SDDM {
+         }
+ 
+         connect(m_socket, &QLocalSocket::connected, this, &HelperApp::doAuth);
+-        connect(m_session, &UserSession::finished, this, 
&HelperApp::sessionFinished);
++        connect(m_session, QOverload<int, 
QProcess::ExitStatus>::of(&QProcess::finished), this, 
&HelperApp::sessionFinished);
+         m_socket->connectToServer(server, QIODevice::ReadWrite | 
QIODevice::Unbuffered);
+     }
+ 
+@@ -198,9 +198,13 @@ namespace SDDM {
+         return;
+     }
+ 
+-    void HelperApp::sessionFinished(int status) {
+-        if (status != 0) {
+-            qWarning("Session crashed (exit code %d).", status);
++    void HelperApp::sessionFinished(int exitCode, QProcess::ExitStatus 
exitStatus) {
++        if (exitStatus == QProcess::CrashExit) {
++            qWarning("Session crashed (killed by signal %d).", exitCode);
++            exit(Auth::HELPER_SESSION_ERROR);
++        }
++        else if (exitCode != 0) {
++            qWarning("Session crashed (exit code %d).", exitCode);
+             exit(Auth::HELPER_SESSION_ERROR);
+         }
+         else
+diff --git a/src/helper/HelperApp.h b/src/helper/HelperApp.h
+index 64ea0e1c8..9874ab8eb 100644
+--- a/src/helper/HelperApp.h
++++ b/src/helper/HelperApp.h
+@@ -54,7 +54,7 @@ namespace SDDM {
+         void setUp();
+         void doAuth();
+ 
+-        void sessionFinished(int status);
++        void sessionFinished(int exitCode, QProcess::ExitStatus exitStatus);
+ 
+     private:
+         qint64 m_id { -1 };
+diff --git a/src/helper/UserSession.cpp b/src/helper/UserSession.cpp
+index 03fd396ee..5fd378a6e 100644
+--- a/src/helper/UserSession.cpp
++++ b/src/helper/UserSession.cpp
+@@ -47,7 +47,6 @@ namespace SDDM {
+     UserSession::UserSession(HelperApp *parent)
+         : QProcess(parent)
+     {
+-        connect(this, QOverload<int, 
QProcess::ExitStatus>::of(&QProcess::finished), this, &UserSession::finished);
+ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+         setChildProcessModifier(std::bind(&UserSession::childModifier, this));
+ #endif
+@@ -157,7 +156,7 @@ namespace SDDM {
+                 }
+             }
+         } else {
+-            Q_EMIT finished(Auth::HELPER_OTHER_ERROR);
++            Q_EMIT finished(Auth::HELPER_OTHER_ERROR, QProcess::NormalExit);
+         }
+     }
+ 
+diff --git a/src/helper/UserSession.h b/src/helper/UserSession.h
+index ecaef8679..78cd994a7 100644
+--- a/src/helper/UserSession.h
++++ b/src/helper/UserSession.h
+@@ -51,10 +51,6 @@ namespace SDDM {
+         */
+         qint64 cachedProcessId();
+ 
+-
+-    Q_SIGNALS:
+-        void finished(int exitCode);
+-
+ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+     protected:
+         void setupChildProcess() override;
+
+From 7052ba863174faa05fed8cbbdc7c71cf202e6cfd Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Wed, 30 Jul 2025 13:37:14 +0200
+Subject: [PATCH 5/9] style(helper): rearrange if conditions to explicitly
+ check for normal exit
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/HelperApp.cpp | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index e0141bb7c..fa1167c9f 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -199,16 +199,16 @@ namespace SDDM {
+     }
+ 
+     void HelperApp::sessionFinished(int exitCode, QProcess::ExitStatus 
exitStatus) {
+-        if (exitStatus == QProcess::CrashExit) {
+-            qWarning("Session crashed (killed by signal %d).", exitCode);
+-            exit(Auth::HELPER_SESSION_ERROR);
+-        }
+-        else if (exitCode != 0) {
+-            qWarning("Session crashed (exit code %d).", exitCode);
+-            exit(Auth::HELPER_SESSION_ERROR);
++        if (exitStatus == QProcess::NormalExit) {
++            if (exitCode != 0) {
++                qWarning("Session crashed (exit code %d).", exitCode);
++                exit(Auth::HELPER_SESSION_ERROR);
++            }
++            else
++                exit(Auth::HELPER_SUCCESS);
+         }
+-        else
+-            exit(Auth::HELPER_SUCCESS);
++        qWarning("Session crashed (killed by signal %d).", exitCode);
++        exit(Auth::HELPER_SESSION_ERROR);
+     }
+ 
+     void HelperApp::info(const QString& message, Auth::Info type) {
+
+From f886081f98f02ed42e517be6949e1a22971b3e1e Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Fri, 1 Aug 2025 01:26:48 +0200
+Subject: [PATCH 6/9] fix(helper): return after exits and check for session
+ state in destructor
+
+This avoids calling exit an unnecessary number of times, which can
+potentially falsify the real return code, and cause restrat loops
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/HelperApp.cpp | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index fa1167c9f..6a39ac00b 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -206,7 +206,11 @@ namespace SDDM {
+             }
+             else
+                 exit(Auth::HELPER_SUCCESS);
++            return;
+         }
++
++        Q_ASSERT_X(exitCode != 0, "HelperApp::sessionFinished", "Crashing 
with 0 is impossible");
++
+         qWarning("Session crashed (killed by signal %d).", exitCode);
+         exit(Auth::HELPER_SESSION_ERROR);
+     }
+@@ -298,7 +302,9 @@ namespace SDDM {
+     HelperApp::~HelperApp() {
+         Q_ASSERT(getuid() == 0);
+ 
+-        m_session->stop();
++        // Avoid re-emitting QProcess::finished if session is not running
++        if (m_session->state() != QProcess::NotRunning)
++            m_session->stop();
+         m_backend->closeSession();
+ 
+         // write logout to utmp/wtmp
+
+From 72db1388b931858af3d0f066ed5c3a1948979422 Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Fri, 1 Aug 2025 11:42:46 +0200
+Subject: [PATCH 7/9] fix(helper): do not emit finish when stopping already
+ stopped session
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/UserSession.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/helper/UserSession.cpp b/src/helper/UserSession.cpp
+index 5fd378a6e..3e0a5afb4 100644
+--- a/src/helper/UserSession.cpp
++++ b/src/helper/UserSession.cpp
+@@ -156,7 +156,7 @@ namespace SDDM {
+                 }
+             }
+         } else {
+-            Q_EMIT finished(Auth::HELPER_OTHER_ERROR, QProcess::NormalExit);
++            qInfo() << "Attempted to stop session, but was already not 
running";
+         }
+     }
+ 
+
+From 7aa2576b1a916796b1700a426bd9df1b368007b7 Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Fri, 1 Aug 2025 11:43:58 +0200
+Subject: [PATCH 8/9] style(helper): explicit usage of `QCoreApplication::exit`
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/HelperApp.cpp | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index 6a39ac00b..f7958e9be 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -73,7 +73,7 @@ namespace SDDM {
+         if ((pos = args.indexOf(QStringLiteral("--socket"))) >= 0) {
+             if (pos >= args.length() - 1) {
+                 qCritical() << "This application is not supposed to be 
executed manually";
+-                exit(Auth::HELPER_OTHER_ERROR);
++                QCoreApplication::exit(Auth::HELPER_OTHER_ERROR);
+                 return;
+             }
+             server = args[pos + 1];
+@@ -82,7 +82,7 @@ namespace SDDM {
+         if ((pos = args.indexOf(QStringLiteral("--id"))) >= 0) {
+             if (pos >= args.length() - 1) {
+                 qCritical() << "This application is not supposed to be 
executed manually";
+-                exit(Auth::HELPER_OTHER_ERROR);
++                QCoreApplication::exit(Auth::HELPER_OTHER_ERROR);
+                 return;
+             }
+             m_id = QString(args[pos + 1]).toLongLong();
+@@ -91,7 +91,7 @@ namespace SDDM {
+         if ((pos = args.indexOf(QStringLiteral("--start"))) >= 0) {
+             if (pos >= args.length() - 1) {
+                 qCritical() << "This application is not supposed to be 
executed manually";
+-                exit(Auth::HELPER_OTHER_ERROR);
++                QCoreApplication::exit(Auth::HELPER_OTHER_ERROR);
+                 return;
+             }
+             m_session->setPath(args[pos + 1]);
+@@ -100,7 +100,7 @@ namespace SDDM {
+         if ((pos = args.indexOf(QStringLiteral("--user"))) >= 0) {
+             if (pos >= args.length() - 1) {
+                 qCritical() << "This application is not supposed to be 
executed manually";
+-                exit(Auth::HELPER_OTHER_ERROR);
++                QCoreApplication::exit(Auth::HELPER_OTHER_ERROR);
+                 return;
+             }
+             m_user = args[pos + 1];
+@@ -109,7 +109,7 @@ namespace SDDM {
+         if ((pos = args.indexOf(QStringLiteral("--display-server"))) >= 0) {
+             if (pos >= args.length() - 1) {
+                 qCritical() << "This application is not supposed to be 
executed manually";
+-                exit(Auth::HELPER_OTHER_ERROR);
++                QCoreApplication::exit(Auth::HELPER_OTHER_ERROR);
+                 return;
+             }
+             m_session->setDisplayServerCommand(args[pos + 1]);
+@@ -126,7 +126,7 @@ namespace SDDM {
+ 
+         if (server.isEmpty() || m_id <= 0) {
+             qCritical() << "This application is not supposed to be executed 
manually";
+-            exit(Auth::HELPER_OTHER_ERROR);
++            QCoreApplication::exit(Auth::HELPER_OTHER_ERROR);
+             return;
+         }
+ 
+@@ -151,7 +151,7 @@ namespace SDDM {
+             const QString vt = env.value(QStringLiteral("XDG_VTNR"));
+             utmpLogin(vt, displayId, m_user, 0, false);
+ 
+-            exit(Auth::HELPER_AUTH_ERROR);
++            QCoreApplication::exit(Auth::HELPER_AUTH_ERROR);
+             return;
+         }
+ 
+@@ -165,7 +165,7 @@ namespace SDDM {
+             const QString vt = env.value(QStringLiteral("XDG_VTNR"));
+             utmpLogin(vt, displayId, m_user, 0, false);
+ 
+-            exit(Auth::HELPER_AUTH_ERROR);
++            QCoreApplication::exit(Auth::HELPER_AUTH_ERROR);
+             return;
+         }
+ 
+@@ -178,7 +178,7 @@ namespace SDDM {
+ 
+             if (!m_backend->openSession()) {
+                 sessionOpened(false);
+-                exit(Auth::HELPER_SESSION_ERROR);
++                QCoreApplication::exit(Auth::HELPER_SESSION_ERROR);
+                 return;
+             }
+ 
+@@ -194,7 +194,7 @@ namespace SDDM {
+             }
+         }
+         else
+-            exit(Auth::HELPER_SUCCESS);
++            QCoreApplication::exit(Auth::HELPER_SUCCESS);
+         return;
+     }
+ 
+@@ -202,17 +202,17 @@ namespace SDDM {
+         if (exitStatus == QProcess::NormalExit) {
+             if (exitCode != 0) {
+                 qWarning("Session crashed (exit code %d).", exitCode);
+-                exit(Auth::HELPER_SESSION_ERROR);
++                QCoreApplication::exit(Auth::HELPER_SESSION_ERROR);
+             }
+             else
+-                exit(Auth::HELPER_SUCCESS);
++                QCoreApplication::exit(Auth::HELPER_SUCCESS);
+             return;
+         }
+ 
+         Q_ASSERT_X(exitCode != 0, "HelperApp::sessionFinished", "Crashing 
with 0 is impossible");
+ 
+         qWarning("Session crashed (killed by signal %d).", exitCode);
+-        exit(Auth::HELPER_SESSION_ERROR);
++        QCoreApplication::exit(Auth::HELPER_SESSION_ERROR);
+     }
+ 
+     void HelperApp::info(const QString& message, Auth::Info type) {
+
+From 4978251750021d5686f5837dffd12a5e99b7ada6 Mon Sep 17 00:00:00 2001
+From: "tsrk." <[email protected]>
+Date: Fri, 1 Aug 2025 12:13:12 +0200
+Subject: [PATCH 9/9] fix(helper): disconnect `sessionFinished` when exiting
+
+Calling `UserSession::stop` results in a call to `QProcess::terminate`,
+which sends a SIGTERM to the session. `QProcess` will catch that and
+emit an excess `QProcess::finished(15, 1)` which we don't want to handle
+since we are in the process of exiting.
+
+Signed-off-by: tsrk. <[email protected]>
+---
+ src/helper/HelperApp.cpp | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp
+index f7958e9be..744a4ef01 100644
+--- a/src/helper/HelperApp.cpp
++++ b/src/helper/HelperApp.cpp
+@@ -302,7 +302,8 @@ namespace SDDM {
+     HelperApp::~HelperApp() {
+         Q_ASSERT(getuid() == 0);
+ 
+-        // Avoid re-emitting QProcess::finished if session is not running
++        // Avoid calls to sessionFinished when exiting
++        disconnect(m_session, QOverload<int, 
QProcess::ExitStatus>::of(&QProcess::finished), this, 
&HelperApp::sessionFinished);
+         if (m_session->state() != QProcess::NotRunning)
+             m_session->stop();
+         m_backend->closeSession();

diff --git a/x11-misc/sddm/sddm-0.21.0_p20251101.ebuild 
b/x11-misc/sddm/sddm-0.21.0_p20251101.ebuild
index c4d1f9645b59..1587ddc948e0 100644
--- a/x11-misc/sddm/sddm-0.21.0_p20251101.ebuild
+++ b/x11-misc/sddm/sddm-0.21.0_p20251101.ebuild
@@ -57,8 +57,10 @@ PATCHES=(
        # Downstream patches
        "${FILESDIR}/${PN}-0.20.0-respect-user-flags.patch"
        "${FILESDIR}/${PN}-0.21.0_p20250310-Xsession-xinitrc.patch" # bug 611210
-       "${FILESDIR}/${PN}-0.21.0_p20250310-set-XAUTHLOCALHOSTNAME.patch" # bug 
913862, thx opensuse
-       "${FILESDIR}/${P}-cmake-minreqver-3.16.patch" # bug 964439
+       "${FILESDIR}/${P}-cmake-minreqver-3.16.patch" # pending upstream, bug 
964439
+       "${FILESDIR}/${P}-fix-restart-greeter.patch" # pending upstream
+       # thx opensuse
+       "${FILESDIR}/${PN}-0.21.0_p20250310-set-XAUTHLOCALHOSTNAME.patch" # bug 
913862
 )
 
 pkg_setup() {

Reply via email to