From 949c486cacf3b9be56acc49a6245286b2457d247 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Mon, 14 Aug 2023 04:57:05 +0400 Subject: [PATCH] Use a higher-level API for restarts/updates on Linux This gets rid of the custom arguments container --- .../platform/linux/launcher_linux.cpp | 117 +++++++----------- 1 file changed, 46 insertions(+), 71 deletions(-) diff --git a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp index e5ae4efb5..a19cb109d 100644 --- a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp @@ -12,38 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "webview/platform/linux/webview_linux_webkitgtk.h" #include +#include -#include -#include -#include -#include -#include -#include -#include +using namespace gi::repository; namespace Platform { -namespace { - -class Arguments { -public: - void push(QByteArray argument) { - argument.append(char(0)); - _argumentValues.push_back(argument); - _arguments.push_back(_argumentValues.back().data()); - } - - char **result() { - _arguments.push_back(nullptr); - return _arguments.data(); - } - -private: - std::vector _argumentValues; - std::vector _arguments; - -}; - -} // namespace Launcher::Launcher(int argc, char *argv[]) : Core::Launcher(argc, argv) { @@ -74,82 +47,84 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { && cWriteProtected(); const auto binaryPath = justRelaunch - ? QFile::encodeName(cExeDir() + cExeName()) - : QFile::encodeName(cWriteProtected() + ? (cExeDir() + cExeName()).toStdString() + : (cWriteProtected() ? (cWorkingDir() + u"tupdates/temp/Updater"_q) - : (cExeDir() + u"Updater"_q)); + : (cExeDir() + u"Updater"_q)).toStdString(); - auto argumentsList = Arguments(); - if (writeProtectedUpdate) { - argumentsList.push("pkexec"); - } - argumentsList.push((justRelaunch && !arguments().isEmpty()) - ? QFile::encodeName(arguments().first()) + std::vector argumentsList; + argumentsList.push_back(writeProtectedUpdate ? "pkexec" : binaryPath); + argumentsList.push_back((justRelaunch && !arguments().isEmpty()) + ? arguments().first().toStdString() : binaryPath); if (cLaunchMode() == LaunchModeAutoStart) { - argumentsList.push("-autostart"); + argumentsList.push_back("-autostart"); } if (Logs::DebugEnabled()) { - argumentsList.push("-debug"); + argumentsList.push_back("-debug"); } if (cStartInTray()) { - argumentsList.push("-startintray"); + argumentsList.push_back("-startintray"); } if (cDataFile() != u"data"_q) { - argumentsList.push("-key"); - argumentsList.push(QFile::encodeName(cDataFile())); + argumentsList.push_back("-key"); + argumentsList.push_back(cDataFile().toStdString()); } if (justRelaunch) { - argumentsList.push("-noupdate"); - argumentsList.push("-tosettings"); + argumentsList.push_back("-noupdate"); + argumentsList.push_back("-tosettings"); if (customWorkingDir()) { - argumentsList.push("-workdir"); - argumentsList.push(QFile::encodeName(cWorkingDir())); + argumentsList.push_back("-workdir"); + argumentsList.push_back(cWorkingDir().toStdString()); } } else { - argumentsList.push("-workpath"); - argumentsList.push(QFile::encodeName(cWorkingDir())); - argumentsList.push("-exename"); - argumentsList.push(QFile::encodeName(cExeName())); - argumentsList.push("-exepath"); - argumentsList.push(QFile::encodeName(cExeDir())); + argumentsList.push_back("-workpath"); + argumentsList.push_back(cWorkingDir().toStdString()); + argumentsList.push_back("-exename"); + argumentsList.push_back(cExeName().toStdString()); + argumentsList.push_back("-exepath"); + argumentsList.push_back(cExeDir().toStdString()); if (!arguments().isEmpty()) { - argumentsList.push("-argv0"); - argumentsList.push(QFile::encodeName(arguments().first())); + argumentsList.push_back("-argv0"); + argumentsList.push_back(arguments().first().toStdString()); } if (customWorkingDir()) { - argumentsList.push("-workdir_custom"); + argumentsList.push_back("-workdir_custom"); } if (cWriteProtected()) { - argumentsList.push("-writeprotected"); + argumentsList.push_back("-writeprotected"); } } Logs::closeMain(); CrashReports::Finish(); - const auto args = argumentsList.result(); - - pid_t pid = fork(); - switch (pid) { - case -1: return false; - case 0: - execvp( - writeProtectedUpdate ? args[0] : binaryPath.constData(), - args); - return false; - } - // pkexec needs an alive parent if (writeProtectedUpdate) { - waitpid(pid, nullptr, 0); + if (!GLib::spawn_sync( + argumentsList, + std::nullopt, + GLib::SpawnFlags::SEARCH_PATH_, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr)) { + return false; + } // launch new version in the same environment return launchUpdater(UpdaterLaunch::JustRelaunch); } - return true; + return GLib::spawn_async( + argumentsList, + std::nullopt, + GLib::SpawnFlags::FILE_AND_ARGV_ZERO_, + nullptr, + nullptr, + nullptr); } } // namespace