Always wait for updater to exit on Linux
This commit is contained in:
parent
db6c69fa5f
commit
7b4a542890
|
@ -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,42 +395,38 @@ 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)
|
writeLog("No workdir, trying to figure it out");
|
||||||
customWorkingDir = false;
|
struct passwd *pw = getpwuid(getuid());
|
||||||
|
if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
|
||||||
writeLog("No workdir, trying to figure it out");
|
string tryDir = pw->pw_dir + string("/.TelegramDesktop/");
|
||||||
struct passwd *pw = getpwuid(getuid());
|
struct stat statbuf;
|
||||||
if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
|
writeLog("Trying to use '%s' as workDir, getting stat() for tupdates/ready", tryDir.c_str());
|
||||||
string tryDir = pw->pw_dir + string("/.TelegramDesktop/");
|
if (!stat((tryDir + "tupdates/ready").c_str(), &statbuf)) {
|
||||||
struct stat statbuf;
|
writeLog("Stat got");
|
||||||
writeLog("Trying to use '%s' as workDir, getting stat() for tupdates/ready", tryDir.c_str());
|
if (S_ISDIR(statbuf.st_mode)) {
|
||||||
if (!stat((tryDir + "tupdates/ready").c_str(), &statbuf)) {
|
writeLog("It is directory, using home work dir");
|
||||||
writeLog("Stat got");
|
workDir = tryDir;
|
||||||
if (S_ISDIR(statbuf.st_mode)) {
|
|
||||||
writeLog("It is directory, using home work dir");
|
|
||||||
workDir = tryDir;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (workDir.empty()) {
|
|
||||||
workDir = exePath;
|
|
||||||
|
|
||||||
struct stat statbuf;
|
|
||||||
writeLog("Trying to use current as workDir, getting stat() for tupdates/ready");
|
|
||||||
if (!stat("tupdates/ready", &statbuf)) {
|
|
||||||
writeLog("Stat got");
|
|
||||||
if (S_ISDIR(statbuf.st_mode)) {
|
|
||||||
writeLog("It is directory, using current dir");
|
|
||||||
workDir = string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
writeLog("Passed workpath is '%s'", workDir.c_str());
|
|
||||||
}
|
}
|
||||||
update();
|
if (workDir.empty()) {
|
||||||
|
workDir = exePath;
|
||||||
|
|
||||||
|
struct stat statbuf;
|
||||||
|
writeLog("Trying to use current as workDir, getting stat() for tupdates/ready");
|
||||||
|
if (!stat("tupdates/ready", &statbuf)) {
|
||||||
|
writeLog("Stat got");
|
||||||
|
if (S_ISDIR(statbuf.st_mode)) {
|
||||||
|
writeLog("It is directory, using current dir");
|
||||||
|
workDir = string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writeLog("Passed workpath is '%s'", workDir.c_str());
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
|
|
@ -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,31 +51,30 @@ 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 (cStartInTray()) {
|
|
||||||
argumentsList.push_back("-startintray");
|
|
||||||
}
|
|
||||||
if (cDataFile() != u"data"_q) {
|
|
||||||
argumentsList.push_back("-key");
|
|
||||||
argumentsList.push_back(cDataFile().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (justRelaunch) {
|
if (justRelaunch) {
|
||||||
|
if (cLaunchMode() == LaunchModeAutoStart) {
|
||||||
|
argumentsList.push_back("-autostart");
|
||||||
|
}
|
||||||
|
if (cStartInTray()) {
|
||||||
|
argumentsList.push_back("-startintray");
|
||||||
|
}
|
||||||
|
if (cDataFile() != u"data"_q) {
|
||||||
|
argumentsList.push_back("-key");
|
||||||
|
argumentsList.push_back(cDataFile().toStdString());
|
||||||
|
}
|
||||||
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,13 +96,24 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
|
||||||
Logs::closeMain();
|
Logs::closeMain();
|
||||||
CrashReports::Finish();
|
CrashReports::Finish();
|
||||||
|
|
||||||
// pkexec needs an alive parent
|
if (justRelaunch) {
|
||||||
if (writeProtectedUpdate) {
|
return GLib::spawn_async(
|
||||||
|
initialWorkingDir().toStdString(),
|
||||||
|
argumentsList,
|
||||||
|
std::nullopt,
|
||||||
|
GLib::SpawnFlags::FILE_AND_ARGV_ZERO_,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
} else {
|
||||||
if (!GLib::spawn_sync(
|
if (!GLib::spawn_sync(
|
||||||
initialWorkingDir().toStdString(),
|
|
||||||
argumentsList,
|
argumentsList,
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
GLib::SpawnFlags::SEARCH_PATH_,
|
// 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,
|
nullptr,
|
||||||
|
@ -120,18 +121,8 @@ bool Launcher::launchUpdater(UpdaterLaunch action) {
|
||||||
nullptr)) {
|
nullptr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// launch new version in the same environment
|
|
||||||
return launchUpdater(UpdaterLaunch::JustRelaunch);
|
return launchUpdater(UpdaterLaunch::JustRelaunch);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLib::spawn_async(
|
|
||||||
initialWorkingDir().toStdString(),
|
|
||||||
argumentsList,
|
|
||||||
std::nullopt,
|
|
||||||
GLib::SpawnFlags::FILE_AND_ARGV_ZERO_,
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue
Block a user