From af29bc277e8b5c5502f6d38a6de966e75d9f8c96 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Wed, 28 Aug 2024 17:53:39 -0700 Subject: [PATCH] core: add by-pid symlinks to instance runtime paths --- src/core/main.cpp | 1 + src/core/paths.cpp | 80 +++++++++++++++++++++++++++++++++++++++------- src/core/paths.hpp | 4 +++ 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/core/main.cpp b/src/core/main.cpp index 25257b5f..c886cc1d 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -535,6 +535,7 @@ int qs_main(int argc, char** argv) { } QsPaths::init(shellId); + QsPaths::instance()->linkPidRunDir(); if (auto* cacheDir = QsPaths::instance()->cacheDir()) { auto qmlCacheDir = cacheDir->filePath("qml-engine-cache"); diff --git a/src/core/paths.cpp b/src/core/paths.cpp index 8f63b3aa..7162da5c 100644 --- a/src/core/paths.cpp +++ b/src/core/paths.cpp @@ -1,4 +1,5 @@ #include "paths.hpp" +#include #include #include @@ -38,9 +39,11 @@ QDir* QsPaths::cacheDir() { qCDebug(logPaths) << "Initialized cache path:" << dir.path(); if (!dir.mkpath(".")) { - qCCritical(logPaths) << "Cannot create cache directory at" << dir.path(); + qCCritical(logPaths) << "Could not create cache directory at" << dir.path(); this->cacheState = DirState::Failed; + } else { + this->cacheState = DirState::Ready; } } @@ -48,23 +51,48 @@ QDir* QsPaths::cacheDir() { else return &this->mCacheDir; } -QDir* QsPaths::runDir() { - if (this->runState == DirState::Unknown) { +QDir* QsPaths::baseRunDir() { + if (this->baseRunState == DirState::Unknown) { auto runtimeDir = qEnvironmentVariable("XDG_RUNTIME_DIR"); if (runtimeDir.isEmpty()) { runtimeDir = QString("/run/user/$1").arg(getuid()); qCInfo(logPaths) << "XDG_RUNTIME_DIR was not set, defaulting to" << runtimeDir; } - auto dir = QDir(runtimeDir); - dir = QDir(dir.filePath("quickshell")); - dir = QDir(dir.filePath(this->shellId)); - this->mRunDir = dir; + this->mBaseRunDir = QDir(runtimeDir); + this->mBaseRunDir = QDir(this->mBaseRunDir.filePath("quickshell")); + qCDebug(logPaths) << "Initialized base runtime path:" << this->mBaseRunDir.path(); - qCDebug(logPaths) << "Initialized runtime path:" << dir.path(); + if (!this->mBaseRunDir.mkpath(".")) { + qCCritical(logPaths) << "Could not create base runtime directory at" + << this->mBaseRunDir.path(); - if (!dir.mkpath(".")) { - qCCritical(logPaths) << "Cannot create runtime directory at" << dir.path(); + this->baseRunState = DirState::Failed; + } else { + this->baseRunState = DirState::Ready; + } + } + + if (this->baseRunState == DirState::Failed) return nullptr; + else return &this->mBaseRunDir; +} + +QDir* QsPaths::runDir() { + if (this->runState == DirState::Unknown) { + if (auto* baseRunDir = this->baseRunDir()) { + this->mRunDir = QDir(baseRunDir->filePath(this->shellId)); + + qCDebug(logPaths) << "Initialized runtime path:" << this->mRunDir.path(); + + if (!this->mRunDir.mkpath(".")) { + qCCritical(logPaths) << "Could not create runtime directory at" << this->mRunDir.path(); + this->runState = DirState::Failed; + } else { + this->runState = DirState::Ready; + } + } else { + qCCritical(logPaths) << "Could not create shell runtime path as it was not possible to " + "create the base runtime path."; this->runState = DirState::Failed; } @@ -89,9 +117,11 @@ QDir* QsPaths::instanceRunDir() { qCDebug(logPaths) << "Initialized instance runtime path:" << this->mInstanceRunDir.path(); if (!this->mInstanceRunDir.mkpath(".")) { - qCCritical(logPaths) << "Cannot create instance runtime directory at" + qCCritical(logPaths) << "Could not create instance runtime directory at" << this->mInstanceRunDir.path(); this->instanceRunState = DirState::Failed; + } else { + this->instanceRunState = DirState::Ready; } } } @@ -99,3 +129,31 @@ QDir* QsPaths::instanceRunDir() { if (this->runState == DirState::Failed) return nullptr; else return &this->mInstanceRunDir; } + +void QsPaths::linkPidRunDir() { + if (auto* runDir = this->instanceRunDir()) { + auto pidDir = QDir(this->baseRunDir()->filePath("by-pid")); + + if (!pidDir.mkpath(".")) { + qCCritical(logPaths) << "Could not create PID symlink directory."; + return; + } + + auto pidPath = pidDir.filePath(QString::number(getpid())); + + QFile::remove(pidPath); + auto r = symlinkat(runDir->filesystemCanonicalPath().c_str(), 0, pidPath.toStdString().c_str()); + + if (r != 0) { + qCCritical(logPaths).nospace() + << "Could not create PID symlink to " << runDir->path() << " at " << pidPath + << " with error code " << errno << ": " << qt_error_string(); + } else { + qCDebug(logPaths) << "Created PID symlink" << pidPath << "to instance runtime path" + << runDir->path(); + } + } else { + qCCritical(logPaths) << "Could not create PID symlink to runtime directory, as the runtime " + "directory could not be created."; + } +} diff --git a/src/core/paths.hpp b/src/core/paths.hpp index 9716e299..866a33cf 100644 --- a/src/core/paths.hpp +++ b/src/core/paths.hpp @@ -9,8 +9,10 @@ public: static QDir crashDir(const QString& shellId, const QDateTime& launchTime); QDir* cacheDir(); + QDir* baseRunDir(); QDir* runDir(); QDir* instanceRunDir(); + void linkPidRunDir(); private: enum class DirState { @@ -21,9 +23,11 @@ private: QString shellId; QDir mCacheDir; + QDir mBaseRunDir; QDir mRunDir; QDir mInstanceRunDir; DirState cacheState = DirState::Unknown; + DirState baseRunState = DirState::Unknown; DirState runState = DirState::Unknown; DirState instanceRunState = DirState::Unknown; };