Display: Do not offer a tty if it's already taken by a logind session

Otherwise, it all freezes and nothing works as it should.

Fixes #1588
This commit is contained in:
Aleix Pol 2022-09-21 15:15:07 +02:00 committed by GitHub
parent a16f612e34
commit 21e965aab8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 19 deletions

View File

@ -35,6 +35,9 @@ option(ENABLE_PAM "Enable PAM support" ON)
option(NO_SYSTEMD "Disable systemd support" OFF)
option(USE_ELOGIND "Use elogind instead of logind" OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# ECM
find_package(ECM 1.4.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH};${ECM_MODULE_PATH}")

View File

@ -31,6 +31,7 @@
#include <linux/kd.h>
#include <sys/ioctl.h>
#include <qscopeguard.h>
#include <QFileInfo>
#define RELEASE_DISPLAY_SIGNAL (SIGRTMAX)
#define ACQUIRE_DISPLAY_SIGNAL (SIGRTMAX - 1)
@ -116,8 +117,8 @@ out:
qDebug() << "VT mode didn't need to be fixed";
}
int fetchAvailableVt() {
// open VT master
int currentVt()
{
int fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
if (fd < 0) {
qCritical() << "Failed to open VT master:" << strerror(errno);
@ -129,19 +130,12 @@ out:
vt_stat vtState = { 0 };
if (ioctl(fd, VT_GETSTATE, &vtState) < 0) {
qCritical() << "Failed to get current VT:" << strerror(errno);
int vt = 0;
// If there's no current tty, request the next to open
if (ioctl(fd, VT_OPENQRY, &vt) < 0) {
qCritical() << "Failed to open new VT:" << strerror(errno);
return -1;
}
return vt;
return -1;
}
return vtState.v_active;
}
int setUpNewVt() {
// open VT master
int fd = open("/dev/tty0", O_RDWR | O_NOCTTY);

View File

@ -22,7 +22,7 @@
namespace SDDM {
namespace VirtualTerminal {
int fetchAvailableVt();
int currentVt();
int setUpNewVt();
void jumpToVt(int vt, bool vt_auto);
}

View File

@ -35,10 +35,9 @@ namespace SDDM {
static char ttyvX[] = "/dev/ttyvX";
static const char ttyvs[] = "0123456789ab";
int setUpNewVt() {
// there is no way to create VTs on FreeBSD, so
// just try to fetch any available
return fetchAvailableVt();
int currentVt()
{
return -1;
}
void jumpToVt(int vt, bool vt_auto) {
@ -64,7 +63,7 @@ namespace SDDM {
}
}
int fetchAvailableVt() {
int setUpNewVt() {
int fd = ::open("/dev/console", O_RDONLY);
if(fd == -1) {
qWarning() << "Failed to open /dev/console: " << strerror(errno);

View File

@ -40,6 +40,10 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/vt.h>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusReply>
@ -51,6 +55,35 @@
namespace SDDM {
bool isTtyInUse(const QString &desiredTty) {
if (Logind::isAvailable()) {
OrgFreedesktopLogin1ManagerInterface manager(Logind::serviceName(), Logind::managerPath(), QDBusConnection::systemBus());
auto reply = manager.ListSessions();
reply.waitForFinished();
const auto info = reply.value();
for(const SessionInfo &s : info) {
OrgFreedesktopLogin1SessionInterface session(Logind::serviceName(), s.sessionPath.path(), QDBusConnection::systemBus());
if (desiredTty == session.tTY() && session.state() != QLatin1String("closing")) {
qDebug() << "tty" << desiredTty << "already in use by" << session.user().path << session.state()
<< session.display() << session.desktop() << session.vTNr();
return true;
}
}
}
return false;
}
int fetchAvailableVt() {
const auto vt = VirtualTerminal::currentVt();
if (vt > 0) {
if (!isTtyInUse(QStringLiteral("tty%1").arg(vt))) {
return vt;
}
}
return VirtualTerminal::setUpNewVt();
}
Display::Display(Seat *parent) : QObject(parent),
m_auth(new Auth(this)),
m_seat(parent),
@ -62,10 +95,10 @@ namespace SDDM {
const QString &displayServerType = mainConfig.DisplayServer.get().toLower();
if (displayServerType == QStringLiteral("x11-user")) {
m_displayServerType = X11UserDisplayServerType;
m_terminalId = VirtualTerminal::fetchAvailableVt();
m_terminalId = fetchAvailableVt();
} else if (displayServerType == QStringLiteral("wayland")) {
m_displayServerType = WaylandDisplayServerType;
m_terminalId = VirtualTerminal::fetchAvailableVt();
m_terminalId = fetchAvailableVt();
} else {
if (displayServerType != QLatin1String("x11")) {
qWarning("\"%s\" is an invalid value for General.DisplayServer: fall back to \"x11\"",