QtPass 2.0.0
Developer documentation
Loading...
Searching...
No Matches
executor.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2// SPDX-License-Identifier: GPL-3.0-or-later
9#ifndef SRC_EXECUTOR_H_
10#define SRC_EXECUTOR_H_
11
12#include <QObject>
13#include <QProcess>
14#include <QProcessEnvironment>
15#include <QQueue>
16#include <atomic>
17#include <optional>
18#include <utility>
19
30
31class Executor : public QObject {
32 Q_OBJECT
33
40 int id;
42 QString app;
44 QStringList args;
46 QString input;
55 QString workingDir;
56 };
57
62 QQueue<ExecQueueItem> m_execQueue;
64 QProcess m_process;
69 bool running{false};
80 void executeNext();
84 void postDrainedIfIdle();
88 bool m_drainCheckPosted = false;
100 static void startProcess(QProcess &process, const QString &app,
101 const QStringList &args);
110 auto collectOutput(const ExecQueueItem &item, int exitCode)
111 -> std::pair<QString, QString>;
134 static auto runBlocking(QProcess &process, const QString &app,
135 const QStringList &args, const QString &input,
136 QString *process_out, QString *process_err,
137 const std::atomic_bool *cancel = nullptr,
138 int timeoutMs = -1) -> int;
139
140public:
145 explicit Executor(QObject *parent = nullptr);
146
155 void execute(int id, const QString &app, const QStringList &args,
156 bool readStdout, bool readStderr = true);
157
167 void execute(int id, const QString &workDir, const QString &app,
168 const QStringList &args, bool readStdout,
169 bool readStderr = true);
170
180 void execute(int id, const QString &app, const QStringList &args,
181 QString input = QString(), bool readStdout = false,
182 bool readStderr = true);
183
194 void execute(int id, const QString &workDir, const QString &app,
195 const QStringList &args, QString input = QString(),
196 bool readStdout = false, bool readStderr = true);
197
207 [[nodiscard]] static auto executeBlocking(const QString &app,
208 const QStringList &args,
209 const QString &input = QString(),
210 QString *process_out = nullptr,
211 QString *process_err = nullptr)
212 -> int;
213
246 [[nodiscard]] static auto executeBlocking(
247 QProcess &process, const QString &app, const QStringList &args,
248 const QString &input = QString(), QString *process_out = nullptr,
249 QString *process_err = nullptr, const std::atomic_bool *cancel = nullptr,
250 int timeoutMs = -1) -> int;
251
260 [[nodiscard]] static auto
261 executeBlocking(const QString &app, const QStringList &args,
262 QString *process_out, QString *process_err = nullptr) -> int;
263
273 [[nodiscard]] static auto
274 executeBlocking(const QProcessEnvironment &env, const QString &app,
275 const QStringList &args, QString *process_out = nullptr,
276 QString *process_err = nullptr) -> int;
277
289 static auto resolveExecutable(const QString &app) -> QString;
290
303 static void detachFromTerminal(QProcess &process);
304
315 static void setChildUmask(int mask);
316
321 [[nodiscard]] static auto childUmask() -> int;
322
328 struct WslCommand {
337 QString launcher;
342 QStringList options;
344 QString command;
356 auto argv(const QStringList &args) const -> QStringList;
362 auto with(const QString &program) const -> WslCommand;
363 };
364
380 static auto parseWslCommand(const QString &app) -> std::optional<WslCommand>;
381
389 static auto wslExecArgs(const QString &command, const QStringList &args)
390 -> QStringList;
391
402 static auto translatePathForWsl(const QString &path, const QString &exe)
403 -> QString;
404
409 void setEnvironment(const QProcessEnvironment &env);
414 auto environment() const -> QProcessEnvironment;
415
420 auto cancelNext() -> int;
425 auto isIdle() const -> bool { return !running && m_execQueue.isEmpty(); }
426
437 auto hasQueued(int id) const -> bool {
438 for (const ExecQueueItem &item : m_execQueue) {
439 if (item.id == id) {
440 return true;
441 }
442 }
443 return false;
444 }
445
446private slots:
457 void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
458signals:
463 void drained();
473 void finished(int id, int exitCode, const QString &output,
474 const QString &errout);
479 void starting();
495 void dequeuing(int id, bool completes);
505 void error(int id, int exitCode, const QString &output,
506 const QString &errout);
507};
508
509#endif // SRC_EXECUTOR_H_
void postDrainedIfIdle()
Definition executor.cpp:503
void dequeuing(int id, bool completes)
Emitted, synchronously, when the queue's head leaves it: just before it is started,...
QQueue< ExecQueueItem > m_execQueue
Commands waiting to run, head first. The head stays queued while it runs and is dequeued in onProcess...
Definition executor.h:62
auto isIdle() const -> bool
Whether no command is running and nothing is queued.
Definition executor.h:425
static auto childUmask() -> int
The umask setChildUmask() set.
Definition executor.cpp:67
static auto executeBlocking(const QString &app, const QStringList &args, const QString &input=QString(), QString *process_out=nullptr, QString *process_err=nullptr) -> int
Run a command synchronously and return its exit code.
Definition executor.cpp:422
static auto translatePathForWsl(const QString &path, const QString &exe) -> QString
Translate a native path for a WSL-routed executable.
Definition executor.cpp:177
auto environment() const -> QProcessEnvironment
Return the environment passed to child processes.
Definition executor.cpp:457
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
Finish the running item when its process exits.
Definition executor.cpp:478
int m_pendingErrors
error()s of failed starts posted but not delivered yet.
Definition executor.h:86
auto collectOutput(const ExecQueueItem &item, int exitCode) -> std::pair< QString, QString >
Read what a finished process produced, according to the queue item's readStdout/readStderr flags; std...
Definition executor.cpp:522
bool m_drainCheckPosted
A drained() check is posted and not run yet.
Definition executor.h:88
auto hasQueued(int id) const -> bool
Whether a command with process id id is queued or running.
Definition executor.h:437
static void startProcess(QProcess &process, const QString &app, const QStringList &args)
Start process running app, handling the "wsl " prefix once for both the queued and the blocking path.
Definition executor.cpp:69
void execute(int id, const QString &app, const QStringList &args, bool readStdout, bool readStderr=true)
Queue a command without stdin input.
Definition executor.cpp:264
static auto resolveExecutable(const QString &app) -> QString
The one rule for turning a configured executable into what runs.
Definition executor.cpp:86
void drained()
Emitted once the last queued item is done and nothing runs or waits any more (isIdle()),...
void error(int id, int exitCode, const QString &output, const QString &errout)
Emitted instead of finished() when a queued process could not be started, had no executable configure...
static auto wslExecArgs(const QString &command, const QStringList &args) -> QStringList
Build the wsl.exe argument list that runs command directly.
Definition executor.cpp:172
static void setChildUmask(int mask)
The umask every child QtPass starts gets, as pass sets its own.
Definition executor.cpp:65
Executor(QObject *parent=nullptr)
Construct an Executor with an optional parent QObject.
Definition executor.cpp:29
bool running
Whether the head of the queue has been started (or is being dequeued, see dequeuing()) and has not fi...
Definition executor.h:69
void finished(int id, int exitCode, const QString &output, const QString &errout)
Emitted when a queued process exits normally, whatever its exit code; a non-zero code is the receiver...
void starting()
Emitted just before a queued process is started; the main window shows the busy indicator on it.
void setEnvironment(const QProcessEnvironment &env)
Set the environment passed to all child processes.
Definition executor.cpp:453
static auto runBlocking(QProcess &process, const QString &app, const QStringList &args, const QString &input, QString *process_out, QString *process_err, const std::atomic_bool *cancel=nullptr, int timeoutMs=-1) -> int
Shared blocking run: start process, optionally feed input on stdin, wait, and capture stdout/stderr....
Definition executor.cpp:382
static void detachFromTerminal(QProcess &process)
Make process start its child without a controlling terminal.
Definition executor.cpp:34
void executeNext()
Start the head of the queue unless something runs or the queue is empty.
Definition executor.cpp:192
static auto parseWslCommand(const QString &app) -> std::optional< WslCommand >
Parse a configured executable as a WSL command.
Definition executor.cpp:114
auto cancelNext() -> int
Cancel the next queued command without executing it.
Definition executor.cpp:462
QProcess m_process
The one process object; every queued command reuses it.
Definition executor.h:64
Execution queue item for non-interactive ordered execution.
Definition executor.h:38
bool readStdout
Whether stdout is captured for finished().
Definition executor.h:48
QString workingDir
Working directory to start in; empty for the current one.
Definition executor.h:55
QString input
Data written to the process's stdin, then closed.
Definition executor.h:46
int id
Identifier the caller gave; echoed in finished()/error().
Definition executor.h:40
bool readStderr
Whether stderr is captured; it is read regardless when the process exits non-zero.
Definition executor.h:53
QStringList args
Arguments for the executable.
Definition executor.h:44
QString app
Executable as configured; resolved when started.
Definition executor.h:42
A configured executable that runs a Linux program through WSL.
Definition executor.h:328
auto argv(const QStringList &args) const -> QStringList
Arguments for launcher that run command with args.
Definition executor.cpp:106
QString command
The Linux program to run, looked up on the WSL PATH.
Definition executor.h:344
QString launcher
What to start.
Definition executor.h:337
QStringList options
wsl.exe options that go before the program (-d Debian, -u me), without any -e/--exec: argv() always a...
Definition executor.h:342
auto with(const QString &program) const -> WslCommand
The same launcher and options running another program.
Definition executor.cpp:110