Always wait for updater to exit on Linux

This commit is contained in:
Ilya Fedin 2023-08-14 15:42:07 +04:00 committed by John Preston
parent db6c69fa5f
commit 7b4a542890
2 changed files with 60 additions and 140 deletions

View file

@ -47,7 +47,6 @@ 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() {
@ -357,40 +356,17 @@ string CurrentExecutablePath(int argc, char *argv[]) {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
bool needupdate = true;
bool autostart = false;
bool debug = false;
bool tosettings = false;
bool startintray = false;
bool customWorkingDir = false;
char *key = 0;
char *workdir = 0;
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
if (equal(argv[i], "-noupdate")) { if (equal(argv[i], "-debug")) {
needupdate = false; _debug = true;
} else if (equal(argv[i], "-autostart")) {
autostart = true;
} else if (equal(argv[i], "-debug")) {
debug = _debug = true;
} else if (equal(argv[i], "-startintray")) {
startintray = true;
} else if (equal(argv[i], "-tosettings")) {
tosettings = true;
} else if (equal(argv[i], "-workdir_custom")) {
customWorkingDir = true;
} else if (equal(argv[i], "-writeprotected")) { } else if (equal(argv[i], "-writeprotected")) {
writeprotected = true; writeprotected = true;
} else if (equal(argv[i], "-key") && ++i < argc) {
key = argv[i];
} else if (equal(argv[i], "-workpath") && ++i < argc) { } else if (equal(argv[i], "-workpath") && ++i < argc) {
workDir = workdir = argv[i]; workDir = argv[i];
} else if (equal(argv[i], "-exename") && ++i < argc) { } else if (equal(argv[i], "-exename") && ++i < argc) {
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) {
@ -402,8 +378,6 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
writeLog("Argument: '%s'", argv[i]); writeLog("Argument: '%s'", argv[i]);
} }
if (needupdate) writeLog("Need to update!");
if (autostart) writeLog("From autostart!");
if (writeprotected) writeLog("Write Protected folder!"); if (writeprotected) writeLog("Write Protected folder!");
updaterName = CurrentExecutablePath(argc, argv); updaterName = CurrentExecutablePath(argc, argv);
@ -421,10 +395,7 @@ int main(int argc, char *argv[]) {
exePath = updaterDir; exePath = updaterDir;
writeLog("Using updater binary dir.", exePath.c_str()); writeLog("Using updater binary dir.", exePath.c_str());
} }
if (needupdate) {
if (workDir.empty()) { // old app launched, update prepared in tupdates/ready (not in tupdates/temp) if (workDir.empty()) { // old app launched, update prepared in tupdates/ready (not in tupdates/temp)
customWorkingDir = false;
writeLog("No workdir, trying to figure it out"); writeLog("No workdir, trying to figure it out");
struct passwd *pw = getpwuid(getuid()); struct passwd *pw = getpwuid(getuid());
if (pw && pw->pw_dir && strlen(pw->pw_dir)) { if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
@ -456,7 +427,6 @@ int main(int argc, char *argv[]) {
writeLog("Passed workpath is '%s'", workDir.c_str()); writeLog("Passed workpath is '%s'", workDir.c_str());
} }
update(); update();
}
} else { } else {
writeLog("Error: bad exe name!"); writeLog("Error: bad exe name!");
} }
@ -464,48 +434,7 @@ int main(int argc, char *argv[]) {
writeLog("Error: short exe name!"); writeLog("Error: short exe name!");
} }
const auto fullBinaryPath = exePath + exeName; writeLog("Closing log and quitting..");
auto values = vector<string>();
const auto push = [&](string arg) {
// Force null-terminated .data() call result.
values.push_back(arg + char(0));
};
push(!argv0.empty() ? argv0 : fullBinaryPath);
push("-noupdate");
if (autostart) push("-autostart");
if (debug) push("-debug");
if (startintray) push("-startintray");
if (tosettings) push("-tosettings");
if (key) {
push("-key");
push(key);
}
if (customWorkingDir && workdir) {
push("-workdir");
push(workdir);
}
auto args = vector<char*>();
for (auto &arg : values) {
args.push_back(arg.data());
}
args.push_back(nullptr);
// let the parent launch instead
if (!writeprotected) {
pid_t pid = fork();
switch (pid) {
case -1:
writeLog("fork() failed!");
return 1;
case 0:
execv(fullBinaryPath.c_str(), args.data());
return 1;
}
}
writeLog("Executed Telegram, closing log and quitting..");
closeLog(); closeLog();
return 0; return 0;

