File indexing completed on 2024-05-26 04:05:32
0001 /* 0002 SPDX-FileCopyrightText: 2010 Mario Bensi <mbensi@ipsquad.net> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "fstabwatcher.h" 0008 #include "fstab_debug.h" 0009 #include "soliddefs_p.h" 0010 0011 #include <QCoreApplication> 0012 #include <QFile> 0013 #include <QFileSystemWatcher> 0014 #include <QSocketNotifier> 0015 0016 namespace Solid 0017 { 0018 namespace Backends 0019 { 0020 namespace Fstab 0021 { 0022 Q_GLOBAL_STATIC(FstabWatcher, globalFstabWatcher) 0023 0024 static const QString s_mtabFile = QStringLiteral("/etc/mtab"); 0025 #ifdef Q_OS_SOLARIS 0026 static const QString s_fstabFile = QStringLiteral("/etc/vfstab"); 0027 #else 0028 static const QString s_fstabFile = QStringLiteral("/etc/fstab"); 0029 #endif 0030 static const QString s_fstabPath = QStringLiteral("/etc"); 0031 0032 FstabWatcher::FstabWatcher() 0033 : m_isRoutineInstalled(false) 0034 , m_fileSystemWatcher(new QFileSystemWatcher(this)) 0035 { 0036 if (qApp) { 0037 connect(qApp, &QCoreApplication::aboutToQuit, this, &FstabWatcher::orphanFileSystemWatcher); 0038 } 0039 0040 m_mtabFile = new QFile(s_mtabFile, this); 0041 if (m_mtabFile && m_mtabFile->symLinkTarget().startsWith("/proc/") && m_mtabFile->open(QIODevice::ReadOnly)) { 0042 m_mtabSocketNotifier = new QSocketNotifier(m_mtabFile->handle(), QSocketNotifier::Exception, this); 0043 connect(m_mtabSocketNotifier, &QSocketNotifier::activated, this, &FstabWatcher::mtabChanged); 0044 } else { 0045 m_fileSystemWatcher->addPath(s_mtabFile); 0046 } 0047 0048 m_fileSystemWatcher->addPath(s_fstabPath); 0049 connect(m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, [this](const QString &) { 0050 if (!m_isFstabWatched) { 0051 m_isFstabWatched = m_fileSystemWatcher->addPath(s_fstabFile); 0052 if (m_isFstabWatched) { 0053 qCDebug(FSTAB_LOG) << "Re-added" << s_fstabFile; 0054 Q_EMIT onFileChanged(s_fstabFile); 0055 } 0056 } 0057 }); 0058 0059 m_isFstabWatched = m_fileSystemWatcher->addPath(s_fstabFile); 0060 connect(m_fileSystemWatcher, &QFileSystemWatcher::fileChanged, this, &FstabWatcher::onFileChanged); 0061 } 0062 0063 FstabWatcher::~FstabWatcher() 0064 { 0065 // The QFileSystemWatcher doesn't work correctly in a singleton 0066 // The solution so far was to destroy the QFileSystemWatcher when the application quits 0067 // But we have some crash with this solution. 0068 // For the moment to workaround the problem, we detach the QFileSystemWatcher from the parent 0069 // effectively leaking it on purpose. 0070 0071 #if 0 0072 //qRemovePostRoutine(globalFstabWatcher.destroy); 0073 #else 0074 m_fileSystemWatcher->setParent(nullptr); 0075 #endif 0076 } 0077 0078 void FstabWatcher::orphanFileSystemWatcher() 0079 { 0080 m_fileSystemWatcher->setParent(nullptr); 0081 } 0082 0083 FstabWatcher *FstabWatcher::instance() 0084 { 0085 #if 0 0086 FstabWatcher *fstabWatcher = globalFstabWatcher; 0087 0088 if (fstabWatcher && !fstabWatcher->m_isRoutineInstalled) { 0089 qAddPostRoutine(globalFstabWatcher.destroy); 0090 fstabWatcher->m_isRoutineInstalled = true; 0091 } 0092 return fstabWatcher; 0093 #else 0094 return globalFstabWatcher; 0095 #endif 0096 } 0097 0098 void FstabWatcher::onFileChanged(const QString &path) 0099 { 0100 if (path == s_mtabFile) { 0101 Q_EMIT mtabChanged(); 0102 if (!m_fileSystemWatcher->files().contains(s_mtabFile)) { 0103 m_fileSystemWatcher->addPath(s_mtabFile); 0104 } 0105 } 0106 if (path == s_fstabFile) { 0107 Q_EMIT fstabChanged(); 0108 if (!m_fileSystemWatcher->files().contains(s_fstabFile)) { 0109 m_isFstabWatched = m_fileSystemWatcher->addPath(s_fstabFile); 0110 qCDebug(FSTAB_LOG) << "Fstab removed, re-added:" << m_isFstabWatched; 0111 } 0112 } 0113 } 0114 0115 } 0116 } 0117 } // namespace Solid:Backends::Fstab 0118 0119 #include "moc_fstabwatcher.cpp"