From 4c522137411828020c26d7834eca08e5eab98505 Mon Sep 17 00:00:00 2001 From: guoyao Date: Wed, 15 Jul 2026 16:03:49 +0800 Subject: [PATCH] fix: allow treeland to start without any users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. session.cpp: fall back to getpwuid(getuid()) on getpwnam failure 2. usermodel.cpp: guard empty user list before .first() to avoid UB 3. usermodel.cpp: replace qFatal with qCWarning for D-Bus graceful fallback 4. treeland.cpp: replace Q_ASSERT(globalSession) with runtime null check Log: treeland can now start normally even when no users exist Influence: 1. Test treeland startup with no system users (empty /etc/passwd user list) 2. Test treeland startup when Accounts D-Bus service is unavailable 3. Verify treeland startup with normal user presence is unaffected 4. Test user switching and session management in edge-case scenarios fix: 允许 treeland 在没有任何用户时正常启动 1. session.cpp: getpwnam 失败时回退到 getpwuid 确保全局会话可用 2. usermodel.cpp: 调用 .first() 前增加空列表守卫避免未定义行为 3. usermodel.cpp: qFatal 替换为 qCWarning 实现 D-Bus 优雅降级 4. treeland.cpp: Q_ASSERT 替换为运行时空指针检查 Log: treeland 现在可以在没有任何用户的情况下正常启动 Influence: 1. 测试在无系统用户时启动 treeland 不会崩溃 2. 测试 Accounts D-Bus 服务不可用时 treeland 启动正常 3. 验证正常用户场景下 treeland 启动不受影响 4. 测试边界场景下的用户切换与会话管理功能 Fixes: #82 --- src/core/treeland.cpp | 7 +++++-- src/greeter/usermodel.cpp | 11 ++++++++--- src/session/session.cpp | 10 ++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/core/treeland.cpp b/src/core/treeland.cpp index f642fd3e74..bd2b79a4cf 100644 --- a/src/core/treeland.cpp +++ b/src/core/treeland.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2023 Dingyuan Zhang . +// Copyright (C) 2023-2026 Dingyuan Zhang . // SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "treeland.h" @@ -314,7 +314,10 @@ Treeland::Treeland() d->init(); auto globalSession = d->helper->sessionManager()->globalSession(); - Q_ASSERT(globalSession); + if (!globalSession) { + qCCritical(lcTlCore) << "Global session is null, skipping initialization"; + return; + } if (CmdLine::ref().run().has_value()) { auto exec = [runCmd = CmdLine::ref().run().value(), d, globalSession] { diff --git a/src/greeter/usermodel.cpp b/src/greeter/usermodel.cpp index 97b65b767f..978fe12417 100644 --- a/src/greeter/usermodel.cpp +++ b/src/greeter/usermodel.cpp @@ -63,7 +63,8 @@ UserModel::UserModel(QObject *parent) auto userList = d->manager.userList(); if (!userList) { - qFatal() << userList.error(); + qCWarning(lcTlGreeter) << "Failed to get user list:" << userList.error(); + return; } const auto uids = userList.value(); @@ -95,8 +96,12 @@ UserModel::UserModel(QObject *parent) } if (d->currentUserName.isEmpty()) { - qCWarning(lcTlGreeter) << "Couldn't find last user, using current running user as current user"; - d->currentUserName = d->users.first()->userName(); + if (d->users.isEmpty()) { + qCWarning(lcTlGreeter) << "No users found, currentUserName remains empty"; + } else { + qCWarning(lcTlGreeter) << "Couldn't find last user, using current running user as current user"; + d->currentUserName = d->users.first()->userName(); + } } } diff --git a/src/session/session.cpp b/src/session/session.cpp index d6d61c8e78..00dfaed051 100644 --- a/src/session/session.cpp +++ b/src/session/session.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #define _DEEPIN_NO_TITLEBAR "_DEEPIN_NO_TITLEBAR" @@ -381,8 +382,13 @@ std::shared_ptr SessionManager::ensureSession(int id, QString username) // Session does not exist, create new session with deleter auto passwd = getpwnam(username.toLocal8Bit().data()); if (!passwd) { - qCWarning(lcTlCore) << "Failed to get passwd entry for user:" << username; - return nullptr; + qCWarning(lcTlCore) << "Failed to get passwd entry for user:" << username + << ", falling back to current user uid"; + passwd = getpwuid(getuid()); + if (!passwd) { + qCCritical(lcTlCore) << "Failed to get passwd entry for current user"; + return nullptr; + } } auto session = std::make_shared(); session->m_id = id;