View file

@ -43,8 +43,6 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
} }
const auto justRelaunch = action == UpdaterLaunch::JustRelaunch; const auto justRelaunch = action == UpdaterLaunch::JustRelaunch;
const auto writeProtectedUpdate = action == UpdaterLaunch::PerformUpdate
&& cWriteProtected();
const auto binaryPath = justRelaunch const auto binaryPath = justRelaunch
? (cExeDir() + cExeName()).toStdString() ? (cExeDir() + cExeName()).toStdString()
@ -53,22 +51,23 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
: (cExeDir() + u"Updater"_q)).toStdString(); : (cExeDir() + u"Updater"_q)).toStdString();
std::vector<std::string> argumentsList; std::vector<std::string> argumentsList;
if (writeProtectedUpdate) { if (justRelaunch) {
argumentsList.push_back("pkexec");
argumentsList.push_back("--keep-cwd");
} else {
argumentsList.push_back(binaryPath); argumentsList.push_back(binaryPath);
} else if (cWriteProtected()) {
argumentsList.push_back("pkexec");
} }
argumentsList.push_back((justRelaunch && !arguments().isEmpty()) argumentsList.push_back((justRelaunch && !arguments().isEmpty())
? arguments().first().toStdString() ? arguments().first().toStdString()
: binaryPath); : binaryPath);
if (cLaunchMode() == LaunchModeAutoStart) {
argumentsList.push_back("-autostart");
}
if (Logs::DebugEnabled()) { if (Logs::DebugEnabled()) {
argumentsList.push_back("-debug"); argumentsList.push_back("-debug");
} }
if (justRelaunch) {
if (cLaunchMode() == LaunchModeAutoStart) {
argumentsList.push_back("-autostart");
}
if (cStartInTray()) { if (cStartInTray()) {
argumentsList.push_back("-startintray"); argumentsList.push_back("-startintray");
} }
@ -76,8 +75,6 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
argumentsList.push_back("-key"); argumentsList.push_back("-key");
argumentsList.push_back(cDataFile().toStdString()); argumentsList.push_back(cDataFile().toStdString());
} }
if (justRelaunch) {
argumentsList.push_back("-noupdate"); argumentsList.push_back("-noupdate");
argumentsList.push_back("-tosettings"); argumentsList.push_back("-tosettings");
if (customWorkingDir()) { if (customWorkingDir()) {
@ -91,13 +88,6 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
argumentsList.push_back(cExeName().toStdString()); argumentsList.push_back(cExeName().toStdString());
argumentsList.push_back("-exepath"); argumentsList.push_back("-exepath");
argumentsList.push_back(cExeDir().toStdString()); argumentsList.push_back(cExeDir().toStdString());
if (!arguments().isEmpty()) {
argumentsList.push_back("-argv0");
argumentsList.push_back(arguments().first().toStdString());
}
if (customWorkingDir()) {
argumentsList.push_back("-workdir_custom");
}
if (cWriteProtected()) { if (cWriteProtected()) {
argumentsList.push_back("-writeprotected"); argumentsList.push_back("-writeprotected");
} }
@ -106,24 +96,7 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
Logs::closeMain(); Logs::closeMain();
CrashReports::Finish(); CrashReports::Finish();
// pkexec needs an alive parent if (justRelaunch) {
if (writeProtectedUpdate) {
if (!GLib::spawn_sync(
initialWorkingDir().toStdString(),
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 GLib::spawn_async( return GLib::spawn_async(
initialWorkingDir().toStdString(), initialWorkingDir().toStdString(),
argumentsList, argumentsList,
@ -132,6 +105,24 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
nullptr, nullptr,
nullptr, nullptr,
nullptr); nullptr);
} else {
if (!GLib::spawn_sync(
argumentsList,
std::nullopt,
// if the spawn is sync, working directory is not set
// and GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_ is set,
// it goes through an optimized code path
GLib::SpawnFlags::SEARCH_PATH_
| GLib::SpawnFlags::LEAVE_DESCRIPTORS_OPEN_,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr)) {
return false;
}
return launchUpdater(UpdaterLaunch::JustRelaunch);
}
} }
} // namespace } // namespace