diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -92,6 +92,7 @@ util/kosrelease.cpp util/kprocesslist.cpp util/kshell.cpp + util/blockingapp.cpp ${kcoreaddons_OPTIONAL_SRCS} ${kcoreaddons_QM_LOADER} ) diff --git a/src/lib/util/blockingapp.h b/src/lib/util/blockingapp.h new file mode 100644 --- /dev/null +++ b/src/lib/util/blockingapp.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE Frameworks + * + * Copyright (C) 2019 Méven Car + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef BLOCKINGAPP_H +#define BLOCKINGAPP_H + +#include +#include +#include "kcoreaddons_export.h" + +class QString; + +class KCOREADDONS_EXPORT BlockingApp: public QObject +{ + Q_OBJECT + +public: + void queryBlockingApps(const QString &fileName); + +Q_SIGNALS: + void blockingAppsReady(const QStringList &apps); +}; + +#endif // BLOCKINGAPP_H diff --git a/src/lib/util/blockingapp.cpp b/src/lib/util/blockingapp.cpp new file mode 100644 --- /dev/null +++ b/src/lib/util/blockingapp.cpp @@ -0,0 +1,72 @@ +/* This file is part of the KDE Frameworks + * + * Copyright (C) 2019 Méven Car + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "blockingapp.h" + +#include +#include +#include +#include + +#include "kprocesslist.h" + +void BlockingApp::queryBlockingApps(const QString &devicePath) +{ + QProcess *p = new QProcess; + + connect(p, static_cast(&QProcess::error), [=](QProcess::ProcessError) { + emit blockingAppsReady({}); + p->deleteLater(); + }); + + connect(p, static_cast(&QProcess::finished), [=](int /* exitCode */, + QProcess::ExitStatus /* status*/) { + QStringList blockApps; + + const QString out = QString::fromStdString(p->readAll().toStdString()); + const QStringList &pidList = out.split(QRegularExpression(QStringLiteral("\\s+")), QString::SkipEmptyParts); + + const KProcessList::KProcessInfoList procs = KProcessList::processInfoList(); + + QString processName; + for (const QString &pidStr : pidList) { + int pid = pidStr.toInt(); + if (!pid) { + continue; + } + for (const KProcessList::KProcessInfo &proc : procs) { + if (proc.pid() == pid) { + processName = proc.name(); + break; + } + } + if (!blockApps.contains(processName)) { + blockApps << processName; + } + } + blockApps.removeDuplicates(); + emit blockingAppsReady(blockApps); + p->deleteLater(); + }); + p->start(QStringLiteral("lsof"), {QStringLiteral("-t"), devicePath}); + // p.start(QStringLiteral("fuser"), {QStringLiteral("-m"), devicePath}); +} + + +#include "moc_blockingapp.cpp" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,3 +11,6 @@ add_executable(faceicontest faceicontest.cpp) target_link_libraries(faceicontest Qt5::Widgets KF5::CoreAddons) + +add_executable(testBlockingApps testblockingapp.cpp) +target_link_libraries(testBlockingApps Qt5::Widgets KF5::CoreAddons) diff --git a/tests/testblockingapp.cpp b/tests/testblockingapp.cpp new file mode 100644 --- /dev/null +++ b/tests/testblockingapp.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019 Méven Car + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + BlockingApp *blocking = new BlockingApp(); + + const QObject *test = new QObject(); + test->connect(blocking, &BlockingApp::blockingAppsReady, test, [=](const QStringList &apps) { + qDebug() << apps; + }); + + // insert a filename open by tail -f for instance to test + QString fileName = "/home/meven/test-file"; + blocking->queryBlockingApps(fileName); + + return app.exec(); +}