From 5f3745351f4df30b50b3a9693f0f617acb2476e8 Mon Sep 17 00:00:00 2001 From: Robert Knight Date: Sun, 21 Aug 2011 21:51:29 +0100 Subject: [PATCH] Get launching of the main update installer process working in the case where elevation is not required. * Add ProcessUtils::currentProcessPath() to get the path to the current application and add a Linux implementation. * Implement ProcessUtils::runAsync() on Unix using fork/execve. * Setup updater to run the main installation phase with the correct arguments. * Add '.zip' to the package name to get the path of the package file. --- src/ProcessUtils.cpp | 32 ++++++++++++++++++++++++++++++++ src/ProcessUtils.h | 2 ++ src/UpdateInstaller.cpp | 13 +++++++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/ProcessUtils.cpp b/src/ProcessUtils.cpp index 36d10f1..37e5825 100644 --- a/src/ProcessUtils.cpp +++ b/src/ProcessUtils.cpp @@ -1,10 +1,13 @@ #include "ProcessUtils.h" +#include "FileOps.h" #include "Platform.h" #include "StringUtils.h" #include "Log.h" #include +#include +#include #ifdef PLATFORM_WINDOWS #include @@ -186,6 +189,25 @@ void ProcessUtils::runElevatedWindows(const std::string& executable, void ProcessUtils::runAsyncUnix(const std::string& executable, const std::list& args) { + if (fork() == 0) + { + // in child process + char** argBuffer = new char*[args.size() + 1]; + argBuffer[0] = strdup(executable.c_str()); + int i = 1; + for (std::list::const_iterator iter = args.begin(); iter != args.end(); iter++) + { + argBuffer[i] = strdup(iter->c_str()); + ++i; + } + argBuffer[i] = 0; + + if (execve(executable.c_str(),argBuffer,environ) == -1) + { + LOG(Error,"error starting child: " + std::string(strerror(errno))); + exit(1); + } + } } #endif @@ -195,3 +217,13 @@ void ProcessUtils::runAsyncWindows(const std::string& executable, { } #endif + +std::string ProcessUtils::currentProcessPath() +{ +#ifdef PLATFORM_LINUX + std::string path = FileOps::canonicalPath("/proc/self/exe"); + LOG(Info,"Current process path " + path); + return path; +#endif +} + diff --git a/src/ProcessUtils.h b/src/ProcessUtils.h index 00a9ebc..9d3134e 100644 --- a/src/ProcessUtils.h +++ b/src/ProcessUtils.h @@ -6,6 +6,8 @@ class ProcessUtils { public: + static std::string currentProcessPath(); + static void runAsync(const std::string& executable, const std::list& args); diff --git a/src/UpdateInstaller.cpp b/src/UpdateInstaller.cpp index 0582162..47865c7 100644 --- a/src/UpdateInstaller.cpp +++ b/src/UpdateInstaller.cpp @@ -51,8 +51,17 @@ void UpdateInstaller::run() throw () LOG(Info,"Waiting for main app process to finish"); ProcessUtils::waitForProcess(m_waitPid); - std::string updaterPath; + std::string updaterPath = ProcessUtils::currentProcessPath(); std::list args; + args.push_back("--mode"); + args.push_back("main"); + args.push_back("--install-dir"); + args.push_back(m_installDir); + args.push_back("--package-dir"); + args.push_back(m_packageDir); + args.push_back("--script"); + args.push_back(m_script->path()); + if (!checkAccess()) { LOG(Info,"Insufficient rights to install app to " + m_installDir + " requesting elevation"); @@ -140,7 +149,7 @@ void UpdateInstaller::revert() void UpdateInstaller::installFile(const UpdateScriptFile& file) { - std::string packageFile = m_installDir + '/' + file.package; + std::string packageFile = m_packageDir + '/' + file.package + ".zip"; std::string destPath = m_installDir + '/' + file.path; std::string target = file.linkTarget;