KCoreAddons

klistopenfilesjob_unix.cpp
1 /*
2  This file is part of the KDE project
3 
4  SPDX-FileCopyrightText: 2010 Jacopo De Simoi <[email protected]>
5  SPDX-FileCopyrightText: 2014 Lukáš Tinkl <[email protected]>
6  SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <[email protected]>
7  SPDX-FileCopyrightText: 2019 David Hallas <[email protected]>
8 
9  SPDX-License-Identifier: LGPL-2.0-only
10 */
11 
12 #include "klistopenfilesjob.h"
13 #include <QDir>
14 #include <QProcess>
15 #include <QRegularExpression>
16 #include <QVector>
17 
18 class KListOpenFilesJobPrivate
19 {
20 public:
21  KListOpenFilesJobPrivate(KListOpenFilesJob *Job, const QDir &Path)
22  : job(Job)
23  , path(Path)
24  {
25  QObject::connect(&lsofProcess, &QProcess::errorOccurred, job, [this](QProcess::ProcessError error) {
26  lsofError(error);
27  });
28 
29  QObject::connect(&lsofProcess,
30  QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
31  job,
32  [this](int exitCode, QProcess::ExitStatus exitStatus) {
33  lsofFinished(exitCode, exitStatus);
34  });
35  }
36  void start()
37  {
38  if (!path.exists()) {
39  emitResult(static_cast<int>(KListOpenFilesJob::Error::DoesNotExist), QObject::tr("Path %1 doesn't exist").arg(path.path()));
40  return;
41  }
42  lsofProcess.start(QStringLiteral("lsof"), {QStringLiteral("-t"), QStringLiteral("+d"), path.path()});
43  }
44  KProcessList::KProcessInfoList getProcessInfoList() const
45  {
46  return processInfoList;
47  }
48 
49 private:
50  void lsofError(QProcess::ProcessError processError)
51  {
52  emitResult(static_cast<int>(KListOpenFilesJob::Error::InternalError), QObject::tr("Failed to execute `lsof' error code %1").arg(processError));
53  }
54  void lsofFinished(int, QProcess::ExitStatus)
55  {
56  if (hasEmittedResult) {
57  return;
58  }
59  const QString out(QString::fromLocal8Bit(lsofProcess.readAll()));
60  const QVector<QStringRef> pidList = out.splitRef(QRegularExpression(QStringLiteral("\\s+")), Qt::SkipEmptyParts);
61  for (const auto &pidStr : pidList) {
62  qint64 pid = pidStr.toLongLong();
63  if (!pid) {
64  continue;
65  }
66  processInfoList << KProcessList::processInfo(pid);
67  }
68  job->emitResult();
69  }
70  void emitResult(int error, const QString &errorText)
71  {
72  if (hasEmittedResult) {
73  return;
74  }
75  job->setError(error);
76  job->setErrorText(errorText);
77  job->emitResult();
78  hasEmittedResult = true;
79  }
80 
81 private:
82  KListOpenFilesJob *job;
83  const QDir path;
84  bool hasEmittedResult = false;
85  QProcess lsofProcess;
86  KProcessList::KProcessInfoList processInfoList;
87 };
88 
89 KListOpenFilesJob::KListOpenFilesJob(const QString &path)
90  : d(new KListOpenFilesJobPrivate(this, path))
91 {
92 }
93 
94 KListOpenFilesJob::~KListOpenFilesJob() = default;
95 
97 {
98  d->start();
99 }
100 
102 {
103  return d->getProcessInfoList();
104 }
105 
106 #include "moc_klistopenfilesjob.cpp"
void start() override
Starts the job asynchronously.
QString tr(const char *sourceText, const char *disambiguation, int n)
void errorOccurred(QProcess::ProcessError error)
QString fromLocal8Bit(const char *str, int size)
void finished(int exitCode)
Provides information about processes that have open files in a given path or subdirectory of path...
SkipEmptyParts
KProcessList::KProcessInfoList processInfoList() const
Returns the list of processes with open files for the requested path.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Apr 9 2021 23:01:38 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.