From 8aee08eaef61cbb426567b1b5753a1eeda420b9b Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Fri, 16 Jun 2023 00:01:45 +0400 Subject: [PATCH] Track argv0 through relaunches --- Telegram/SourceFiles/_other/updater_linux.cpp | 10 ++++--- .../platform/linux/launcher_linux.cpp | 30 ++++++++++++++----- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Telegram/SourceFiles/_other/updater_linux.cpp b/Telegram/SourceFiles/_other/updater_linux.cpp index 40e887c52..f286b05be 100644 --- a/Telegram/SourceFiles/_other/updater_linux.cpp +++ b/Telegram/SourceFiles/_other/updater_linux.cpp @@ -46,6 +46,7 @@ string updaterName; string workDir; string exeName; string exePath; +string argv0; FILE *_logFile = 0; void openLog() { @@ -388,6 +389,8 @@ int main(int argc, char *argv[]) { exeName = argv[i]; } else if (equal(argv[i], "-exepath") && ++i < argc) { exePath = argv[i]; + } else if (equal(argv[i], "-argv0") && ++i < argc) { + argv0 = argv[i]; } } if (exeName.empty() || exeName.find('/') != string::npos) { @@ -461,15 +464,14 @@ int main(int argc, char *argv[]) { writeLog("Error: short exe name!"); } - auto fullBinaryPath = exePath + exeName; - const auto path = fullBinaryPath.c_str(); + const auto fullBinaryPath = exePath + exeName; auto values = vector(); const auto push = [&](string arg) { // Force null-terminated .data() call result. values.push_back(arg + char(0)); }; - push(path); + push(!argv0.empty() ? argv0 : fullBinaryPath); push("-noupdate"); if (autostart) push("-autostart"); if (debug) push("-debug"); @@ -498,7 +500,7 @@ int main(int argc, char *argv[]) { writeLog("fork() failed!"); return 1; case 0: - execv(args[0], args.data()); + execv(fullBinaryPath.c_str(), args.data()); return 1; } } diff --git a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp index 9662cf427..e5ae4efb5 100644 --- a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp @@ -69,17 +69,23 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { return false; } - const auto binaryPath = (action == UpdaterLaunch::JustRelaunch) - ? (cExeDir() + cExeName()) - : (cWriteProtected() + const auto justRelaunch = action == UpdaterLaunch::JustRelaunch; + const auto writeProtectedUpdate = action == UpdaterLaunch::PerformUpdate + && cWriteProtected(); + + const auto binaryPath = justRelaunch + ? QFile::encodeName(cExeDir() + cExeName()) + : QFile::encodeName(cWriteProtected() ? (cWorkingDir() + u"tupdates/temp/Updater"_q) : (cExeDir() + u"Updater"_q)); auto argumentsList = Arguments(); - if (action == UpdaterLaunch::PerformUpdate && cWriteProtected()) { + if (writeProtectedUpdate) { argumentsList.push("pkexec"); } - argumentsList.push(QFile::encodeName(binaryPath)); + argumentsList.push((justRelaunch && !arguments().isEmpty()) + ? QFile::encodeName(arguments().first()) + : binaryPath); if (cLaunchMode() == LaunchModeAutoStart) { argumentsList.push("-autostart"); @@ -95,7 +101,7 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { argumentsList.push(QFile::encodeName(cDataFile())); } - if (action == UpdaterLaunch::JustRelaunch) { + if (justRelaunch) { argumentsList.push("-noupdate"); argumentsList.push("-tosettings"); if (customWorkingDir()) { @@ -109,6 +115,10 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { argumentsList.push(QFile::encodeName(cExeName())); argumentsList.push("-exepath"); argumentsList.push(QFile::encodeName(cExeDir())); + if (!arguments().isEmpty()) { + argumentsList.push("-argv0"); + argumentsList.push(QFile::encodeName(arguments().first())); + } if (customWorkingDir()) { argumentsList.push("-workdir_custom"); } @@ -125,11 +135,15 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { pid_t pid = fork(); switch (pid) { case -1: return false; - case 0: execvp(args[0], args); return false; + case 0: + execvp( + writeProtectedUpdate ? args[0] : binaryPath.constData(), + args); + return false; } // pkexec needs an alive parent - if (action == UpdaterLaunch::PerformUpdate && cWriteProtected()) { + if (writeProtectedUpdate) { waitpid(pid, nullptr, 0); // launch new version in the same environment return launchUpdater(UpdaterLaunch::JustRelaunch);