From 3e34124e68734fc1d51a47665f3455f21f2906d1 Mon Sep 17 00:00:00 2001 From: Maarten ter Huurne Date: Thu, 7 Aug 2014 16:48:30 +0200 Subject: [PATCH] Added Launcher class Currently the launched application is exec-ed from deep within the menu code. This means a lot of destructors are never run and as a result for example file descriptors from the menu remain open in the launched process. This is a first step to move the launch invocation from a deep call stack to the top level. --- src/Makefile.am | 2 +- src/gmenu2x.cpp | 5 ++++- src/launcher.cpp | 33 +++++++++++++++++++++++++++++++++ src/launcher.h | 20 ++++++++++++++++++++ src/linkapp.cpp | 16 +++++++++++----- 5 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 src/launcher.cpp create mode 100644 src/launcher.h diff --git a/src/Makefile.am b/src/Makefile.am index c5ad333..f5cc34c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ bin_PROGRAMS = gmenu2x gmenu2x_SOURCES = font.cpp cpu.cpp dirdialog.cpp filedialog.cpp \ filelister.cpp gmenu2x.cpp iconbutton.cpp imagedialog.cpp inputdialog.cpp \ - inputmanager.cpp linkapp.cpp link.cpp \ + inputmanager.cpp linkapp.cpp link.cpp launcher.cpp \ menu.cpp menusettingbool.cpp menusetting.cpp menusettingdir.cpp \ menusettingfile.cpp menusettingimage.cpp menusettingint.cpp \ menusettingmultistring.cpp menusettingrgba.cpp menusettingstring.cpp \ diff --git a/src/gmenu2x.cpp b/src/gmenu2x.cpp index df186bb..da7f8d3 100644 --- a/src/gmenu2x.cpp +++ b/src/gmenu2x.cpp @@ -30,6 +30,7 @@ #include "helppopup.h" #include "iconbutton.h" #include "inputdialog.h" +#include "launcher.h" #include "linkapp.h" #include "mediamonitor.h" #include "menu.h" @@ -648,7 +649,9 @@ void GMenu2X::explorer() { #ifdef ENABLE_CPUFREQ setClock(cpuFreqAppDefault); #endif - execlp("/bin/sh","/bin/sh","-c",command.c_str(),NULL); + + Launcher launcher(vector { "/bin/sh", "-c", command }); + launcher.exec(); //if execution continues then something went wrong and as we already called SDL_Quit we cannot continue //try relaunching gmenu2x diff --git a/src/launcher.cpp b/src/launcher.cpp new file mode 100644 index 0000000..85ebe9c --- /dev/null +++ b/src/launcher.cpp @@ -0,0 +1,33 @@ +#include "launcher.h" + +#include "debug.h" + +#include +#include +#include + +using namespace std; + + +Launcher::Launcher(vector const& commandLine) + : commandLine(commandLine) +{ +} + +Launcher::Launcher(vector && commandLine) + : commandLine(commandLine) +{ +} + +void Launcher::exec() +{ + vector args; + args.reserve(commandLine.size() + 1); + for (auto arg : commandLine) { + args.push_back(arg.c_str()); + } + args.push_back(nullptr); + execvp(commandLine[0].c_str(), (char* const*)&args[0]); + WARNING("Failed to exec '%s': %s\n", + commandLine[0].c_str(), strerror(errno)); +} diff --git a/src/launcher.h b/src/launcher.h new file mode 100644 index 0000000..0c99b28 --- /dev/null +++ b/src/launcher.h @@ -0,0 +1,20 @@ +#ifndef LAUNCHER_H +#define LAUNCHER_H + +#include +#include + + +class Launcher +{ +public: + Launcher(std::vector const& commandLine); + Launcher(std::vector && commandLine); + + void exec(); + +private: + std::vector commandLine; +}; + +#endif // LAUNCHER_H diff --git a/src/linkapp.cpp b/src/linkapp.cpp index 43e5ba3..9498007 100644 --- a/src/linkapp.cpp +++ b/src/linkapp.cpp @@ -23,6 +23,7 @@ #include "debug.h" #include "delegate.h" #include "gmenu2x.h" +#include "launcher.h" #include "menu.h" #include "selector.h" #include "surface.h" @@ -40,6 +41,7 @@ #include #include #include +#include #if defined(PLATFORM_A320) || defined(PLATFORM_GCW0) #include @@ -608,17 +610,21 @@ void LinkApp::launch(const string &selectedFile) { } #endif + vector commandLine; if (isOpk()) { #ifdef HAVE_LIBOPK - execlp("opkrun", "opkrun", "-m", metadata.c_str(), opkFile.c_str(), - !params.empty() ? params.c_str() : NULL, - NULL); + commandLine = { "opkrun", "-m", metadata, opkFile }; + if (!params.empty()) { + commandLine.push_back(params); + } #endif } else { - std::string command = exec + " " + params; - execlp("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL); + commandLine = { "/bin/sh", "-c", exec + " " + params }; } + Launcher launcher(move(commandLine)); + launcher.exec(); + //if execution continues then something went wrong and as we already called SDL_Quit we cannot continue //try relaunching gmenu2x gmenu2x->main();