Track argv0 through relaunches

This commit is contained in:
Ilya Fedin 2023-06-16 00:01:45 +04:00 committed by John Preston
parent 32f13c3716
commit 8aee08eaef
2 changed files with 28 additions and 12 deletions

View file

@ -46,6 +46,7 @@ string updaterName;
string workDir; string workDir;
string exeName; string exeName;
string exePath; string exePath;
string argv0;
FILE *_logFile = 0; FILE *_logFile = 0;
void openLog() { void openLog() {
@ -388,6 +389,8 @@ int main(int argc, char *argv[]) {
exeName = argv[i]; exeName = argv[i];
} else if (equal(argv[i], "-exepath") && ++i < argc) { } else if (equal(argv[i], "-exepath") && ++i < argc) {
exePath = argv[i]; exePath = argv[i];
} else if (equal(argv[i], "-argv0") && ++i < argc) {
argv0 = argv[i];
} }
} }
if (exeName.empty() || exeName.find('/') != string::npos) { if (exeName.empty() || exeName.find('/') != string::npos) {
@ -461,15 +464,14 @@ int main(int argc, char *argv[]) {
writeLog("Error: short exe name!"); writeLog("Error: short exe name!");
} }
auto fullBinaryPath = exePath + exeName; const auto fullBinaryPath = exePath + exeName;
const auto path = fullBinaryPath.c_str();
auto values = vector<string>(); auto values = vector<string>();
const auto push = [&](string arg) { const auto push = [&](string arg) {
// Force null-terminated .data() call result. // Force null-terminated .data() call result.
values.push_back(arg + char(0)); values.push_back(arg + char(0));
}; };
push(path); push(!argv0.empty() ? argv0 : fullBinaryPath);
push("-noupdate"); push("-noupdate");
if (autostart) push("-autostart"); if (autostart) push("-autostart");
if (debug) push("-debug"); if (debug) push("-debug");
@ -498,7 +500,7 @@ int main(int argc, char *argv[]) {
writeLog("fork() failed!"); writeLog("fork() failed!");
return 1; return 1;
case 0: case 0:
execv(args[0], args.data()); execv(fullBinaryPath.c_str(), args.data());
return 1; return 1;
} }
} }

View file

@ -69,17 +69,23 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
return false; return false;
} }
const auto binaryPath = (action == UpdaterLaunch::JustRelaunch) const auto justRelaunch = action == UpdaterLaunch::JustRelaunch;
? (cExeDir() + cExeName()) const auto writeProtectedUpdate = action == UpdaterLaunch::PerformUpdate
: (cWriteProtected() && cWriteProtected();
const auto binaryPath = justRelaunch
? QFile::encodeName(cExeDir() + cExeName())
: QFile::encodeName(cWriteProtected()
? (cWorkingDir() + u"tupdates/temp/Updater"_q) ? (cWorkingDir() + u"tupdates/temp/Updater"_q)
: (cExeDir() + u"Updater"_q)); : (cExeDir() + u"Updater"_q));
auto argumentsList = Arguments(); auto argumentsList = Arguments();
if (action == UpdaterLaunch::PerformUpdate && cWriteProtected()) { if (writeProtectedUpdate) {
argumentsList.push("pkexec"); argumentsList.push("pkexec");
} }
argumentsList.push(QFile::encodeName(binaryPath)); argumentsList.push((justRelaunch && !arguments().isEmpty())
? QFile::encodeName(arguments().first())
: binaryPath);
if (cLaunchMode() == LaunchModeAutoStart) { if (cLaunchMode() == LaunchModeAutoStart) {
argumentsList.push("-autostart"); argumentsList.push("-autostart");
@ -95,7 +101,7 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
argumentsList.push(QFile::encodeName(cDataFile())); argumentsList.push(QFile::encodeName(cDataFile()));
} }
if (action == UpdaterLaunch::JustRelaunch) { if (justRelaunch) {
argumentsList.push("-noupdate"); argumentsList.push("-noupdate");
argumentsList.push("-tosettings"); argumentsList.push("-tosettings");
if (customWorkingDir()) { if (customWorkingDir()) {
@ -109,6 +115,10 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
argumentsList.push(QFile::encodeName(cExeName())); argumentsList.push(QFile::encodeName(cExeName()));
argumentsList.push("-exepath"); argumentsList.push("-exepath");
argumentsList.push(QFile::encodeName(cExeDir())); argumentsList.push(QFile::encodeName(cExeDir()));
if (!arguments().isEmpty()) {
argumentsList.push("-argv0");
argumentsList.push(QFile::encodeName(arguments().first()));
}
if (customWorkingDir()) { if (customWorkingDir()) {
argumentsList.push("-workdir_custom"); argumentsList.push("-workdir_custom");
} }
@ -125,11 +135,15 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
pid_t pid = fork(); pid_t pid = fork();
switch (pid) { switch (pid) {
case -1: return false; 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 // pkexec needs an alive parent
if (action == UpdaterLaunch::PerformUpdate && cWriteProtected()) { if (writeProtectedUpdate) {
waitpid(pid, nullptr, 0); waitpid(pid, nullptr, 0);
// launch new version in the same environment // launch new version in the same environment
return launchUpdater(UpdaterLaunch::JustRelaunch); return launchUpdater(UpdaterLaunch::JustRelaunch);