a-la-karte/src/gamecenter/processscanner.h

58 lines
1.6 KiB
C++

// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2026 A-La-Karte Contributors
#pragma once
#include <QFutureWatcher>
#include <QList>
#include <QObject>
#include <QString>
#include <QTimer>
#include <QtGlobal>
#include <functional>
class ProcessScanner : public QObject
{
Q_OBJECT
public:
explicit ProcessScanner(QObject *parent = nullptr);
struct Match {
uint pid = 0;
QString exe;
QString cmdline;
};
// Find PIDs whose /proc/<pid>/environ contains key=value
static QList<Match> findByEnvironment(const QString &key, const QString &value);
// Find PIDs whose /proc/<pid>/environ contains any of key=value for the provided keys
static QList<Match> findByAnyEnvironment(const QStringList &keys, const QString &value);
// Find PIDs whose /proc/<pid>/cmdline contains the substring
static QList<Match> findByCmdline(const QString &substring);
// Find PIDs whose /proc/<pid>/exe resolves to a path under the given directory
static QList<Match> findByExePath(const QString &dirPrefix);
// Async poll: calls matcher repeatedly until it returns non-empty or timeout.
// Emits found() with matching PIDs, or timedOut() on failure.
void pollUntilFound(std::function<QList<Match>()> matcher, int intervalMs = 500, int timeoutMs = 15000);
void cancel();
Q_SIGNALS:
void found(const QList<ProcessScanner::Match> &matches);
void timedOut();
private:
void startScan();
QTimer m_timer;
QTimer m_deadline;
std::function<QList<Match>()> m_matcher;
quint64 m_generation = 0;
bool m_scanInFlight = false;
quint64 m_scanGeneration = 0;
};