core: add by-pid symlinks to instance runtime paths

This commit is contained in:
outfoxxed 2024-08-28 17:53:39 -07:00
parent 9967e2e03b
commit af29bc277e
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
3 changed files with 74 additions and 11 deletions

View file

@ -535,6 +535,7 @@ int qs_main(int argc, char** argv) {
} }
QsPaths::init(shellId); QsPaths::init(shellId);
QsPaths::instance()->linkPidRunDir();
if (auto* cacheDir = QsPaths::instance()->cacheDir()) { if (auto* cacheDir = QsPaths::instance()->cacheDir()) {
auto qmlCacheDir = cacheDir->filePath("qml-engine-cache"); auto qmlCacheDir = cacheDir->filePath("qml-engine-cache");

View file

@ -1,4 +1,5 @@
#include "paths.hpp" #include "paths.hpp"
#include <cerrno>
#include <utility> #include <utility>
#include <qdatetime.h> #include <qdatetime.h>
@ -38,9 +39,11 @@ QDir* QsPaths::cacheDir() {
qCDebug(logPaths) << "Initialized cache path:" << dir.path(); qCDebug(logPaths) << "Initialized cache path:" << dir.path();
if (!dir.mkpath(".")) { 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; this->cacheState = DirState::Failed;
} else {
this->cacheState = DirState::Ready;
} }
} }
@ -48,23 +51,48 @@ QDir* QsPaths::cacheDir() {
else return &this->mCacheDir; else return &this->mCacheDir;
} }
QDir* QsPaths::runDir() { QDir* QsPaths::baseRunDir() {
if (this->runState == DirState::Unknown) { if (this->baseRunState == DirState::Unknown) {
auto runtimeDir = qEnvironmentVariable("XDG_RUNTIME_DIR"); auto runtimeDir = qEnvironmentVariable("XDG_RUNTIME_DIR");
if (runtimeDir.isEmpty()) { if (runtimeDir.isEmpty()) {
runtimeDir = QString("/run/user/$1").arg(getuid()); runtimeDir = QString("/run/user/$1").arg(getuid());
qCInfo(logPaths) << "XDG_RUNTIME_DIR was not set, defaulting to" << runtimeDir; qCInfo(logPaths) << "XDG_RUNTIME_DIR was not set, defaulting to" << runtimeDir;
} }
auto dir = QDir(runtimeDir); this->mBaseRunDir = QDir(runtimeDir);
dir = QDir(dir.filePath("quickshell")); this->mBaseRunDir = QDir(this->mBaseRunDir.filePath("quickshell"));
dir = QDir(dir.filePath(this->shellId)); qCDebug(logPaths) << "Initialized base runtime path:" << this->mBaseRunDir.path();
this->mRunDir = dir;
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(".")) { this->baseRunState = DirState::Failed;
qCCritical(logPaths) << "Cannot create runtime directory at" << dir.path(); } 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; this->runState = DirState::Failed;
} }
@ -89,9 +117,11 @@ QDir* QsPaths::instanceRunDir() {
qCDebug(logPaths) << "Initialized instance runtime path:" << this->mInstanceRunDir.path(); qCDebug(logPaths) << "Initialized instance runtime path:" << this->mInstanceRunDir.path();
if (!this->mInstanceRunDir.mkpath(".")) { 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->mInstanceRunDir.path();
this->instanceRunState = DirState::Failed; this->instanceRunState = DirState::Failed;
} else {
this->instanceRunState = DirState::Ready;
} }
} }
} }
@ -99,3 +129,31 @@ QDir* QsPaths::instanceRunDir() {
if (this->runState == DirState::Failed) return nullptr; if (this->runState == DirState::Failed) return nullptr;
else return &this->mInstanceRunDir; 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.";
}
}

View file

@ -9,8 +9,10 @@ public:
static QDir crashDir(const QString& shellId, const QDateTime& launchTime); static QDir crashDir(const QString& shellId, const QDateTime& launchTime);
QDir* cacheDir(); QDir* cacheDir();
QDir* baseRunDir();
QDir* runDir(); QDir* runDir();
QDir* instanceRunDir(); QDir* instanceRunDir();
void linkPidRunDir();
private: private:
enum class DirState { enum class DirState {
@ -21,9 +23,11 @@ private:
QString shellId; QString shellId;
QDir mCacheDir; QDir mCacheDir;
QDir mBaseRunDir;
QDir mRunDir; QDir mRunDir;
QDir mInstanceRunDir; QDir mInstanceRunDir;
DirState cacheState = DirState::Unknown; DirState cacheState = DirState::Unknown;
DirState baseRunState = DirState::Unknown;
DirState runState = DirState::Unknown; DirState runState = DirState::Unknown;
DirState instanceRunState = DirState::Unknown; DirState instanceRunState = DirState::Unknown;
}; };