1 | // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
2 | // SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org> |
3 | |
4 | #include "ksandbox.h" |
5 | |
6 | #include <QDebug> |
7 | #include <QFileInfo> |
8 | |
9 | #include <kcoreaddons_debug.h> |
10 | |
11 | bool KSandbox::isInside() |
12 | { |
13 | static const bool isInside = isFlatpak() || isSnap(); |
14 | return isInside; |
15 | } |
16 | |
17 | bool KSandbox::isFlatpak() |
18 | { |
19 | static const bool isFlatpak = QFileInfo::exists(QStringLiteral("/.flatpak-info" )); |
20 | return isFlatpak; |
21 | } |
22 | |
23 | bool KSandbox::isSnap() |
24 | { |
25 | static const bool isSnap = qEnvironmentVariableIsSet(varName: "SNAP" ); |
26 | return isSnap; |
27 | } |
28 | |
29 | bool checkHasFlatpakSpawnPrivileges() |
30 | { |
31 | QFile f(QStringLiteral("/.flatpak-info" )); |
32 | if (!f.open(flags: QIODevice::ReadOnly)) { |
33 | return false; |
34 | } |
35 | |
36 | return f.readAll().contains(bv: "\norg.freedesktop.Flatpak=talk\n" ); |
37 | } |
38 | |
39 | KSandbox::ProcessContext KSandbox::makeHostContext(const QProcess &process) |
40 | { |
41 | if (!KSandbox::isFlatpak()) { |
42 | return {.program: process.program(), .arguments: process.arguments()}; |
43 | } |
44 | |
45 | static const bool hasFlatpakSpawnPrivileges = checkHasFlatpakSpawnPrivileges(); |
46 | if (!hasFlatpakSpawnPrivileges) { |
47 | qCWarning(KCOREADDONS_DEBUG) << "Process execution expects 'org.freedesktop.Flatpak=talk'" << process.program(); |
48 | return {.program: process.program(), .arguments: process.arguments()}; |
49 | } |
50 | |
51 | QStringList args{QStringLiteral("--watch-bus" ), QStringLiteral("--host" ), QStringLiteral("--forward-fd=1" ), QStringLiteral("--forward-fd=2" )}; |
52 | if (!process.workingDirectory().isEmpty()) { |
53 | args << QStringLiteral("--directory=%1" ).arg(a: process.workingDirectory()); |
54 | } |
55 | const auto systemEnvironment = QProcessEnvironment::systemEnvironment().toStringList(); |
56 | const auto processEnvironment = process.processEnvironment().toStringList(); |
57 | for (const auto &variable : processEnvironment) { |
58 | if (systemEnvironment.contains(str: variable)) { |
59 | continue; |
60 | } |
61 | args << QStringLiteral("--env=%1" ).arg(a: variable); |
62 | } |
63 | if (!process.program().isEmpty()) { // some callers are cheeky and pass no program but put it into the arguments (e.g. konsole) |
64 | args << process.program(); |
65 | } |
66 | args += process.arguments(); |
67 | return {QStringLiteral("/usr/bin/flatpak-spawn" ), .arguments: args}; |
68 | } |
69 | |
70 | KCOREADDONS_EXPORT void KSandbox::startHostProcess(QProcess &process, QProcess::OpenMode mode) |
71 | { |
72 | const auto context = makeHostContext(process); |
73 | process.start(program: context.program, arguments: context.arguments, mode); |
74 | } |
75 | |